Initial MTP Migration [Broken]

This commit is contained in:
Alex Emmet 2026-06-28 13:44:58 +02:00
commit b2a22456ff
30 changed files with 1886 additions and 1574 deletions

2
.cargo/config.toml Normal file
View file

@ -0,0 +1,2 @@
[env]
MTP_TYPE_MAPS = { value = "type-maps.yaml", relative = true }

807
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
iota-storage = { path = "../iota-storage" } iota-storage = { path = "../iota-storage" }

View file

@ -10,14 +10,25 @@ use iota_storage::util::{chat_files, chats_util};
use iota_util::crypto_helper; use iota_util::crypto_helper;
use iota_util::crypto_util::{DataFormat, SecurePayload}; use iota_util::crypto_util::{DataFormat, SecurePayload};
use iota_util::file_util::{get_children, load_file, save_file}; use iota_util::file_util::{get_children, load_file, save_file};
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use mtp::transport::{Receiver, Sender};
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::{Mutex, RwLock, mpsc, watch}; use tokio::sync::{Mutex, RwLock, mpsc, watch};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue};
use ttp_native::{Receiver, Sender};
use uuid::Uuid; use uuid::Uuid;
fn typed_container(items: Vec<(DataType, DataValue)>) -> DataValue {
use mtp::type_map::{DataTypeId, TypeMap};
let tm = TypeMap::latest();
DataValue::Container(
items
.into_iter()
.filter_map(|(dt, dv)| tm.data_id_enum(dt).map(|id| (DataTypeId(id), dv)))
.collect(),
)
}
// ============================================================================ // ============================================================================
// Waiting Task System // Waiting Task System
// ============================================================================ // ============================================================================
@ -97,76 +108,76 @@ impl ClientConnection {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
async fn handle_ping(self: Arc<Self>, cv: CommunicationValue) { async fn handle_ping(self: Arc<Self>, cv: CommunicationValue) {
// Update our ping if provided // Update our ping if provided
if let DataValue::Number(last_ping) = cv.get_data(DataTypes::last_ping) { if let DataValue::SignedNumber(last_ping) = cv.get_data(DataType::LastPing) {
let current = SystemTime::now() let current = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap() .unwrap()
.as_millis(); .as_millis();
let mut ping_guard = self.ping.write().await; let mut ping_guard = self.ping.write().await;
*ping_guard = current as i64 - last_ping; *ping_guard = current as i64 - *last_ping as i64;
} }
// Send pong response // Send pong response
let response = CommunicationValue::new(CommunicationType::pong) let response = CommunicationValue::new(CommunicationType::Pong)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data(DataTypes::ping_iota, DataValue::Number(0)); .add_typed_default(DataType::PingIota, DataValue::SignedNumber(0));
self.send_message(&response).await; self.send_message(&response).await;
} }
pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) { pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) {
if !cv.is_type(CommunicationType::ping) && !cv.is_type(CommunicationType::pong) { if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_in!(&cv); log_cv_in!(&cv);
} }
let _msg_id = cv.get_id(); let _msg_id = cv.get_id();
if cv.is_type(CommunicationType::ping) { if cv.is_type(CommunicationType::Ping) {
self.handle_ping(cv).await; self.handle_ping(cv).await;
return; return;
} }
if cv.is_type(CommunicationType::challenge) { if cv.is_type(CommunicationType::Challenge) {
self.handle_challenge(&cv).await; self.handle_challenge(&cv).await;
return; return;
} }
if cv.is_type(CommunicationType::save_app_data) { if cv.is_type(CommunicationType::SaveAppData) {
let sender_id = cv.get_sender(); let sender_id = cv.get_sender();
let _app_data = cv let _app_data = cv
.get_data(DataTypes::app_data) .get_data(DataType::AppData)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let res = CommunicationValue::new(CommunicationType::save_app_data) let res = CommunicationValue::new(CommunicationType::SaveAppData)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id); .with_receiver(sender_id);
self.send_message(&res).await; self.send_message(&res).await;
return; return;
} }
if cv.is_type(CommunicationType::load_app_data) { if cv.is_type(CommunicationType::LoadAppData) {
let sender_id = cv.get_sender(); let sender_id = cv.get_sender();
let app_data = String::new(); let app_data = String::new();
let res = CommunicationValue::new(CommunicationType::load_app_data) let res = CommunicationValue::new(CommunicationType::LoadAppData)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id) .with_receiver(sender_id)
.add_data(DataTypes::app_data, DataValue::Str(app_data)); .add_typed_default(DataType::AppData, DataValue::Str(app_data));
self.send_message(&res).await; self.send_message(&res).await;
return; return;
} }
if cv.is_type(CommunicationType::create_app) { if cv.is_type(CommunicationType::CreateApp) {
let sender_id = cv.get_sender() as i64; let sender_id = cv.get_sender() as i64;
let app_identifier = cv let app_identifier = cv
.get_data(DataTypes::app_identifier) .get_data(DataType::AppIdentifier)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let app_public_key = cv let app_public_key = cv
.get_data(DataTypes::app_public_key) .get_data(DataType::AppPublicKey)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
@ -180,17 +191,17 @@ impl ClientConnection {
} }
} }
let res = CommunicationValue::new(CommunicationType::create_app) let res = CommunicationValue::new(CommunicationType::CreateApp)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64); .with_receiver(sender_id as u64);
self.send_message(&res).await; self.send_message(&res).await;
return; return;
} }
if cv.is_type(CommunicationType::delete_app) { if cv.is_type(CommunicationType::DeleteApp) {
let sender_id = cv.get_sender() as i64; let sender_id = cv.get_sender() as i64;
let app_identifier = cv let app_identifier = cv
.get_data(DataTypes::app_identifier) .get_data(DataType::AppIdentifier)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
@ -204,30 +215,30 @@ impl ClientConnection {
} }
} }
let res = CommunicationValue::new(CommunicationType::delete_app) let res = CommunicationValue::new(CommunicationType::DeleteApp)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64); .with_receiver(sender_id as u64);
self.send_message(&res).await; self.send_message(&res).await;
return; return;
} }
if cv.is_type(CommunicationType::client_connected) { if cv.is_type(CommunicationType::ClientConnected) {
let user_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0) as i64; let user_id = cv.get_data(DataType::UserId).as_number().unwrap_or(0) as i64;
let _session_id = cv.get_data(DataTypes::session_id).as_number().unwrap_or(0) as i64; let _session_id = cv.get_data(DataType::SessionId).as_number().unwrap_or(0) as i64;
let contacts = chats_util::get_users(user_id); let contacts = chats_util::get_users(user_id);
let mut contacts_array = Vec::new(); let mut contacts_array = Vec::new();
for (i, contact) in contacts.iter().enumerate() { for (i, contact) in contacts.iter().enumerate() {
let mut contact_container = Vec::new(); let mut contact_container = Vec::new();
contact_container.push((DataTypes::user_id, DataValue::Number(contact.user_id))); contact_container.push((DataType::UserId, DataValue::SignedNumber(contact.user_id as i128)));
contact_container.push(( contact_container.push((
DataTypes::last_message_at, DataType::LastMessageAt,
DataValue::Number(contact.last_message_at.unwrap_or(0)), DataValue::SignedNumber(contact.last_message_at.unwrap_or(0) as i128),
)); ));
if let Some(ref name) = contact.user_name { if let Some(ref name) = contact.user_name {
contact_container.push((DataTypes::username, DataValue::Str(name.clone()))); contact_container.push((DataType::Username, DataValue::Str(name.clone())));
} }
let amount = if i < 10 { 20 } else { 1 }; let amount = if i < 10 { 20 } else { 1 };
@ -242,12 +253,12 @@ impl ClientConnection {
let message_state = m["message_state"].as_str().unwrap_or("").to_string(); let message_state = m["message_state"].as_str().unwrap_or("").to_string();
let mut msg_container = Vec::new(); let mut msg_container = Vec::new();
msg_container.push((DataTypes::send_time, DataValue::Number(message_time))); msg_container.push((DataType::SendTime, DataValue::SignedNumber(message_time as i128)));
msg_container.push((DataTypes::content, DataValue::Str(content.clone()))); msg_container.push((DataType::Content, DataValue::Str(content.clone())));
msg_container.push((DataTypes::message_state, DataValue::Str(message_state))); msg_container.push((DataType::MessageState, DataValue::Str(message_state)));
msg_container.push((DataTypes::height, DataValue::Number(height))); msg_container.push((DataType::Height, DataValue::SignedNumber(height as i128)));
msg_container.push((DataTypes::sent_by_self, DataValue::Bool(sent_by_self))); msg_container.push((DataType::SentBySelf, DataValue::Bool(sent_by_self)));
msg_array.push(DataValue::Container(msg_container)); msg_array.push(typed_container(msg_container));
if msg_array.len() == 1 { if msg_array.len() == 1 {
let sender_id = if sent_by_self { let sender_id = if sent_by_self {
@ -256,19 +267,19 @@ impl ClientConnection {
contact.user_id contact.user_id
}; };
let mut last_msg = Vec::new(); let mut last_msg = Vec::new();
last_msg.push((DataTypes::content, DataValue::Str(content))); last_msg.push((DataType::Content, DataValue::Str(content)));
last_msg.push((DataTypes::sender_id, DataValue::Number(sender_id))); last_msg.push((DataType::SenderId, DataValue::SignedNumber(sender_id as i128)));
contact_container contact_container
.push((DataTypes::last_message, DataValue::Container(last_msg))); .push((DataType::LastMessage, typed_container(last_msg)));
} }
} }
contact_container.push((DataTypes::messages, DataValue::Array(msg_array))); contact_container.push((DataType::Messages, DataValue::Array(msg_array)));
contacts_array.push(DataValue::Container(contact_container)); contacts_array.push(typed_container(contact_container));
} }
let resp = CommunicationValue::new(CommunicationType::client_connected) let resp = CommunicationValue::new(CommunicationType::ClientConnected)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data(DataTypes::contacts, DataValue::Array(contacts_array)); .add_typed_default(DataType::Contacts, DataValue::Array(contacts_array));
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
@ -277,15 +288,15 @@ impl ClientConnection {
// Direct messages // // Direct messages //
// ************************************************ // // ************************************************ //
if cv.is_type(CommunicationType::message_state) { if cv.is_type(CommunicationType::MessageState) {
let sender_id = &cv.get_sender(); let sender_id = &cv.get_sender();
let receiver_id = match cv.get_data(DataTypes::chat_partner_id).as_number() { let receiver_id = match cv.get_data(DataType::ChatPartnerId).as_number() {
Some(id) => id, Some(id) => id,
_ => return, _ => return,
}; };
// Parse send_time robustly: accept numeric or string, fallback to current time // Parse send_time robustly: accept numeric or string, fallback to current time
let send_time_val = cv.get_data(DataTypes::send_time); let send_time_val = cv.get_data(DataType::SendTime);
let now_i64 = SystemTime::now() let now_i64 = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap_or_default() .unwrap_or_default()
@ -302,28 +313,25 @@ impl ClientConnection {
timestamp_i64, timestamp_i64,
receiver_id as i64, receiver_id as i64,
*sender_id as i64, *sender_id as i64,
MessageState::from_str( MessageState::from_str(cv.get_data(DataType::MessageState).as_str().unwrap_or("")),
cv.get_data(DataTypes::message_state).as_str().unwrap_or(""),
),
); );
} }
// Incoming storsed message: store for the recipient, attempt local delivery, notify sender. // Incoming storsed message: store for the recipient, attempt local delivery, notify sender.
if cv.is_type(CommunicationType::message_send) { if cv.is_type(CommunicationType::MessageSend) {
let sender_id: u64 = cv.get_sender(); let sender_id: u64 = cv.get_sender();
// parse receiver_id (the storage owner for this incoming message) // parse receiver_id (the storage owner for this incoming message)
let receiver_id: i64 = if let Some(n) = cv.get_data(DataTypes::receiver_id).as_number() let receiver_id: i64 = if let Some(n) = cv.get_data(DataType::ReceiverId).as_number() {
{
n as i64 n as i64
} else if let Some(s) = cv.get_data(DataTypes::receiver_id).as_str() { } else if let Some(s) = cv.get_data(DataType::ReceiverId).as_str() {
s.parse::<i64>().unwrap_or(0) s.parse::<i64>().unwrap_or(0)
} else { } else {
0 0
}; };
// parse send_time robustly (number or string), fallback to now // parse send_time robustly (number or string), fallback to now
let send_time_val = cv.get_data(DataTypes::send_time); let send_time_val = cv.get_data(DataType::SendTime);
let now_i64 = SystemTime::now() let now_i64 = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap_or_default() .unwrap_or_default()
@ -339,12 +347,12 @@ impl ClientConnection {
// content may be missing; default to empty string // content may be missing; default to empty string
let content = cv let content = cv
.get_data(DataTypes::content) .get_data(DataType::Content)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let height = cv.get_data(DataTypes::height).as_number().unwrap_or(0) as i64; let height = cv.get_data(DataType::Height).as_number().unwrap_or(0) as i64;
let is_local = iota_storage::users::user_manager::get_user(receiver_id).is_some(); let is_local = iota_storage::users::user_manager::get_user(receiver_id).is_some();
@ -371,19 +379,19 @@ impl ClientConnection {
); );
// send confirmation back to sender // send confirmation back to sender
let conf_msg = CommunicationValue::new(CommunicationType::message_send) let conf_msg = CommunicationValue::new(CommunicationType::MessageSend)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64); .with_receiver(sender_id as u64);
self.send_message(&conf_msg).await; self.send_message(&conf_msg).await;
if !is_local { if !is_local {
let fw_msg = CommunicationValue::new(CommunicationType::message_other_iota) let fw_msg = CommunicationValue::new(CommunicationType::MessageOtherIota)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(receiver_id as u64) .with_receiver(receiver_id as u64)
.with_sender(sender_id as u64) .with_sender(sender_id as u64)
.add_data(DataTypes::height, DataValue::Number(height)) .add_typed_default(DataType::Height, DataValue::SignedNumber(height as i128))
.add_data(DataTypes::content, DataValue::Str(content)) .add_typed_default(DataType::Content, DataValue::Str(content))
.add_data(DataTypes::send_time, DataValue::Number(timestamp_i64)); .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128));
let other_iota_resp = self let other_iota_resp = self
.clone() .clone()
@ -392,7 +400,7 @@ impl ClientConnection {
if let Ok(resp) = other_iota_resp { if let Ok(resp) = other_iota_resp {
let ms_raw = resp let ms_raw = resp
.get_data(DataTypes::message_state) .get_data(DataType::MessageState)
.as_string() .as_string()
.unwrap_or_else(|| "".to_string()); .unwrap_or_else(|| "".to_string());
let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received); let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received);
@ -405,17 +413,17 @@ impl ClientConnection {
); );
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64) .with_receiver(sender_id as u64)
.with_sender(receiver_id as u64) .with_sender(receiver_id as u64)
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(receiver_id as i64), DataValue::SignedNumber(receiver_id as i128),
) )
.add_data(DataTypes::send_time, DataValue::Number(timestamp_i64)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128))
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(ms.as_str().to_string()), DataValue::Str(ms.as_str().to_string()),
), ),
) )
@ -429,17 +437,17 @@ impl ClientConnection {
); );
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64) .with_receiver(sender_id as u64)
.with_sender(receiver_id as u64) .with_sender(receiver_id as u64)
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(receiver_id as i64), DataValue::SignedNumber(receiver_id as i128),
) )
.add_data(DataTypes::send_time, DataValue::Number(timestamp_i64)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128))
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(MessageState::Sent.as_str().to_string()), DataValue::Str(MessageState::Sent.as_str().to_string()),
), ),
) )
@ -448,16 +456,16 @@ impl ClientConnection {
return; return;
} else { } else {
// Build a live-delivery message for the local client (recipient) // Build a live-delivery message for the local client (recipient)
let user_forward = CommunicationValue::new(CommunicationType::message_live) let user_forward = CommunicationValue::new(CommunicationType::MessageLive)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(receiver_id as u64) .with_receiver(receiver_id as u64)
.add_data(DataTypes::sender_id, DataValue::Number(sender_id as i64)) .add_typed_default(DataType::SenderId, DataValue::SignedNumber(sender_id as i128))
.add_data( .add_typed_default(
DataTypes::message, DataType::Message,
DataValue::Container(vec![ typed_container(vec![
(DataTypes::content, DataValue::Str(content.clone())), (DataType::Content, DataValue::Str(content.clone())),
(DataTypes::send_time, DataValue::Number(timestamp_i64)), (DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128)),
(DataTypes::height, DataValue::Number(height)), (DataType::Height, DataValue::SignedNumber(height as i128)),
]), ]),
); );
@ -469,7 +477,7 @@ impl ClientConnection {
if let Ok(user_resp) = user_resp { if let Ok(user_resp) = user_resp {
let ms_raw = user_resp let ms_raw = user_resp
.get_data(DataTypes::message_state) .get_data(DataType::MessageState)
.as_string() .as_string()
.unwrap_or_else(|| "".to_string()); .unwrap_or_else(|| "".to_string());
let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received); let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received);
@ -492,17 +500,17 @@ impl ClientConnection {
// notify original sender about the delivered/read state // notify original sender about the delivered/read state
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64) .with_receiver(sender_id as u64)
.with_sender(receiver_id as u64) .with_sender(receiver_id as u64)
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(receiver_id as i64), DataValue::SignedNumber(receiver_id as i128),
) )
.add_data(DataTypes::send_time, DataValue::Number(timestamp_i64)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128))
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(ms.as_str().to_string()), DataValue::Str(ms.as_str().to_string()),
), ),
) )
@ -525,17 +533,17 @@ impl ClientConnection {
// notify sender // notify sender
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(sender_id as u64) .with_receiver(sender_id as u64)
.with_sender(receiver_id as u64) .with_sender(receiver_id as u64)
.add_data(DataTypes::send_time, DataValue::Number(timestamp_i64)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp_i64 as i128))
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(receiver_id as i64), DataValue::SignedNumber(receiver_id as i128),
) )
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(MessageState::Sent.as_str().to_string()), DataValue::Str(MessageState::Sent.as_str().to_string()),
), ),
) )
@ -545,12 +553,12 @@ impl ClientConnection {
} }
} }
if cv.is_type(CommunicationType::message_other_iota) { if cv.is_type(CommunicationType::MessageOtherIota) {
let sender_id = &cv.get_sender(); let sender_id = &cv.get_sender();
let receiver_id = &cv.get_receiver(); let receiver_id = &cv.get_receiver();
// parse send_time safely (number or string), fallback to now // parse send_time safely (number or string), fallback to now
let send_time_val = cv.get_data(DataTypes::send_time); let send_time_val = cv.get_data(DataType::SendTime);
let now_i64 = SystemTime::now() let now_i64 = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap_or_default() .unwrap_or_default()
@ -565,12 +573,12 @@ impl ClientConnection {
// content may be missing or non-string; default to empty string // content may be missing or non-string; default to empty string
let content = cv let content = cv
.get_data(DataTypes::content) .get_data(DataType::Content)
.as_str() .as_str()
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let height = cv.get_data(DataTypes::height).as_number().unwrap_or(0) as i64; let height = cv.get_data(DataType::Height).as_number().unwrap_or(0) as i64;
chat_files::add_message( chat_files::add_message(
timestamp as u128, timestamp as u128,
@ -582,16 +590,16 @@ impl ClientConnection {
); );
// Build user_forward using the parsed numeric timestamp and safe content string // Build user_forward using the parsed numeric timestamp and safe content string
let user_forward = CommunicationValue::new(CommunicationType::message_live) let user_forward = CommunicationValue::new(CommunicationType::MessageLive)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(*receiver_id) .with_receiver(*receiver_id)
.add_data(DataTypes::sender_id, DataValue::Number(*sender_id as i64)) .add_typed_default(DataType::SenderId, DataValue::SignedNumber(*sender_id as i128))
.add_data( .add_typed_default(
DataTypes::message, DataType::Message,
DataValue::Container(vec![ typed_container(vec![
(DataTypes::content, DataValue::Str(content.clone())), (DataType::Content, DataValue::Str(content.clone())),
(DataTypes::send_time, DataValue::Number(timestamp)), (DataType::SendTime, DataValue::SignedNumber(timestamp as i128)),
(DataTypes::height, DataValue::Number(height)), (DataType::Height, DataValue::SignedNumber(height as i128)),
]), ]),
); );
@ -602,7 +610,7 @@ impl ClientConnection {
if let Ok(user_resp) = user_resp { if let Ok(user_resp) = user_resp {
let ms_raw = user_resp let ms_raw = user_resp
.get_data(DataTypes::message_state) .get_data(DataType::MessageState)
.as_string() .as_string()
.unwrap_or_else(|| "".to_string()); .unwrap_or_else(|| "".to_string());
let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received); let ms = MessageState::from_str(&ms_raw).upgrade(MessageState::Received);
@ -615,17 +623,17 @@ impl ClientConnection {
); );
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(*sender_id) .with_receiver(*sender_id)
.with_sender(*receiver_id) .with_sender(*receiver_id)
.add_data(DataTypes::send_time, DataValue::Number(timestamp)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp as i128))
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(*sender_id as i64), DataValue::SignedNumber(*sender_id as i128),
) )
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(ms.as_str().to_string()), DataValue::Str(ms.as_str().to_string()),
), ),
) )
@ -640,17 +648,17 @@ impl ClientConnection {
); );
self.send_message( self.send_message(
&CommunicationValue::new(CommunicationType::message_state) &CommunicationValue::new(CommunicationType::MessageState)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(*sender_id) .with_receiver(*sender_id)
.with_sender(*receiver_id) .with_sender(*receiver_id)
.add_data(DataTypes::send_time, DataValue::Number(timestamp)) .add_typed_default(DataType::SendTime, DataValue::SignedNumber(timestamp as i128))
.add_data( .add_typed_default(
DataTypes::chat_partner_id, DataType::ChatPartnerId,
DataValue::Number(*receiver_id as i64), DataValue::SignedNumber(*receiver_id as i128),
) )
.add_data( .add_typed_default(
DataTypes::message_state, DataType::MessageState,
DataValue::Str(MessageState::Sent.as_str().to_string()), DataValue::Str(MessageState::Sent.as_str().to_string()),
), ),
) )
@ -659,12 +667,12 @@ impl ClientConnection {
return; return;
} }
if cv.is_type(CommunicationType::messages_get) { if cv.is_type(CommunicationType::MessagesGet) {
let my_id = cv.get_sender(); let my_id = cv.get_sender();
let partner_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); let partner_id = cv.get_data(DataType::UserId).as_number().unwrap_or(0);
let offset = cv.get_data(DataTypes::offset).as_number().unwrap_or(0); let offset = cv.get_data(DataType::Offset).as_number().unwrap_or(0);
let amount = cv.get_data(DataTypes::amount).as_number().unwrap_or(0); let amount = cv.get_data(DataType::Amount).as_number().unwrap_or(0);
let messages = chat_files::get_messages(my_id as i64, partner_id, offset, amount); let messages = chat_files::get_messages(my_id as i64, partner_id as i64, offset as i64, amount as i64);
let mut msg_array: Vec<DataValue> = Vec::new(); let mut msg_array: Vec<DataValue> = Vec::new();
for m in messages.members() { for m in messages.members() {
let message_time: i64 = m["message_time"].as_i64().unwrap_or(0); let message_time: i64 = m["message_time"].as_i64().unwrap_or(0);
@ -674,9 +682,9 @@ impl ClientConnection {
let sender_id: i64 = if sent_by_self { let sender_id: i64 = if sent_by_self {
my_id as i64 my_id as i64
} else { } else {
if let Some(n) = cv.get_data(DataTypes::chat_partner_id).as_number() { if let Some(n) = cv.get_data(DataType::ChatPartnerId).as_number() {
n as i64 n as i64
} else if let Some(s) = cv.get_data(DataTypes::chat_partner_id).as_str() { } else if let Some(s) = cv.get_data(DataType::ChatPartnerId).as_str() {
s.parse::<i64>().unwrap_or(partner_id as i64) s.parse::<i64>().unwrap_or(partner_id as i64)
} else { } else {
partner_id as i64 partner_id as i64
@ -685,53 +693,53 @@ impl ClientConnection {
let message_state: String = m["message_state"].as_str().unwrap_or("").to_string(); let message_state: String = m["message_state"].as_str().unwrap_or("").to_string();
let mut container = Vec::new(); let mut container = Vec::new();
container.push((DataTypes::send_time, DataValue::Number(message_time))); container.push((DataType::SendTime, DataValue::SignedNumber(message_time as i128)));
container.push((DataTypes::content, DataValue::Str(content))); container.push((DataType::Content, DataValue::Str(content)));
container.push((DataTypes::sender_id, DataValue::Number(sender_id))); container.push((DataType::SenderId, DataValue::SignedNumber(sender_id as i128)));
container.push((DataTypes::message_state, DataValue::Str(message_state))); container.push((DataType::MessageState, DataValue::Str(message_state)));
container.push((DataTypes::height, DataValue::Number(height))); container.push((DataType::Height, DataValue::SignedNumber(height as i128)));
container.push((DataTypes::sent_by_self, DataValue::Bool(sent_by_self))); container.push((DataType::SentBySelf, DataValue::Bool(sent_by_self)));
msg_array.push(DataValue::Container(container)); msg_array.push(typed_container(container));
} }
let resp = CommunicationValue::new(CommunicationType::messages_get) let resp = CommunicationValue::new(CommunicationType::MessagesGet)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(my_id) .with_receiver(my_id)
.add_data(DataTypes::messages, DataValue::Array(msg_array)); .add_typed_default(DataType::Messages, DataValue::Array(msg_array));
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::get_chats) { if cv.is_type(CommunicationType::GetChats) {
let user_id = cv.get_sender(); let user_id = cv.get_sender();
let users = chats_util::get_users(user_id as i64); let users = chats_util::get_users(user_id as i64);
let mut user_array = Vec::new(); let mut user_array = Vec::new();
for user in users { for user in users {
let mut container = Vec::new(); let mut container = Vec::new();
container.push((DataTypes::user_id, DataValue::Number(user.user_id))); container.push((DataType::UserId, DataValue::SignedNumber(user.user_id as i128)));
if let Some(name) = user.user_name { if let Some(name) = user.user_name {
container.push((DataTypes::username, DataValue::Str(name))); container.push((DataType::Username, DataValue::Str(name)));
} }
if let Some(ts) = user.last_message_at { if let Some(ts) = user.last_message_at {
container.push((DataTypes::last_message_at, DataValue::Number(ts))); container.push((DataType::LastMessageAt, DataValue::SignedNumber(ts as i128)));
} }
user_array.push(DataValue::Container(container)); user_array.push(typed_container(container));
} }
let resp = CommunicationValue::new(CommunicationType::get_chats) let resp = CommunicationValue::new(CommunicationType::GetChats)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id) .with_receiver(user_id)
.add_data(DataTypes::user_ids, DataValue::Array(user_array)); .add_typed_default(DataType::UserIds, DataValue::Array(user_array));
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::add_conversation) { if cv.is_type(CommunicationType::AddConversation) {
let user_id = cv.get_sender(); let user_id = cv.get_sender();
let other_id = match cv.get_data(DataTypes::chat_partner_id).as_number() { let other_id = match cv.get_data(DataType::ChatPartnerId).as_number() {
Some(n) => n as i64, Some(n) => n as i64,
None => cv None => cv
.get_data(DataTypes::chat_partner_id) .get_data(DataType::ChatPartnerId)
.as_str() .as_str()
.unwrap_or("0") .unwrap_or("0")
.parse() .parse()
@ -739,7 +747,7 @@ impl ClientConnection {
}; };
let mut contact = get_user(user_id as i64, other_id).unwrap_or(Contact::new(other_id)); let mut contact = get_user(user_id as i64, other_id).unwrap_or(Contact::new(other_id));
if let Some(name) = cv.get_data(DataTypes::chat_partner_name).as_str() { if let Some(name) = cv.get_data(DataType::ChatPartnerName).as_str() {
contact.user_name = Some(name.to_string()); contact.user_name = Some(name.to_string());
} }
@ -750,85 +758,82 @@ impl ClientConnection {
.as_millis() as i64, .as_millis() as i64,
); );
mod_user(user_id as i64, &contact); mod_user(user_id as i64, &contact);
let resp = CommunicationValue::new(CommunicationType::add_conversation) let resp = CommunicationValue::new(CommunicationType::AddConversation)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id); .with_receiver(user_id);
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::add_community) { if cv.is_type(CommunicationType::AddCommunity) {
CommunitiesUtil::add_community( CommunitiesUtil::add_community(
cv.get_sender() as i64, cv.get_sender() as i64,
cv.get_data(DataTypes::community_address) cv.get_data(DataType::CommunityAddress)
.as_str() .as_str()
.unwrap() .unwrap()
.to_string(), .to_string(),
cv.get_data(DataTypes::community_title) cv.get_data(DataType::CommunityTitle)
.as_str() .as_str()
.unwrap() .unwrap()
.to_string(), .to_string(),
cv.get_data(DataTypes::position) cv.get_data(DataType::Position)
.as_str() .as_str()
.unwrap() .unwrap()
.to_string(), .to_string(),
); );
let resp = CommunicationValue::new(CommunicationType::add_community) let resp = CommunicationValue::new(CommunicationType::AddCommunity)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender()); .with_receiver(cv.get_sender());
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::get_communities) { if cv.is_type(CommunicationType::GetCommunities) {
let mut comm_array = Vec::new(); let mut comm_array = Vec::new();
for c in CommunitiesUtil::get_communities(cv.get_sender() as i64) { for c in CommunitiesUtil::get_communities(cv.get_sender() as i64) {
let mut container: Vec<(DataTypes, DataValue)> = Vec::new(); let mut container: Vec<(DataType, DataValue)> = Vec::new();
if let Some(address) = c["address"].as_str() { if let Some(address) = c["address"].as_str() {
container.push(( container.push((
DataTypes::community_address, DataType::CommunityAddress,
DataValue::Str(address.to_string()), DataValue::Str(address.to_string()),
)); ));
} }
if let Some(title) = c["title"].as_str() { if let Some(title) = c["title"].as_str() {
container.push(( container.push((DataType::CommunityTitle, DataValue::Str(title.to_string())));
DataTypes::community_title,
DataValue::Str(title.to_string()),
));
} }
if let Some(position) = c["position"].as_str() { if let Some(position) = c["position"].as_str() {
container.push((DataTypes::position, DataValue::Str(position.to_string()))); container.push((DataType::Position, DataValue::Str(position.to_string())));
} }
comm_array.push(DataValue::Container(container)); comm_array.push(typed_container(container));
} }
let resp = CommunicationValue::new(CommunicationType::get_communities) let resp = CommunicationValue::new(CommunicationType::GetCommunities)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender()) .with_receiver(cv.get_sender())
.add_data(DataTypes::communities, DataValue::Array(comm_array)); .add_typed_default(DataType::Communities, DataValue::Array(comm_array));
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::remove_community) { if cv.is_type(CommunicationType::RemoveCommunity) {
CommunitiesUtil::remove_community( CommunitiesUtil::remove_community(
cv.get_sender() as i64, cv.get_sender() as i64,
cv.get_data(DataTypes::community_address) cv.get_data(DataType::CommunityAddress)
.as_str() .as_str()
.unwrap() .unwrap()
.to_string(), .to_string(),
); );
let resp = CommunicationValue::new(CommunicationType::remove_community) let resp = CommunicationValue::new(CommunicationType::RemoveCommunity)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender()); .with_receiver(cv.get_sender());
self.send_message(&resp).await; self.send_message(&resp).await;
return; return;
} }
if cv.is_type(CommunicationType::settings_save) { if cv.is_type(CommunicationType::SettingsSave) {
let my_id = cv.get_sender(); let my_id = cv.get_sender();
let settings_name = cv.get_data(DataTypes::settings_name).as_str().unwrap(); let settings_name = cv.get_data(DataType::SettingsName).as_str().unwrap();
let settings_value = cv.get_data(DataTypes::payload).as_str().unwrap(); let settings_value = cv.get_data(DataType::Payload).as_str().unwrap();
save_file( save_file(
&format!("users/{}/settings/", my_id), &format!("users/{}/settings/", my_id),
@ -836,7 +841,7 @@ impl ClientConnection {
&settings_value, &settings_value,
); );
let response = CommunicationValue::new(CommunicationType::settings_save) let response = CommunicationValue::new(CommunicationType::SettingsSave)
.with_receiver(my_id) .with_receiver(my_id)
.with_id(cv.get_id()); .with_id(cv.get_id());
@ -844,24 +849,24 @@ impl ClientConnection {
return; return;
} }
if cv.is_type(CommunicationType::settings_load) { if cv.is_type(CommunicationType::SettingsLoad) {
let my_id = cv.get_sender(); let my_id = cv.get_sender();
let settings_name = cv.get_data(DataTypes::settings_name).as_string().unwrap(); let settings_name = cv.get_data(DataType::SettingsName).as_string().unwrap();
let settings_value_str = load_file( let settings_value_str = load_file(
&format!("users/{}/settings/", my_id), &format!("users/{}/settings/", my_id),
&format!("{}.settings", settings_name), &format!("{}.settings", settings_name),
); );
let response = CommunicationValue::new(CommunicationType::settings_load) let response = CommunicationValue::new(CommunicationType::SettingsLoad)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(my_id) .with_receiver(my_id)
.add_data(DataTypes::payload, DataValue::Str(settings_value_str)) .add_typed_default(DataType::Payload, DataValue::Str(settings_value_str))
.add_data(DataTypes::settings_name, DataValue::Str(settings_name)); .add_typed_default(DataType::SettingsName, DataValue::Str(settings_name));
self.send_message(&response).await; self.send_message(&response).await;
return; return;
} }
if cv.is_type(CommunicationType::settings_list) { if cv.is_type(CommunicationType::SettingsList) {
let my_id = cv.get_sender(); let my_id = cv.get_sender();
let settings = get_children(&format!("users/{}/settings/", my_id)); let settings = get_children(&format!("users/{}/settings/", my_id));
let mut settings_json = Vec::new(); let mut settings_json = Vec::new();
@ -872,10 +877,10 @@ impl ClientConnection {
} }
let _ = settings_json.push(DataValue::Str(s)); let _ = settings_json.push(DataValue::Str(s));
} }
let response = CommunicationValue::new(CommunicationType::settings_list) let response = CommunicationValue::new(CommunicationType::SettingsList)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(my_id) .with_receiver(my_id)
.add_data(DataTypes::settings, DataValue::Array(settings_json)); .add_typed_default(DataType::Settings, DataValue::Array(settings_json));
self.send_message(&response).await; self.send_message(&response).await;
return; return;
@ -887,8 +892,8 @@ impl ClientConnection {
let private_key = conf.get_private_key().unwrap(); let private_key = conf.get_private_key().unwrap();
drop(conf); drop(conf);
let omikron_public_key = cv.get_data(DataTypes::public_key).as_str().unwrap(); let omikron_public_key = cv.get_data(DataType::PublicKey).as_str().unwrap();
let encrypted_challenge = cv.get_data(DataTypes::challenge).as_str().unwrap(); let encrypted_challenge = cv.get_data(DataType::Challenge).as_str().unwrap();
let solved_challenge = { let solved_challenge = {
if let Ok(decrypted) = SecurePayload::new( if let Ok(decrypted) = SecurePayload::new(
@ -911,9 +916,9 @@ impl ClientConnection {
if let Some(decrypted) = solved_challenge { if let Some(decrypted) = solved_challenge {
let solved = decrypted.export(DataFormat::Raw); let solved = decrypted.export(DataFormat::Raw);
let response = CommunicationValue::new(CommunicationType::challenge_response) let response = CommunicationValue::new(CommunicationType::ChallengeResponse)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data(DataTypes::challenge, DataValue::Str(solved)); .add_typed_default(DataType::Challenge, DataValue::Str(solved));
self.send_message(&response).await; self.send_message(&response).await;
} }
@ -943,7 +948,7 @@ impl ClientConnection {
let sender_clone = Arc::clone(sender); let sender_clone = Arc::clone(sender);
drop(sender_guard); drop(sender_guard);
if !cv.is_type(CommunicationType::ping) && !cv.is_type(CommunicationType::pong) { if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_out!(&cv); log_cv_out!(&cv);
} }

View file

@ -4,8 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
iota-storage = { path = "../iota-storage" } iota-storage = { path = "../iota-storage" }

View file

@ -210,7 +210,7 @@ impl Community {
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" {
return CommunicationValue::new(CommunicationType::error_internal); return CommunicationValue::new(CommunicationType::ErrorInternal);
} else { } else {
// cannot move a value of type dyn Interactable the size of dyn Interactable cannot be statically determined (rustc E0161) // cannot move a value of type dyn Interactable the size of dyn Interactable cannot be statically determined (rustc E0161)
return interactable.run_function(cv.clone()).await; return interactable.run_function(cv.clone()).await;
@ -231,12 +231,12 @@ impl Community {
.run_function(cv.clone()) .run_function(cv.clone())
.await; .await;
} else { } else {
return CommunicationValue::new(CommunicationType::error_internal); return CommunicationValue::new(CommunicationType::ErrorInternal);
} }
} }
} }
} }
CommunicationValue::new(CommunicationType::add_conversation) CommunicationValue::new(CommunicationType::AddConversation)
} }
pub async fn save(&self) { pub async fn save(&self) {

View file

@ -70,12 +70,12 @@ impl CommunityConnection {
let user_id = self.get_user_id().await; let user_id = self.get_user_id().await;
cv = cv.with_sender(user_id); cv = cv.with_sender(user_id);
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;
return; return;
} }
if cv.is_type(CommunicationType::challenge_response) && !self.is_identified().await { if cv.is_type(CommunicationType::ChallengeResponse) && !self.is_identified().await {
self.handle_challenge_response(cv).await; self.handle_challenge_response(cv).await;
return; return;
} }
@ -84,25 +84,25 @@ impl CommunityConnection {
return; return;
} }
if cv.is_type(CommunicationType::ping) { if cv.is_type(CommunicationType::Ping) {
self.handle_ping(cv).await; self.handle_ping(cv).await;
return; return;
} }
if cv.is_type(CommunicationType::client_changed) { if cv.is_type(CommunicationType::ClientChanged) {
//self.handle_client_changed(cv).await; //self.handle_client_changed(cv).await;
return; return;
} }
if cv.is_type(CommunicationType::function) { if cv.is_type(CommunicationType::Function) {
self.handle_function(cv).await; self.handle_function(cv).await;
return; return;
} }
} }
async fn handle_function(&self, cv: CommunicationValue) { async fn handle_function(&self, cv: CommunicationValue) {
let name = cv.get_data(DataTypes::name).unwrap().as_str().unwrap(); let name = cv.get_data(DataType::Name).unwrap().as_str().unwrap();
let path = cv.get_data(DataTypes::path).unwrap().as_str().unwrap(); let path = cv.get_data(DataType::Path).unwrap().as_str().unwrap();
let function = cv.get_data(DataTypes::function).unwrap().as_str().unwrap(); let function = cv.get_data(DataType::Function).unwrap().as_str().unwrap();
let result = self let result = self
.get_community() .get_community()
@ -115,13 +115,13 @@ impl CommunityConnection {
} }
async fn handle_identification(&self, cv: CommunicationValue) { async fn handle_identification(&self, cv: CommunicationValue) {
let user_id = cv let user_id = cv
.get_data(DataTypes::user_id) .get_data(DataType::UserId)
.unwrap_or(&JsonValue::Number(Number::from(0))) .unwrap_or(&JsonValue::Number(Number::from(0)))
.as_i64() .as_i64()
.unwrap_or(0); .unwrap_or(0);
let Some(user) = get_user(user_id) else { let Some(user) = get_user(user_id) else {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidUserId)
.await; .await;
return; return;
}; };
@ -151,7 +151,7 @@ impl CommunityConnection {
let user_public_key_bytes = match STANDARD.decode(&user.public_key) { let user_public_key_bytes = match STANDARD.decode(&user.public_key) {
Ok(bytes) => bytes, Ok(bytes) => bytes,
Err(_) => { Err(_) => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidUserId)
.await; .await;
return; return;
} }
@ -160,14 +160,14 @@ impl CommunityConnection {
let user_pub_key: PublicKey = match PublicKey::from_bytes(&user_public_key_bytes) { let user_pub_key: PublicKey = match PublicKey::from_bytes(&user_public_key_bytes) {
Some(key) => key, Some(key) => key,
__ => { __ => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidUserId)
.await; .await;
return; return;
} }
}; };
let Some(community) = self.community.read().await.clone() else { let Some(community) = self.community.read().await.clone() else {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
}; };
@ -178,7 +178,7 @@ impl CommunityConnection {
let shared_secret = match community_private_key.to_diffie_hellman(&user_pub_key) { let shared_secret = match community_private_key.to_diffie_hellman(&user_pub_key) {
Some(secret) => secret, Some(secret) => secret,
_ => { _ => {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
} }
@ -200,7 +200,7 @@ impl CommunityConnection {
let encrypted_challenge = match cipher.encrypt(nonce, challenge_str.as_bytes()) { let encrypted_challenge = match cipher.encrypt(nonce, challenge_str.as_bytes()) {
Ok(data) => data, Ok(data) => data,
Err(_) => { Err(_) => {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
} }
@ -209,21 +209,21 @@ impl CommunityConnection {
let mut encrypted_out = nonce_bytes.to_vec(); let mut encrypted_out = nonce_bytes.to_vec();
encrypted_out.extend(encrypted_challenge); encrypted_out.extend(encrypted_challenge);
let response = CommunicationValue::new(CommunicationType::challenge) let response = CommunicationValue::new(CommunicationType::Challenge)
.add_data_str( .add_data_str(
DataTypes::public_key, DataType::PublicKey,
STANDARD.encode(community_public_key.as_bytes()), STANDARD.encode(community_public_key.as_bytes()),
) )
.add_data_str(DataTypes::challenge, STANDARD.encode(&encrypted_out)) .add_data_str(DataType::Challenge, STANDARD.encode(&encrypted_out))
.with_id(cv.get_id()); .with_id(cv.get_id());
self.send_message(&response).await; self.send_message(&response).await;
} }
async fn handle_challenge_response(self: Arc<Self>, cv: CommunicationValue) { async fn handle_challenge_response(self: Arc<Self>, cv: CommunicationValue) {
let client_challenge_response_b64 = match cv.get_data(DataTypes::challenge) { let client_challenge_response_b64 = match cv.get_data(DataType::Challenge) {
Some(data) => data.to_string(), Some(data) => data.to_string(),
_ => { _ => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_data) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidData)
.await; .await;
return; return;
} }
@ -232,38 +232,38 @@ impl CommunityConnection {
let challenge_response_bytes = match STANDARD.decode(&client_challenge_response_b64) { let challenge_response_bytes = match STANDARD.decode(&client_challenge_response_b64) {
Ok(bytes) => bytes, Ok(bytes) => bytes,
Err(_) => { Err(_) => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_data) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidData)
.await; .await;
return; return;
} }
}; };
if challenge_response_bytes.len() < 12 { if challenge_response_bytes.len() < 12 {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_data) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidData)
.await; .await;
return; return;
} }
let Some(user) = self.auth.read().await.clone() else { let Some(user) = self.auth.read().await.clone() else {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
}; };
let Some(user_pub_bytes) = STANDARD.decode(&user.public_key).ok() else { let Some(user_pub_bytes) = STANDARD.decode(&user.public_key).ok() else {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_data) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidData)
.await; .await;
return; return;
}; };
let Some(user_pub_key) = PublicKey::from_bytes(&user_pub_bytes) else { let Some(user_pub_key) = PublicKey::from_bytes(&user_pub_bytes) else {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_public_key) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidPublicKey)
.await; .await;
return; return;
}; };
let Some(community) = self.community.read().await.clone() else { let Some(community) = self.community.read().await.clone() else {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
}; };
@ -273,7 +273,7 @@ impl CommunityConnection {
let shared_secret = match community_private_key.to_diffie_hellman(&user_pub_key) { let shared_secret = match community_private_key.to_diffie_hellman(&user_pub_key) {
Some(secret) => secret, Some(secret) => secret,
_ => { _ => {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
} }
@ -297,7 +297,7 @@ impl CommunityConnection {
let decrypted_bytes = match cipher.decrypt(nonce, ciphertext) { let decrypted_bytes = match cipher.decrypt(nonce, ciphertext) {
Ok(pt) => pt, Ok(pt) => pt,
Err(_) => { Err(_) => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_challenge) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidChallenge)
.await; .await;
return; return;
} }
@ -306,7 +306,7 @@ impl CommunityConnection {
let client_response = match String::from_utf8(decrypted_bytes) { let client_response = match String::from_utf8(decrypted_bytes) {
Ok(str) => str, Ok(str) => str,
Err(_) => { Err(_) => {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_data) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidData)
.await; .await;
return; return;
} }
@ -315,7 +315,7 @@ impl CommunityConnection {
let expected_challenge = self.challenge.read().await.clone(); let expected_challenge = self.challenge.read().await.clone();
if client_response != expected_challenge { if client_response != expected_challenge {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_challenge) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidChallenge)
.await; .await;
self.close().await; self.close().await;
return; return;
@ -327,7 +327,7 @@ impl CommunityConnection {
} }
let Some(community) = self.community.read().await.clone() else { let Some(community) = self.community.read().await.clone() else {
self.send_error_response(&cv.get_id(), CommunicationType::error_internal) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInternal)
.await; .await;
return; return;
}; };
@ -335,15 +335,15 @@ impl CommunityConnection {
let user_id = self.get_user_id().await; let user_id = self.get_user_id().await;
if user_id == 0 { if user_id == 0 {
self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) self.send_error_response(&cv.get_id(), CommunicationType::ErrorInvalidUserId)
.await; .await;
return; return;
} }
arc.add_connection(self.clone()).await; arc.add_connection(self.clone()).await;
let response = CommunicationValue::new(CommunicationType::identification_response) let response = CommunicationValue::new(CommunicationType::IdentificationResponse)
.add_data(DataTypes::interactables, { .add_data(DataType::Interactables, {
let a: Vec<Arc<Box<dyn Interactable>>> = arc.get_interactables(user_id).await; let a: Vec<Arc<Box<dyn Interactable>>> = arc.get_interactables(user_id).await;
let mut c: JsonValue = JsonValue::new_object(); let mut c: JsonValue = JsonValue::new_object();
for b in a { for b in a {
@ -382,14 +382,14 @@ impl CommunityConnection {
} }
async fn handle_ping(&self, cv: CommunicationValue) { async fn handle_ping(&self, cv: CommunicationValue) {
if let Some(last_ping) = cv.get_data(DataTypes::last_ping) { if let Some(last_ping) = cv.get_data(DataType::LastPing) {
if let Ok(ping_val) = last_ping.to_string().parse::<i64>() { if let Ok(ping_val) = last_ping.to_string().parse::<i64>() {
let mut ping_guard = self.ping.write().await; let mut ping_guard = self.ping.write().await;
*ping_guard = ping_val; *ping_guard = ping_val;
} }
} }
let response = CommunicationValue::new(CommunicationType::pong).with_id(cv.get_id()); let response = CommunicationValue::new(CommunicationType::Pong).with_id(cv.get_id());
self.send_message(&response).await; self.send_message(&response).await;
} }

View file

@ -3,7 +3,7 @@ use async_trait::async_trait;
use json::JsonValue; use json::JsonValue;
use std::any::Any; use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
use ttp_core::CommunicationValue; use mtp::codec::CommunicationValue;
use uuid::Uuid; use uuid::Uuid;
pub struct Category { pub struct Category {
@ -95,7 +95,7 @@ impl Interactable for Category {
v v
} }
async fn run_function(&self, _cv: CommunicationValue) -> CommunicationValue { async fn run_function(&self, _cv: CommunicationValue) -> CommunicationValue {
CommunicationValue::new(CommunicationType::error_internal) CommunicationValue::new(CommunicationType::ErrorInternal)
} }
fn to_json(&self) -> JsonValue { fn to_json(&self) -> JsonValue {
let mut v = JsonValue::new_object(); let mut v = JsonValue::new_object();

View file

@ -3,7 +3,7 @@ use async_trait::async_trait;
use json::JsonValue; use json::JsonValue;
use std::any::Any; use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
use ttp_core::CommunicationValue; use mtp::codec::CommunicationValue;
use uuid::Uuid; use uuid::Uuid;
pub type InteractableFactory = fn() -> Box<dyn Interactable>; pub type InteractableFactory = fn() -> Box<dyn Interactable>;

View file

@ -12,7 +12,7 @@ use std::fs;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use std::{any::Any, collections::HashMap}; use std::{any::Any, collections::HashMap};
use ttp_core::{CommunicationType, CommunicationValue, DataTypes}; use mtp::codec::{CommunicationType, CommunicationValue, DataType};
use uuid::Uuid; use uuid::Uuid;
pub struct TextChat { pub struct TextChat {
id: Uuid, id: Uuid,
@ -193,21 +193,21 @@ impl Interactable for TextChat {
JsonValue::new_object() JsonValue::new_object()
} }
async fn run_function(&self, cv: CommunicationValue) -> CommunicationValue { async fn run_function(&self, cv: CommunicationValue) -> CommunicationValue {
let payload = cv.get_data(DataTypes::payload).as_container().unwrap(); let payload = cv.get_data(DataType::Payload).as_container().unwrap();
if cv.get_data(DataTypes::function).as_str().unwrap() == "get_messages" { if cv.get_data(DataType::Function).as_str().unwrap() == "get_messages" {
let amount = payload.get(DataTypes::amount).as_i64().unwrap(); let amount = payload.get(DataType::Amount).as_i64().unwrap();
let loaded_messages = payload["loaded_messages"].as_i64().unwrap(); let loaded_messages = payload["loaded_messages"].as_i64().unwrap();
let messages = self.get_messages(loaded_messages, amount).clone(); let messages = self.get_messages(loaded_messages, amount).clone();
let mut payload = JsonValue::new_object(); let mut payload = JsonValue::new_object();
payload["messages"] = messages; payload["messages"] = messages;
return CommunicationValue::new(CommunicationType::function) return CommunicationValue::new(CommunicationType::Function)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data_str(DataTypes::name, self.name.clone()) .add_data_str(DataType::Name, self.name.clone())
.add_data_str(DataTypes::path, self.path.clone()) .add_data_str(DataType::Path, self.path.clone())
.add_data_str(DataTypes::result, "message_chunk".to_string()) .add_data_str(DataType::Result, "message_chunk".to_string())
.add_data(DataTypes::payload, payload); .add_data(DataType::Payload, payload);
} }
if cv.get_data(DataTypes::function).unwrap().as_str().unwrap() == "send_message" { if cv.get_data(DataType::Function).unwrap().as_str().unwrap() == "send_message" {
let message = payload["message"].as_str().unwrap(); let message = payload["message"].as_str().unwrap();
let milliseconds_timestamp: u128 = std::time::SystemTime::now() let milliseconds_timestamp: u128 = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH) .duration_since(std::time::UNIX_EPOCH)
@ -220,12 +220,12 @@ impl Interactable for TextChat {
distribution_payload["sender_id"] = JsonValue::String(cv.get_sender().to_string()); distribution_payload["sender_id"] = JsonValue::String(cv.get_sender().to_string());
distribution_payload["send_time"] = distribution_payload["send_time"] =
JsonValue::String(milliseconds_timestamp.to_string()); JsonValue::String(milliseconds_timestamp.to_string());
let distribution = CommunicationValue::new(CommunicationType::update) let distribution = CommunicationValue::new(CommunicationType::Update)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data_str(DataTypes::name, self.name.clone()) .add_data_str(DataType::Name, self.name.clone())
.add_data_str(DataTypes::path, self.path.clone()) .add_data_str(DataType::Path, self.path.clone())
.add_data_str(DataTypes::result, "message_live".to_string()) .add_data_str(DataType::Result, "message_live".to_string())
.add_data(DataTypes::payload, distribution_payload); .add_data(DataType::Payload, distribution_payload);
let connections: HashMap<i64, Vec<Arc<CommunityConnection>>> = let connections: HashMap<i64, Vec<Arc<CommunityConnection>>> =
self.get_community().get_connections().await.clone(); self.get_community().get_connections().await.clone();
@ -236,14 +236,14 @@ impl Interactable for TextChat {
cd.send_message(&distribution).await; cd.send_message(&distribution).await;
} }
} }
return CommunicationValue::new(CommunicationType::function) return CommunicationValue::new(CommunicationType::Function)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data_str(DataTypes::name, self.name.clone()) .add_data_str(DataType::Name, self.name.clone())
.add_data_str(DataTypes::path, self.path.clone()) .add_data_str(DataType::Path, self.path.clone())
.add_data_str(DataTypes::result, "message_received".to_string()) .add_data_str(DataType::Result, "message_received".to_string())
.add_data(DataTypes::payload, JsonValue::new_object()); .add_data(DataType::Payload, JsonValue::new_object());
} }
CommunicationValue::new(CommunicationType::error_internal).with_id(cv.get_id()) CommunicationValue::new(CommunicationType::ErrorInternal).with_id(cv.get_id())
} }
fn to_json(&self) -> JsonValue { fn to_json(&self) -> JsonValue {
JsonValue::new_object() JsonValue::new_object()

View file

@ -116,8 +116,8 @@ impl Interactable for VoiceChat {
data data
} }
async fn run_function(&self, cv: CommunicationValue) -> CommunicationValue { async fn run_function(&self, cv: CommunicationValue) -> CommunicationValue {
let payload = cv.get_data(DataTypes::payload).unwrap(); let payload = cv.get_data(DataType::Payload).unwrap();
let function = cv.get_data(DataTypes::function).unwrap().as_str().unwrap(); let function = cv.get_data(DataType::Function).unwrap().as_str().unwrap();
if function == "get_call" { if function == "get_call" {
let sender_id = payload["sender_id"].as_str().unwrap(); let sender_id = payload["sender_id"].as_str().unwrap();
@ -129,12 +129,12 @@ impl Interactable for VoiceChat {
response_payload["message"] = JsonValue::String(message_id.to_string()); response_payload["message"] = JsonValue::String(message_id.to_string());
response_payload["send_time"] = JsonValue::String(send_time.to_string()); response_payload["send_time"] = JsonValue::String(send_time.to_string());
return CommunicationValue::new(CommunicationType::function) return CommunicationValue::new(CommunicationType::Function)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data_str(DataTypes::name, self.name.clone()) .add_data_str(DataType::Name, self.name.clone())
.add_data_str(DataTypes::path, self.path.clone()) .add_data_str(DataType::Path, self.path.clone())
.add_data_str(DataTypes::result, "getting_call".to_string()) .add_data_str(DataType::Result, "getting_call".to_string())
.add_data(DataTypes::payload, response_payload); .add_data(DataType::Payload, response_payload);
} }
if function == "update_user_state" { if function == "update_user_state" {
@ -153,18 +153,18 @@ impl Interactable for VoiceChat {
user.streaming = streaming; user.streaming = streaming;
} }
let mut response_payload = JsonValue::new_object(); let mut response_payload = JsonValue::new_object();
response_payload["user_id"] = JsonValue::String(user_id.to_string()); response_payload["user_id"] = JsonValue::Number(user_id);
response_payload["state"] = JsonValue::String(state.to_string()); response_payload["state"] = JsonValue::String(state.to_string());
response_payload["streaming"] = JsonValue::Boolean(streaming); response_payload["streaming"] = JsonValue::Boolean(streaming);
return CommunicationValue::new(CommunicationType::update) return CommunicationValue::new(CommunicationType::Update)
.with_id(cv.get_id()) .with_id(cv.get_id())
.add_data_str(DataTypes::name, self.name.clone()) .add_data_str(DataType::Name, self.name.clone())
.add_data_str(DataTypes::path, self.path.clone()) .add_data_str(DataType::Path, self.path.clone())
.add_data_str(DataTypes::result, "user_changed".to_string()) .add_data_str(DataType::Result, "user_changed".to_string())
.add_data(DataTypes::payload, response_payload); .add_data(DataType::Payload, response_payload);
} }
CommunicationValue::new(CommunicationType::error_internal).with_id(cv.get_id()) CommunicationValue::new(CommunicationType::ErrorInternal).with_id(cv.get_id())
} }
fn to_json(&self) -> JsonValue { fn to_json(&self) -> JsonValue {

View file

@ -262,7 +262,7 @@
LockPersonality = true; LockPersonality = true;
MemoryDenyWriteExecute = true; MemoryDenyWriteExecute = true;
Environment = [ Environment = [
"TTP_BIND=${cfg.ttpBind}" "mtp::BIND=${cfg.ttpBind}"
"BIND_ADDRESS=${cfg.bindAddress}" "BIND_ADDRESS=${cfg.bindAddress}"
]; ];
} }

View file

@ -4,8 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
iota-storage = { path = "../iota-storage" } iota-storage = { path = "../iota-storage" }

View file

@ -12,8 +12,7 @@ iota-util = { path = "../iota-util" }
omikron-connector = { path = "../omikron-connector" } omikron-connector = { path = "../omikron-connector" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
actix-web = { version = "4", features = ["rustls-0_23"] } actix-web = { version = "4", features = ["rustls-0_23"] }
actix-web-actors = "4" actix-web-actors = "4"

View file

@ -4,6 +4,7 @@ use iota_state::{ACTIVE_TASKS, RELOAD, SHUTDOWN};
use iota_storage::users::{user_manager, user_profile::UserProfile}; use iota_storage::users::{user_manager, user_profile::UserProfile};
use iota_storage::util::config_util::CONFIG; use iota_storage::util::config_util::CONFIG;
use iota_util::{crypto_helper, file_util}; use iota_util::{crypto_helper, file_util};
use mtp::codec::{CommunicationType, CommunicationValue};
use omikron_connector::omikron_connection::OMIKRON_CONNECTION; use omikron_connector::omikron_connection::OMIKRON_CONNECTION;
use ratatui::{ use ratatui::{
Frame, Frame,
@ -12,7 +13,6 @@ use ratatui::{
text::{Line, Span}, text::{Line, Span},
widgets::{Block, Borders, Paragraph}, widgets::{Block, Borders, Paragraph},
}; };
use ttp_core::{CommunicationType, CommunicationValue};
use uuid::Uuid; use uuid::Uuid;
use std::{ use std::{
@ -442,7 +442,7 @@ pub async fn run_command(command: &str) {
} }
["user", "remove", username] => { ["user", "remove", username] => {
if let Some(user) = user_manager::get_user_by_username(username) { if let Some(user) = user_manager::get_user_by_username(username) {
let msg = CommunicationValue::new(CommunicationType::delete_user) let msg = CommunicationValue::new(CommunicationType::DeleteUser)
.with_sender(user.user_id as u64); .with_sender(user.user_id as u64);
OMIKRON_CONNECTION.send_message(&msg).await; OMIKRON_CONNECTION.send_message(&msg).await;
user_manager::remove_user(user.user_id); user_manager::remove_user(user.user_id);
@ -510,7 +510,7 @@ pub async fn ping(time: u64) {
let response_cv = conn let response_cv = conn
.await_response( .await_response(
&CommunicationValue::new(CommunicationType::ping), &CommunicationValue::new(CommunicationType::Ping),
Some(Duration::from_secs(time)), Some(Duration::from_secs(time)),
) )
.await; .await;

View file

@ -15,8 +15,7 @@ omikron-connector = { path = "../omikron-connector" }
web-server = { path = "../web-server" } web-server = { path = "../web-server" }
web-ui = { path = "../web-ui" } web-ui = { path = "../web-ui" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
dashmap = "6.1.0" dashmap = "6.1.0"
json = "*" json = "*"

View file

@ -7,7 +7,7 @@ edition = "2024"
iota-state = { path = "../iota-state" } iota-state = { path = "../iota-state" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ratatui = "0.30.0" ratatui = "0.30.0"
json = "0.12.4" json = "0.12.4"

View file

@ -8,8 +8,8 @@ use std::{
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, UNIX_EPOCH},
}; };
use mtp::codec::{CommunicationValue, DataType, DataTypeId, DataValue, Version};
use ratatui::style::Color; use ratatui::style::Color;
use ttp_core::{CommunicationValue, DataTypes, DataValue};
use iota_state::{APP_STATE, UNIQUE, UiLogEntry}; use iota_state::{APP_STATE, UNIQUE, UiLogEntry};
pub mod language_creator; pub mod language_creator;
@ -317,17 +317,19 @@ pub fn format_cv(cv: &CommunicationValue) -> String {
let comm_type = cv.get_type().to_string(); let comm_type = cv.get_type().to_string();
parts.push(format!("{}", comm_type)); parts.push(format!("{}", comm_type));
let data: &BTreeMap<DataTypes, DataValue> = cv.get_data_container(); let data = cv.data();
let formated_data = let formated_data = format_data_container(
format_data_container(data.iter().map(|(k, v)| (k.clone(), v.clone())).collect()); data.iter().map(|(k, v)| (*k, v.clone())).collect(),
Version(1, 0),
);
parts.push(format!("{}", formated_data)); parts.push(format!("{}", formated_data));
parts.join(": ") parts.join(": ")
} }
fn format_data_container(data: Vec<(DataTypes, DataValue)>) -> String { fn format_data_container(data: Vec<(DataTypeId, DataValue)>, version: Version) -> String {
let parts: Vec<String> = data let parts: Vec<String> = data
.into_iter() .into_iter()
.map(|(key, value)| { .map(|(key, value)| {
@ -337,12 +339,12 @@ fn format_data_container(data: Vec<(DataTypes, DataValue)>) -> String {
DataValue::Str(s) => format!("{}=\"{}\"", key_str, s), DataValue::Str(s) => format!("{}=\"{}\"", key_str, s),
DataValue::Container(inner) => { DataValue::Container(inner) => {
let inner_formatted = format_data_container(inner); let inner_formatted = format_data_container(inner, version.clone());
format!("{}={{ {} }}", key_str, inner_formatted) format!("{}={{ {} }}", key_str, inner_formatted)
} }
DataValue::Array(arr) => { DataValue::Array(arr) => {
let arr_formatted = format_array(arr); let arr_formatted = format_array(arr, version.clone());
format!("{}=[{}]", key_str, arr_formatted) format!("{}=[{}]", key_str, arr_formatted)
} }
@ -351,7 +353,7 @@ fn format_data_container(data: Vec<(DataTypes, DataValue)>) -> String {
DataValue::BoolTrue => format!("{}=true", key_str), DataValue::BoolTrue => format!("{}=true", key_str),
DataValue::BoolFalse => format!("{}=false", key_str), DataValue::BoolFalse => format!("{}=false", key_str),
DataValue::Number(num) => format!("{}={}", key_str, num), DataValue::SignedNumber(num) => format!("{}={}", key_str, num),
_ => "".to_string(), _ => "".to_string(),
} }
@ -361,19 +363,19 @@ fn format_data_container(data: Vec<(DataTypes, DataValue)>) -> String {
parts.join(", ") parts.join(", ")
} }
fn format_array(arr: Vec<DataValue>) -> String { fn format_array(arr: Vec<DataValue>, version: Version) -> String {
let parts: Vec<String> = arr let parts: Vec<String> = arr
.into_iter() .into_iter()
.map(|value| match value { .map(|value| match value {
DataValue::Str(s) => format!("\"{}\"", s), DataValue::Str(s) => format!("\"{}\"", s),
DataValue::Container(inner) => { DataValue::Container(inner) => {
let inner_formatted = format_data_container(inner); let inner_formatted = format_data_container(inner, version.clone());
format!("{{ {} }}", inner_formatted) format!("{{ {} }}", inner_formatted)
} }
DataValue::Array(inner_arr) => { DataValue::Array(inner_arr) => {
let formatted = format_array(inner_arr); let formatted = format_array(inner_arr, version.clone());
format!("[{}]", formatted) format!("[{}]", formatted)
} }
@ -382,7 +384,7 @@ fn format_array(arr: Vec<DataValue>) -> String {
DataValue::BoolTrue => "true".to_string(), DataValue::BoolTrue => "true".to_string(),
DataValue::BoolFalse => "false".to_string(), DataValue::BoolFalse => "false".to_string(),
DataValue::Number(num) => num.to_string(), DataValue::SignedNumber(num) => num.to_string(),
_ => String::new(), _ => String::new(),
}) })

View file

@ -9,4 +9,4 @@ once_cell = "1.21.3"
tokio = { version = "1.50.0", features = ["full"] } tokio = { version = "1.50.0", features = ["full"] }
json = "*" json = "*"
sysinfo = "0.38.3" sysinfo = "0.38.3"
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }

View file

@ -8,8 +8,7 @@ iota-logger = { path = "../iota-logger" }
iota-state = { path = "../iota-state" } iota-state = { path = "../iota-state" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
aes-gcm = "0.10.3" aes-gcm = "0.10.3"
base64 = "0.22.1" base64 = "0.22.1"

View file

@ -6,8 +6,7 @@ edition = "2024"
[dependencies] [dependencies]
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
json = "*" json = "*"
pnet = "0.35.0" pnet = "0.35.0"

View file

@ -4,8 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
reqwest = "0.13.2" reqwest = "0.13.2"
tokio = { version = "1.50.0", features = ["full"] } tokio = { version = "1.50.0", features = ["full"] }

View file

@ -8,8 +8,7 @@ iota-logger = { path = "../iota-logger" }
iota-state = { path = "../iota-state" } iota-state = { path = "../iota-state" }
iota-storage = { path = "../iota-storage" } iota-storage = { path = "../iota-storage" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
dashmap = "6.1.0" dashmap = "6.1.0"
json = "*" json = "*"
@ -17,6 +16,7 @@ tokio = { version = "1.50.0", features = ["full"] }
uuid = { version = "*", features = ["v4"] } uuid = { version = "*", features = ["v4"] }
base64 = "0.22.1" base64 = "0.22.1"
hex = "*" hex = "*"
rand = "0.8"
rand_core = { version = "0.6", features = ["getrandom", "std"] } rand_core = { version = "0.6", features = ["getrandom", "std"] }
sha2 = "0.10.9" sha2 = "0.10.9"
x448 = { version = "*" } x448 = { version = "*" }

File diff suppressed because it is too large Load diff

View file

@ -1,26 +1,26 @@
use crate::omikron_connection::OmikronConnection; use crate::omikron_connection::OmikronConnection;
use dashmap::DashMap; use dashmap::DashMap;
use iota_state::APP_STATE; use iota_state::APP_STATE;
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use std::sync::LazyLock; use std::sync::LazyLock;
use std::time::Instant; use std::time::Instant;
use tokio::time::Duration; use tokio::time::Duration;
use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue, rand_u32};
static PING_TIMES: LazyLock<DashMap<u32, Instant>> = LazyLock::new(|| DashMap::new()); static PING_TIMES: LazyLock<DashMap<u32, Instant>> = LazyLock::new(|| DashMap::new());
impl OmikronConnection { impl OmikronConnection {
pub async fn send_ping(&self) { pub async fn send_ping(&self) {
let id = rand_u32(); let id = rand::random();
PING_TIMES.insert(id, Instant::now()); PING_TIMES.insert(id, Instant::now());
PING_TIMES.retain(|_, v| v.elapsed() < Duration::from_secs(30)); PING_TIMES.retain(|_, v| v.elapsed() < Duration::from_secs(30));
let ping_message = CommunicationValue::new(CommunicationType::ping) let ping_message = CommunicationValue::new(CommunicationType::Ping)
.with_id(id) .with_id(id)
.add_data( .add_typed_default(
DataTypes::last_ping, DataType::LastPing,
DataValue::Array(vec![DataValue::Number(*self.last_ping.lock().await)]), DataValue::Array(vec![DataValue::SignedNumber(*self.last_ping.lock().await as i128)]),
); );
self.send_message(&ping_message).await; self.send_message(&ping_message).await;

View file

@ -6,16 +6,16 @@ use iota_storage::users::user_manager::{add_user, save_users};
use iota_storage::users::user_profile::UserProfile; use iota_storage::users::user_profile::UserProfile;
use iota_util::crypto_helper::public_key_to_base64; use iota_util::crypto_helper::public_key_to_base64;
use iota_util::file_util::save_file; use iota_util::file_util::save_file;
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use rand_core::{OsRng, RngCore}; use rand_core::{OsRng, RngCore};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::time::Duration; use std::time::Duration;
use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue};
use x448::{PublicKey, Secret}; use x448::{PublicKey, Secret};
use crate::omikron_connection::OMIKRON_CONNECTION; use crate::omikron_connection::OMIKRON_CONNECTION;
pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) { pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) {
let register_communication_value = CommunicationValue::new(CommunicationType::get_register); let register_communication_value = CommunicationValue::new(CommunicationType::GetRegister);
let connection = OMIKRON_CONNECTION.clone(); let connection = OMIKRON_CONNECTION.clone();
@ -32,7 +32,7 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
log_cv!(PrintType::Omega, response_communication_value); log_cv!(PrintType::Omega, response_communication_value);
let user_id = match response_communication_value let user_id = match response_communication_value
.get_data(DataTypes::user_id) .get_data(DataType::UserId)
.as_number() .as_number()
{ {
Some(id) => id, Some(id) => id,
@ -57,7 +57,7 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
let reset_token = STANDARD.encode(&bytes); let reset_token = STANDARD.encode(&bytes);
let user_profile = UserProfile::new( let user_profile = UserProfile::new(
user_id, user_id as i64,
username.to_string(), username.to_string(),
None, None,
STANDARD.encode(&public_key.as_bytes()), STANDARD.encode(&public_key.as_bytes()),
@ -65,15 +65,15 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
reset_token.clone(), reset_token.clone(),
); );
let communication_value = CommunicationValue::new(CommunicationType::complete_register_user) let communication_value = CommunicationValue::new(CommunicationType::CompleteRegisterUser)
.add_data(DataTypes::user_id, DataValue::Number(user_id)) .add_typed_default(DataType::UserId, DataValue::SignedNumber(user_id as i128))
.add_data(DataTypes::username, DataValue::Str(username.to_string())) .add_typed_default(DataType::Username, DataValue::Str(username.to_string()))
.add_data( .add_typed_default(
DataTypes::public_key, DataType::PublicKey,
DataValue::Str(public_key_to_base64(&public_key)), DataValue::Str(public_key_to_base64(&public_key)),
) )
.add_data(DataTypes::iota_id, DataValue::Number(user_id)) .add_typed_default(DataType::IotaId, DataValue::SignedNumber(user_id as i128))
.add_data(DataTypes::reset_token, DataValue::Str(reset_token)); .add_typed_default(DataType::ResetToken, DataValue::Str(reset_token));
let response_communication_value = connection let response_communication_value = connection
.await_response(&communication_value, Some(Duration::from_secs(20))) .await_response(&communication_value, Some(Duration::from_secs(20)))
@ -81,7 +81,7 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
if let Ok(response) = response_communication_value { if let Ok(response) = response_communication_value {
log_cv!(PrintType::Omega, response); log_cv!(PrintType::Omega, response);
if !response.is_type(CommunicationType::success) { if !response.is_type(CommunicationType::Success) {
return (None, None); return (None, None);
} }
} else { } else {

View file

@ -4,8 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
iota-storage = { path = "../iota-storage" } iota-storage = { path = "../iota-storage" }

241
type-maps.yaml Normal file
View file

@ -0,0 +1,241 @@
# The version a Client should use
protocol_version: "1.0"
# Note that markers 0 to 31 are reserved for default use, manually working with them is not recommended
# Fixed CommunicationType markers are:
# Error: 0
# ErrorParsing: 1
# ErrorBadVersion: 2
# Disconnect: 3
# Redirect: 4
# Shutdown: 5
# BadRequest: 6
# Unauthorized: 7
# Forbidden: 8
# NotFound: 9
# TooManyRequests: 10
# InternalServerError: 11
# BadGateway: 12
# ServiceUnavailable: 13
# GatewayTimeout: 14
# Identification: 15
# IdentificationResponse: 16
# Register: 17
# RegisterResponse: 18
# Ping: 19
# Pong: 20
#
# Fixed Data Type markers are:
# Error: 0
# ErrorParsing: 1
# ErrorMessage: 2
# Version: 3
# Description: 4
# Timestamp: 5
# Id: 6
# ClientNonce: 7
# ServerNonce: 8
# PublicKeys: 9
# Signature: 10
# Connected: 11
#
# If a Type can't be used it will be mapped to 0
type_maps:
"1.0": # Protocol version 1.0
CommunicationTypes:
ErrorProtocol: 33
ErrorAnonymous: 34
ErrorInternal: 35
ErrorInvalidData: 36
ErrorInvalidUserId: 37
ErrorInvalidOmikronId: 38
ErrorNotFound: 39
ErrorNotAuthenticated: 40
ErrorNoIota: 41
ErrorInvalidChallenge: 42
ErrorInvalidSecret: 43
ErrorInvalidPrivateKey: 44
ErrorInvalidPublicKey: 45
ErrorNoUserId: 46
ErrorNoCallId: 47
ErrorInvalidCallId: 48
Success: 49
ShortenLink: 50
SettingsSave: 51
SettingsLoad: 52
SettingsList: 53
GlobalSettingsSave: 54
GlobalSettingsLoad: 55
Message: 56
MessageState: 57
MessageSend: 58
MessageLive: 59
MessageOtherIota: 60
MessageChunk: 61
MessagesGet: 62
PushNotification: 63
ReadNotification: 64
GetNotifications: 65
TauriIdentification: 66
ChangeConfirm: 67
ConfirmReceive: 68
ConfirmRead: 69
GetChats: 70
GetStates: 71
AddCommunity: 72
RemoveCommunity: 73
GetCommunities: 74
RegisterIota: 81
RegisterIotaSuccess: 82
AddConversation: 85
SendChat: 86
ClientChanged: 87
ClientConnected: 88
ClientDisconnected: 89
ClientClosed: 90
PublicKey: 91
PrivateKey: 92
WebrtcSdp: 93
WebrtcIce: 94
StartStream: 95
EndStream: 96
WatchStream: 97
CallToken: 98
CallInvite: 99
CallDisconnectUser: 100
CallTimeoutUser: 101
CallSetAnonymousJoining: 102
CallData: 103
EndCall: 104
Function: 105
Update: 106
CreateUser: 107
RhoUpdate: 108
UserConnected: 109
UserDisconnected: 110
IotaConnected: 111
IotaDisconnected: 112
SyncClientIotaStatus: 113
GetUserData: 114
GetIotaData: 115
IotaUserData: 116
ChangeUserData: 117
ChangeIotaData: 118
GetRegister: 119
CompleteRegisterUser: 120
CompleteRegisterIota: 121
DeleteUser: 122
DeleteIota: 123
StartRegister: 124
CompleteRegister: 125
GetApp: 126
CreateApp: 127
DeleteApp: 128
SaveAppData: 129
LoadAppData: 130
AppIdentification: 131
AppChallenge: 132
AppChallengeResponse: 133
AppIdentificationResponse: 134
LoadTxtRecord: 135
DataTypes:
ErrorType: 32
ErrorProtocol: 33
AcceptedIds: 34
Uuid: 35
RegisterId: 36
Link: 37
Settings: 38
SettingsName: 39
ChatPartnerId: 40
ChatPartnerName: 41
IotaId: 42
UserId: 43
UserIds: 44
IotaIds: 45
UserState: 46
UserStates: 47
UserPings: 48
CallState: 49
ScreenShare: 50
PrivateKeyHash: 51
Accepted: 52
AcceptedProfiles: 53
DeniedProfiles: 54
Content: 55
Messages: 56
Notifications: 57
SendTime: 58
GetTime: 59
GetVariant: 60
SharedSecretOwn: 61
SharedSecretOther: 62
SharedSecretSign: 63
SharedSecret: 64
CallId: 65
CallToken: 66
CallSecret: 67
Untill: 68
Enabled: 69
StartDate: 70
EndDate: 71
ReceiverId: 72
SenderId: 73
Signed: 75
Message: 76
MessageState: 77
LastPing: 78
PingIota: 79
PingClients: 80
Matches: 81
Omikron: 82
Offset: 83
Amount: 84
Position: 85
Name: 86
Path: 87
Codec: 88
Function: 89
Payload: 90
Result: 91
Interactables: 92
WantToWatch: 93
Watcher: 94
CreatedAt: 95
Username: 96
Display: 97
Avatar: 98
About: 99
Status: 100
PublicKey: 101
SubLevel: 102
SubEnd: 103
CommunityAddress: 104
CommunityTitle: 106
Communities: 107
RhoConnections: 108
User: 109
OnlineStatus: 110
OmikronId: 111
OmikronConnections: 112
ResetToken: 113
NewToken: 114
CallInvited: 115
CallMembers: 116
Calls: 117
Timeout: 118
HasAdmin: 119
LastMessageAt: 120
Height: 121
SentBySelf: 122
SessionId: 123
Contacts: 124
LastMessage: 125
AppIdentifier: 127
AppPrivateKey: 128
AppPublicKey: 129
AppSession: 130
AppData: 131
TauriToken: 132
Challenge: 133

View file

@ -5,5 +5,4 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }

View file

@ -9,8 +9,7 @@ iota-storage = { path = "../iota-storage" }
iota-state = { path = "../iota-state" } iota-state = { path = "../iota-state" }
iota-util = { path = "../iota-util" } iota-util = { path = "../iota-util" }
iota-logger = { path = "../iota-logger" } iota-logger = { path = "../iota-logger" }
ttp-core = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-core" } mtp = { git = "https://git.methanium.net/Methanium/mtp.git" }
ttp-native = { git = "https://git.methanium.net/Tensamin/TTP.git", package = "ttp-native" }
actix-web = { version = "4", features = ["rustls-0_23"] } actix-web = { version = "4", features = ["rustls-0_23"] }
actix-web-actors = "4" actix-web-actors = "4"
@ -24,7 +23,15 @@ futures = "*"
futures-util = "*" futures-util = "*"
hex = "*" hex = "*"
hkdf = "0.12.4" hkdf = "0.12.4"
hyper = { version = "1.8.1", features = ["capi", "client", "full", "http1", "http2", "nightly", "server"] } hyper = { version = "1.8.1", features = [
"capi",
"client",
"full",
"http1",
"http2",
"nightly",
"server",
] }
hyper-util = { version = "*" } hyper-util = { version = "*" }
json = "*" json = "*"
lazy_static = "1.5.0" lazy_static = "1.5.0"