init commit

This commit is contained in:
MeexReay 2024-05-18 01:43:53 +03:00
commit 7130f872bc
9 changed files with 1214 additions and 0 deletions

629
Cargo.lock generated Normal file
View file

@ -0,0 +1,629 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytebuffer"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7bfaf7cd08cacd74cdc6b521c37ac39cbc92692e5ab5c21ed5657a749b577c"
dependencies = [
"byteorder",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "clearscreen"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f8c93eb5f77c9050c7750e14f13ef1033a40a0aac70c6371535b6763a01438c"
dependencies = [
"nix",
"terminfo",
"thiserror",
"which",
"winapi",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "easymsg"
version = "0.1.0"
dependencies = [
"bytebuffer",
"byteorder",
"chrono",
"clearscreen",
"getch",
]
[[package]]
name = "either"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "getch"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13990e2d5b29e1770ddf7fc000afead4acb9bd8f8a9602de63bf189e261b1ba8"
dependencies = [
"libc",
"termios",
]
[[package]]
name = "getrandom"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys",
]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "js-sys"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nix"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
"siphasher",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "redox_users"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "syn"
version = "2.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "terminfo"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f"
dependencies = [
"dirs",
"fnv",
"nom",
"phf",
"phf_codegen",
]
[[package]]
name = "termios"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
dependencies = [
"libc",
]
[[package]]
name = "thiserror"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "which"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7"
dependencies = [
"either",
"home",
"rustix",
"winsafe",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "winsafe"
version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"

13
Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "easymsg"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bytebuffer = "2.2.0"
byteorder = "1.5.0"
chrono = "0.4.38"
getch = "0.3.1"
clearscreen = "3.0.0"

13
LICENSE Normal file
View file

@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

12
README.md Normal file
View file

@ -0,0 +1,12 @@
# easy_msg
simple cli messenger on rust
# how to use
start server:
```
./easymsg server SERVER_NAME IP:PORT
```
connect server:
```
./easymsg client CLIENT_NAME IP:PORT
```

172
src/chat/chat_client.rs Normal file
View file

@ -0,0 +1,172 @@
use std::cell::RefCell;
use std::io::{Error, Write};
use std::net::TcpStream;
use std::sync::{Arc, Mutex};
use chrono::prelude::*;
use super::chat_packet::*;
#[derive(Debug)]
pub struct Console {
pub input: String,
pub lines: Vec<String>
}
impl Console {
pub fn new() -> Console {
Console {
input: String::new(),
lines: Vec::new()
}
}
pub fn meow(&mut self) {
self.lines.push("meow".to_string());
self.update();
}
pub fn add_line(&mut self, text: String) {
self.lines.push(text);
self.update();
}
pub fn run_input_loop(this: Arc<Mutex<Console>>, on_enter: fn(&mut TcpStream, String) -> (), client: &mut TcpStream) -> Result<(), Error> {
let ge = getch::Getch::new();
loop {
match ge.getch() {
Ok(i) => {
let mut th = this.lock().unwrap();
match i {
127 => {
if th.input.len() > 0 {
th.input = (&th.input[..th.input.len()-1]).to_string();
}
th.update();
}, 10 => {
// th.meow();
on_enter(client, th.input.clone());
th.input = String::new();
th.update();
}, _ => {
let ch = &String::from_utf8(vec![i]).unwrap();
// let was = th.input.clone();
th.input.push_str(ch);
th.update();
}
}
},
Err(_) => {},
}
};
}
pub fn update(&mut self) {
clearscreen::clear().unwrap();
let mut text = "\n".to_string();
for l in self.lines.as_slice() {
text += &(l.to_string() + "\n");
}
text += &("> ".to_string() + self.input.as_str());
std::io::stdout()
.write_all(text.as_bytes())
.unwrap();
std::io::stdout()
.flush()
.unwrap();
}
}
#[derive(Debug)]
pub struct ChatClient {
pub me: String,
pub messages: Vec<Message>,
pub chat_name: String,
pub stream: Option<TcpStream>,
pub console: Arc<Mutex<Console>>
}
impl ChatClient {
pub fn new(name: String, console: Arc<Mutex<Console>>) -> Self {
ChatClient {
me: name,
messages: Vec::new(),
chat_name: String::from("Chat"),
stream: None,
console: console
}
}
pub fn on_enter(stream: &mut TcpStream, text: String) {
Self::send_message(stream, text).unwrap();
}
pub fn on_message(&mut self, msg: &Message) {
self.console.lock().unwrap().add_line(format!("{} | {} > {}", msg.sent_at, msg.author, msg.text));
}
pub fn communicate(&mut self) -> Result<(), Error> {
Self::send_join(&mut self.stream.as_mut().unwrap(), &self.me)?;
loop {
let mut packet = read_packet(&mut self.stream.as_mut().unwrap())?;
// dbg!(&packet);
match packet.id {
b'm' => {
let msg = Message::new(
packet.buffer.read_string()?,
packet.buffer.read_string()?,
DateTime::from_timestamp(packet.buffer.read_i64()?,0).unwrap()
);
self.on_message(&msg);
self.messages.push(msg);
}, b'n' => {
self.chat_name = packet.buffer.read_string()?;
}, _ => {
println!("packet error");
break;
}
}
}
close_stream(&mut self.stream.as_mut().unwrap())?;
Ok(())
}
pub fn connect(&mut self, host: String) -> Result<(), Error> {
self.stream = Some(TcpStream::connect(host.clone())?);
Ok(())
}
pub fn send_message(stream: &mut TcpStream, text: String) -> Result<(), Error> {
let packet = ChatPacket::build(b's', &|p| {
p.buffer.write_string(&text);
});
send_packet(stream, &packet)
}
pub fn send_join(stream: &mut TcpStream, name: &String) -> Result<(), Error> {
let packet = ChatPacket::build(b'j', &|p| {
p.buffer.write_string(&name);
});
send_packet(stream, &packet)
}
pub fn send_quit(stream: &mut TcpStream) -> Result<(), Error> {
let packet = ChatPacket::empty(b'q');
send_packet(stream, &packet)
}
}

87
src/chat/chat_packet.rs Normal file
View file

@ -0,0 +1,87 @@
use std::io::{Read, Write, Error};
use std::net::{TcpStream, Shutdown};
use bytebuffer::ByteBuffer;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use chrono::DateTime;
use chrono::Utc;
#[derive(Clone, Debug)]
pub struct Message {
pub author: String,
pub text: String,
pub sent_at: DateTime<Utc>
}
impl Message {
pub fn new(text: String,
author: String,
sent_at: DateTime<Utc>) -> Message {
Message {
author,
text,
sent_at
}
}
pub fn at_now(text: String, author: String) -> Message {
Message {
author,
text,
sent_at: Utc::now()
}
}
}
pub fn close_stream(stream: &mut TcpStream) -> Result<(), Error> {
stream.shutdown(Shutdown::Both)
}
#[derive(Debug)]
pub struct ChatPacket {
pub id: u8,
pub buffer: ByteBuffer
}
impl ChatPacket {
pub fn new(id: u8, buffer: ByteBuffer) -> ChatPacket {
ChatPacket { id, buffer }
}
pub fn empty(id: u8) -> ChatPacket {
ChatPacket { id, buffer: ByteBuffer::new() }
}
pub fn from_bytes(id: u8, bytes: &[u8]) -> ChatPacket {
ChatPacket { id, buffer: ByteBuffer::from_bytes(bytes) }
}
pub fn build(id: u8, builder: &dyn Fn(&mut ChatPacket) -> ()) -> ChatPacket {
let mut packet = Self::empty(id);
builder(&mut packet);
packet
}
}
pub fn read_packet(stream: &mut TcpStream) -> Result<ChatPacket, Error> {
let length = stream.read_u64::<BigEndian>()? as usize;
let packet_id = stream.read_u8()?;
let mut data: Vec<u8> = vec![0; length - 1];
stream.read(&mut data)?;
Ok(ChatPacket::from_bytes(packet_id, &data))
}
pub fn send_packet(stream: &mut TcpStream, packet: &ChatPacket) -> Result<(), Error> {
let mut buf = ByteBuffer::new();
buf.write_u8(packet.id);
buf.write(packet.buffer.as_bytes())?;
stream.write_u64::<BigEndian>(buf.len() as u64)?;
stream.write(&buf.as_bytes())?;
Ok(())
}

177
src/chat/chat_server.rs Normal file
View file

@ -0,0 +1,177 @@
use std::net::{TcpListener, TcpStream};
use std::sync::Mutex;
use std::sync::Arc;
use std::thread;
use std::io::Error;
use std::time::Duration;
use super::chat_packet::*;
pub struct ChatServer {
pub host: String,
pub name: String,
pub messages: Vec<Message>,
pub conns: Vec<TcpStream>
}
pub fn send_packet_all(server: &mut ChatServer, packet: ChatPacket) -> Result<(), Error> {
for stream in &mut server.conns {
send_packet(stream, &packet)?;
}
Ok(())
}
static mut MEOW_TIME: u32 = 0;
fn meow() {
unsafe {
MEOW_TIME += 1;
println!("meow {}", MEOW_TIME);
}
}
impl ChatServer {
pub fn new(host: String, name: String) -> Self {
ChatServer {
host: host,
name: name,
messages: Vec::new(),
conns: Vec::new()
}
}
pub fn send_message(&mut self, msg: Message) -> Result<(), Error> {
println!("{} | {} > {}", msg.sent_at, msg.author, msg.text);
let packet = ChatPacket::build(b'm', &|p| {
p.buffer.write_string(&msg.text);
p.buffer.write_string(&msg.author);
p.buffer.write_i64(msg.sent_at.timestamp());
});
send_packet_all(self, packet)?;
self.messages.push(msg);
Ok(())
}
pub fn send_message_packet(&mut self, stream: &mut TcpStream, msg: &Message) -> Result<(), Error> {
let packet = ChatPacket::build(b'm', &|p| {
p.buffer.write_string(&msg.text);
p.buffer.write_string(&msg.author);
p.buffer.write_i64(msg.sent_at.timestamp());
});
send_packet(stream, &packet)?;
// println!("send message packet");
Ok(())
}
pub fn send_chat_name(&mut self, stream: &mut TcpStream) -> Result<(), Error> {
let packet = ChatPacket::build(b'n', &|p| {
p.buffer.write_string(&self.name);
});
send_packet(stream, &packet)?;
// println!("send chat name");
Ok(())
}
pub fn join_client(this: Arc<Mutex<ChatServer>>, stream: &mut TcpStream, name: String) -> Result<(), Error> {
println!("connected lol {}", name.clone());
// dbg!(&this.lock().unwrap().messages);
this.lock().unwrap().send_chat_name(stream)?;
let messages = &this.lock().unwrap().messages.clone();
for m in messages {
this.lock().unwrap().send_message_packet(stream, m)?;
}
loop {
let mut packet = read_packet(stream)?;
match packet.id {
b's' => {
this.lock().unwrap().send_message(Message::at_now(packet.buffer.read_string()?, name.clone()))?;
},
_ => {
break;
}
}
}
close_stream(stream)?;
Ok(())
}
pub fn accept_client(this: Arc<Mutex<ChatServer>>, stream: &mut TcpStream) -> Result<(), Error> {
println!("stream got!!! lol {:?}", &stream);
let mut packet: ChatPacket = read_packet(stream)?;
println!("packet got!!! lol {:?}", &packet);
match packet.id {
b'j' => {
Self::join_client(this, stream, packet.buffer.read_string()?)
}, _ => {
close_stream(stream)?;
Ok(())
}
}
}
pub fn run(self) {
let listener: TcpListener = TcpListener::bind(self.host.clone()).expect("bind error");
println!("binded lol {}", self.host.clone());
let arc_self = Arc::new(Mutex::new(self));
loop {
let (mut socket, _) = listener.accept().expect("accept error");
let local_self = arc_self.clone();
thread::spawn(move || {
meow();
let socket_clone = match socket.try_clone() {
Ok(i) => i,
Err(_) => { return },
};
meow();
let mut ind: usize = 0;
{
let mut se = local_self.lock().unwrap();
ind = se.conns.len();
se.conns.push(socket_clone);
}
meow();
match Self::accept_client(local_self.clone(), &mut socket) {
Ok(_) => { println!("disconnected normally") },
Err(_) => { println!("trahnutiy disconnect XDDDDDDDDDDD))))))000)0)0)))") },
};
meow();
local_self.lock().unwrap().conns.remove(ind);
meow();
});
}
}
}

7
src/chat/mod.rs Normal file
View file

@ -0,0 +1,7 @@
pub mod chat_client;
pub mod chat_server;
pub mod chat_packet;
pub use chat_client::*;
pub use chat_server::*;
pub use chat_packet::*;

104
src/main.rs Normal file
View file

@ -0,0 +1,104 @@
mod chat;
use chat::*;
use std::env;
use chrono::Utc;
use std::sync::{Arc, Mutex};
use std::cell::{RefCell};
use std::thread;
use std::pin::pin;
fn main() {
let args: Vec<String> = Vec::from_iter(env::args());
if args.len() > 1 {
if args[1].as_str() == "server" {
let mut server = ChatServer::new(
args[3].clone(),
args[2].clone());
server.messages.push(Message {
author: "avtor".to_string(),
text: "text".to_string(),
sent_at: Utc::now()
});
server.run();
} else if args[1].as_str() == "client" {
let console = Arc::new(Mutex::new(Console::new()));
console.lock().unwrap().update();
let mut client = ChatClient::new(args[2].clone(), console.clone());
let console_copy = console.clone();
client.connect(args[3].clone()).unwrap();
let mut input_stream = client.stream.as_mut().unwrap().try_clone().unwrap();
thread::spawn(move || {
Console::run_input_loop(
console_copy,
ChatClient::on_enter,
&mut input_stream);
});
client.communicate().unwrap();
}
}
// let моя_коза = МояГоворящаяКоза::создать(true);
// моя_коза.финты_ушами();
// моя_коза.поздароваться();
// моя_коза.привет("Товарищ Сталин".to_string());
}
// struct МояГоворящаяКоза {
// здоровье: u128,
// еда_в_холодильнике: u8,
// возраст: u128,
// коммунист: bool,
// кличка: String
// }
// impl МояГоворящаяКоза {
// fn создать(коммунист: bool) -> МояГоворящаяКоза {
// МояГоворящаяКоза {
// здоровье: 9999999999999999999,
// еда_в_холодильнике: 0,
// возраст: 9,
// коммунист: коммунист,
// кличка: "Ленин".to_string()
// }
// }
// fn финты_ушами(&self) {
// println!("{} крутит финты ушами", self.кличка);
// }
// fn поздароваться(&self) {
// println!("{} поздаровался", self.кличка);
// }
// }
// trait ГоворящееЧтото {
// fn моя_кличка(&self) -> &String;
// fn привет(&self, имя: String) {
// println!("{} сказал привет {}", self.моя_кличка(), имя);
// }
// }
// impl ГоворящееЧтото for МояГоворящаяКоза {
// fn моя_кличка(&self) -> &String {
// &self.кличка
// }
// }
// console.run_event_loop():
// on_enter:
// client.send_message()
// client.connect():
// on_message:
// console.print()