diff --git a/Cargo.lock b/Cargo.lock index 41aa957..0112781 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1586,6 +1586,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "include_optional" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3328afceb205b7534c691f71b12334973dbfdfe0eecb9e345bddfbb925bc55fc" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "indexmap" version = "1.7.0" @@ -1649,6 +1659,7 @@ version = "0.1.0" dependencies = [ "base64", "core-error", + "include_optional", "rand", "rand_os", "rayon", @@ -1660,6 +1671,10 @@ dependencies = [ "spin 0.9.2", ] +[[package]] +name = "ironforce_degeon" +version = "0.1.0" + [[package]] name = "itoa" version = "0.4.8" diff --git a/Cargo.toml b/Cargo.toml index c771f67..eb91217 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,35 +1,14 @@ [package] -name = "ironforce" +name = "ironforce_degeon" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [workspace] -members = ["degeon", "degeon_core"] - -[features] -default = [] -std = ["rayon"] +members = ["degeon", "degeon_core", "ironforce"] -[dependencies] -rand_os = "*" -# x25519-dalek = "0.6.0" -# ed25519-dalek = { version = "1.0", features = ["serde"] } -sha2 = "0.8.1" -rand = "*" -rsa = { version = "0.5", features = ["serde"] } -serde = { version = "1.0", features = ["derive", "alloc"], default-features = false } -rayon = { version = "1.5.1", optional = true } -core-error = "0.0.1-rc4" -serde_cbor = "0.11.2" -serde_json = "1.0.72" -spin = "0.9.2" -base64 = "0.13.0" - -[profile.dev.package.num-bigint-dig] -opt-level = 3 +[lib] +name = "ironforce" +path = "ironforce/src/lib.rs" -[[bin]] -name = "worker" -required-features = ["std"] diff --git a/degeon/Cargo.toml b/degeon/Cargo.toml index 7a33055..c9d585f 100644 --- a/degeon/Cargo.toml +++ b/degeon/Cargo.toml @@ -7,11 +7,11 @@ edition = "2021" [dependencies] iced = { version = "0.3.0", features = ["glow"] } -ironforce = { path = "..", features = ["std"] } +ironforce = { path = "../ironforce", features = ["std", "image"] } degeon_core = { path = "../degeon_core" } base64 = "0.13.0" serde = { version = "1.0" } serde_json = "1.0.72" futures = "0.3.18" iced_native = "0.4.0" -chrono = "0.4.19" \ No newline at end of file +chrono = "0.4.19" diff --git a/degeon/src/state.rs b/degeon/src/state.rs index 099584c..5ad5a6c 100644 --- a/degeon/src/state.rs +++ b/degeon/src/state.rs @@ -242,8 +242,15 @@ impl Application for DegeonApp { self.data.save_to_file("".to_string()).unwrap(); } GuiEvent::ChangeScreen(sc) => { + let prev_screen = self.screen; self.screen = sc; self.data.save_to_file("".to_string()).unwrap(); + if prev_screen == AppScreen::ProfileEditor { + return self.data.get_send_command( + ProtocolMsg::ProfileResponse(self.data.get_profile()), + &target, + ); + } } GuiEvent::ChangeName(name) => self.data.profile.name = name, // The following events are already handled in Degeon::process_event diff --git a/degeon_core/Cargo.toml b/degeon_core/Cargo.toml index 9683061..6767d45 100644 --- a/degeon_core/Cargo.toml +++ b/degeon_core/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ironforce = { path = "..", features = ["std"] } +ironforce = { path = "../ironforce", features = ["std"] } base64 = "0.13.0" serde = { version = "1.0" } serde_json = "1.0.72" diff --git a/degeon_core/src/message.rs b/degeon_core/src/message.rs index da17387..f5604d6 100644 --- a/degeon_core/src/message.rs +++ b/degeon_core/src/message.rs @@ -43,6 +43,8 @@ pub enum DegMessageContent { pub struct Profile { #[pyo3(get, set)] pub name: String, + #[pyo3(get, set)] + pub bio: String, } /// A protocol message (that's sent through IF) diff --git a/degeon_py/active_chat.py b/degeon_py/active_chat.py index 38bef75..ee0e4c6 100644 --- a/degeon_py/active_chat.py +++ b/degeon_py/active_chat.py @@ -44,14 +44,14 @@ class ActiveChat: """ return cls(chat=chat, **kwargs) - def get_messages(self) -> typing.Iterable[Message]: + def get_messages(self, core: dc.Degeon) -> typing.Iterable[Message]: """ Get an iterator over all messages in this chat in the backwards order This function creates a python `message.Message` object from rust instances :return: an iterator of `message.Message` objects """ for msg in reversed(self.chat.messages): - yield Message(text=msg.get_content_py().text, is_from_me=False) + yield Message(text=msg.get_content_py().text, is_from_me=core.check_message_ownership(msg)) def get_header(self) -> pygame.Surface: """ @@ -66,7 +66,7 @@ class ActiveChat: surface.blit(name_surface, (20, 20)) return surface - def render(self) -> pygame.Surface: + def render(self, core: dc.Degeon) -> pygame.Surface: """ Creates a pygame surface and draws the chat on it :return: the surface with the chat on it @@ -77,7 +77,7 @@ class ActiveChat: # Render messages # This is the y0 for the last message last_message_y = self.height - MESSAGE_HEIGHT * 2 - for i, message in zip(range(30), self.get_messages()): + for i, message in zip(range(30), self.get_messages(core)): msg_surface = message.render() surface.blit(msg_surface, (0, last_message_y - (MESSAGE_HEIGHT + 30) * (i + 1))) # Render header diff --git a/degeon_py/degeon.py b/degeon_py/degeon.py index 13a2da4..35de341 100644 --- a/degeon_py/degeon.py +++ b/degeon_py/degeon.py @@ -44,7 +44,7 @@ class Degeon: chats_surface = self.chat_selector.render() screen.blit(chats_surface, (0, 0)) if self.active_chat is not None: - active_chat_surface = self.active_chat.render() + active_chat_surface = self.active_chat.render(self.core) screen.blit(active_chat_surface, (self.active_chat.delta_x, 0)) else: text_surface: pygame.Surface = font.render('<- Select chat in the menu', True, WHITE) diff --git a/degeon_py/message.py b/degeon_py/message.py index dabd25c..e09a764 100644 --- a/degeon_py/message.py +++ b/degeon_py/message.py @@ -35,7 +35,7 @@ class Message: # Size of the scaled text surface blit_height: int = self.height - padding * 2 blit_width: int = round(text_surface.get_width() * blit_height / text_surface.get_height()) - x: int = 0 if not self.is_from_me else self.chat_width - blit_width - padding * 2 + x: int = 0 if not self.is_from_me else self.chat_width - blit_width - padding * 3.5 pygame.draw.rect(surface, bg_color, (x, 0, blit_width + padding * 2, self.height)) text_surface: pygame.Surface = pygame.transform.smoothscale(text_surface, (blit_width, blit_height)) surface.blit(text_surface, (x + padding, padding)) diff --git a/examples/test_ip_connection.rs b/examples/test_ip_connection.rs deleted file mode 100644 index cc59e8e..0000000 --- a/examples/test_ip_connection.rs +++ /dev/null @@ -1,49 +0,0 @@ -#[cfg(feature = "std")] -use ironforce::interface::Interface; -#[cfg(feature = "std")] -use ironforce::interfaces::ip::IPInterface; -#[cfg(feature = "std")] -use std::net; -use std::thread; -use std::time::Duration; -#[cfg(feature = "std")] -use ironforce::res::IFResult; - -#[cfg(feature = "std")] -fn main() { - println!("hello"); - test(); -} - -#[cfg(feature = "std")] -fn test() -> IFResult<()> { - let message = *b"Hello world from iron forest"; - - let mut interface1 = IPInterface::new()?; - let mut interface2 = IPInterface::new()?; - - let t1 = std::thread::spawn(move || { - interface1.send(&message, Some(String::from("127.0.0.1:50001"))).unwrap(); - interface1 - }); - thread::sleep(Duration::from_millis(10)); - let t2 = std::thread::spawn(move || { - - interface2.main_loop_iteration().unwrap(); - interface2 - }); - let res1 = t1.join(); - match res1 { - Ok(_) => println!("Ok"), - Err(e) => println!("{:?}", e) - } - let res2 = t2.join(); - match res2 { - Ok(_) => println!("Ok"), - Err(e) => println!("{:?}", e) - } - Ok(()) -} - -#[cfg(not(feature = "std"))] -fn main() {} diff --git a/images/explanation.svg b/images/explanation.svg index 9e520b6..cccf792 100644 --- a/images/explanation.svg +++ b/images/explanation.svg @@ -24,9 +24,9 @@ inkscape:pagecheckerboard="0" inkscape:document-units="mm" showgrid="false" - inkscape:zoom="1.0684095" - inkscape:cx="198.89378" - inkscape:cy="192.34198" + inkscape:zoom="0.42190593" + inkscape:cx="117.32473" + inkscape:cy="387.52714" inkscape:window-width="1920" inkscape:window-height="1036" inkscape:window-x="0" @@ -111,13 +111,19 @@ height="93.487419" x="8.5933933" y="5.2217455" - ry="8.0541668" /> + ry="8.0541668" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> IronForce worker + transform="matrix(0.50052676,0,0,0.50052676,86.42112,10.813918)" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49"> keys + id="tspan44898">keys messages + id="tspan44900">messages transport + id="tspan44902">transport tunnels + id="tspan44904">tunnels + sodipodi:nodetypes="csc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + ry="8.0541553" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + ry="8.0541553" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + ry="3.5077736" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + ry="3.5077665" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> Messages are collected + id="tspan44906">Messages are collected into a queue + id="tspan44910">into a queue in another thread + id="tspan44914">in another thread + ry="3.5077665" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + r="6.170032" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + id="path33547" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + id="path33812" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + transform="matrix(0.45409146,0,0,0.45409146,31.061511,94.796231)" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49"> + r="39.348465" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> + sodipodi:nodetypes="cc" + inkscape:export-filename="/home/ennucore/dev/ironforce/scheme.png" + inkscape:export-xdpi="1121.49" + inkscape:export-ydpi="1121.49" /> diff --git a/ironforce/Cargo.toml b/ironforce/Cargo.toml new file mode 100644 index 0000000..605de51 --- /dev/null +++ b/ironforce/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "ironforce" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "ironforce" +path = "src/lib.rs" + + +[features] +default = [] +std = ["rayon"] + +[dependencies] +rand_os = "*" +# x25519-dalek = "0.6.0" +# ed25519-dalek = { version = "1.0", features = ["serde"] } +sha2 = "0.8.1" +rand = "*" +rsa = { version = "0.5", features = ["serde"] } +serde = { version = "1.0", features = ["derive", "alloc"], default-features = false } +rayon = { version = "1.5.1", optional = true } +core-error = "0.0.1-rc4" +serde_cbor = "0.11.2" +serde_json = "1.0.72" +spin = "0.9.2" +base64 = "0.13.0" +include_optional = "1.0.1" + +[[bin]] +name = "worker" +required-features = ["std"] diff --git a/src/bin/worker.rs b/ironforce/src/bin/worker.rs similarity index 100% rename from src/bin/worker.rs rename to ironforce/src/bin/worker.rs diff --git a/src/crypto.rs b/ironforce/src/crypto.rs similarity index 100% rename from src/crypto.rs rename to ironforce/src/crypto.rs diff --git a/src/interface.rs b/ironforce/src/interface.rs similarity index 100% rename from src/interface.rs rename to ironforce/src/interface.rs diff --git a/src/interfaces/ip.rs b/ironforce/src/interfaces/ip.rs similarity index 96% rename from src/interfaces/ip.rs rename to ironforce/src/interfaces/ip.rs index 59e57ea..9667070 100644 --- a/src/interfaces/ip.rs +++ b/ironforce/src/interfaces/ip.rs @@ -2,9 +2,9 @@ use alloc::borrow::ToOwned; use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; -use core::ops::RangeInclusive; use core::str::FromStr; use core::time::Duration; +use include_optional::include_str_optional; use rayon::prelude::*; use serde::{Deserialize, Serialize}; use std::net::TcpStream; @@ -17,11 +17,13 @@ use crate::std::io::{Read, Write}; use crate::std::println; pub const DEFAULT_PORT: u16 = 50000; -const SOCKET_RANGE: RangeInclusive = 50000..=50010; /// The threshold for the number of peers below which we are desperate const PEER_THRESHOLD: usize = 70; +/// Default peers +const DEFAULT_PEERS_FILE: Option<&'static str> = include_str_optional!(".if_ip_peers"); + type Peer = (net::IpAddr, u16); /// Interface for interactions using tcp sockets @@ -271,12 +273,12 @@ impl Interface for IPInterface { Err(_) => { self.remove_all_connections_to_peer(&peer); let index = self.obtain_connection(&(addr.ip(), addr.port()))?; - IPInterface::send_package(&mut self.connections[index], package).map_err( - |e| { + IPInterface::send_package(&mut self.connections[index], package) + .map_err(|e| { println!("Error while sending: {:?}", e); e - }, - ).unwrap_or_default(); + }) + .unwrap_or_default(); } } } @@ -342,17 +344,19 @@ impl Interface for IPInterface { IPInterface::new(data.port, data.peers) } else { let ip_path = std::path::Path::new(".if_ip_peers"); - let peers = if ip_path.exists() { - std::fs::read_to_string(ip_path) - .unwrap() - .split('\n') - .filter_map(|line| net::SocketAddr::from_str(line).ok()) - .map(|addr| (addr.ip(), addr.port())) - .collect() + let data = if ip_path.exists() { + std::fs::read_to_string(ip_path).unwrap() + } else if let Some(data) = DEFAULT_PEERS_FILE { + data.to_string() } else { println!("Warning: there are no peers in IP, which makes it essentially useless"); - vec![] + "".to_string() }; + let peers = data + .split('\n') + .filter_map(|line| net::SocketAddr::from_str(line).ok()) + .map(|addr| (addr.ip(), addr.port())) + .collect(); IPInterface::new(DEFAULT_PORT, peers) } } diff --git a/src/interfaces/mod.rs b/ironforce/src/interfaces/mod.rs similarity index 100% rename from src/interfaces/mod.rs rename to ironforce/src/interfaces/mod.rs diff --git a/src/ironforce.rs b/ironforce/src/ironforce.rs similarity index 100% rename from src/ironforce.rs rename to ironforce/src/ironforce.rs diff --git a/src/lib.rs b/ironforce/src/lib.rs similarity index 90% rename from src/lib.rs rename to ironforce/src/lib.rs index 555ab4e..42ac601 100644 --- a/src/lib.rs +++ b/ironforce/src/lib.rs @@ -12,6 +12,8 @@ extern crate rsa; extern crate serde; extern crate core_error; extern crate spin; +#[cfg(feature = "std")] +extern crate include_optional; mod crypto; mod ironforce; diff --git a/src/message.rs b/ironforce/src/message.rs similarity index 100% rename from src/message.rs rename to ironforce/src/message.rs diff --git a/src/res.rs b/ironforce/src/res.rs similarity index 100% rename from src/res.rs rename to ironforce/src/res.rs diff --git a/src/transport.rs b/ironforce/src/transport.rs similarity index 100% rename from src/transport.rs rename to ironforce/src/transport.rs diff --git a/src/tunnel.rs b/ironforce/src/tunnel.rs similarity index 100% rename from src/tunnel.rs rename to ironforce/src/tunnel.rs