summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-02-28 16:14:18 +0100
committersalmonik <raisersoft@proton.me>2026-02-28 16:14:18 +0100
commit63a3c3e4be75c757383be46e196a4462d8da818b (patch)
treeb21b78b371e1e16d7b76e1804286f75945e8fa93
downloadzagan-bet-63a3c3e4be75c757383be46e196a4462d8da818b.tar.gz
zagan-bet-63a3c3e4be75c757383be46e196a4462d8da818b.zip
init version
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock32
-rw-r--r--Cargo.toml7
-rw-r--r--src/bin/client.rs98
-rw-r--r--src/bin/server.rs66
5 files changed, 204 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..17b9b81
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,32 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 4
4
5[[package]]
6name = "winapi"
7version = "0.3.9"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
10dependencies = [
11 "winapi-i686-pc-windows-gnu",
12 "winapi-x86_64-pc-windows-gnu",
13]
14
15[[package]]
16name = "winapi-i686-pc-windows-gnu"
17version = "0.4.0"
18source = "registry+https://github.com/rust-lang/crates.io-index"
19checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
20
21[[package]]
22name = "winapi-x86_64-pc-windows-gnu"
23version = "0.4.0"
24source = "registry+https://github.com/rust-lang/crates.io-index"
25checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
26
27[[package]]
28name = "zagan-bet"
29version = "0.1.0"
30dependencies = [
31 "winapi",
32]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..33903f4
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,7 @@
1[package]
2name = "zagan-bet"
3version = "0.1.0"
4edition = "2024"
5
6[dependencies]
7winapi = { version = "0.3", features = ["consoleapi", "processenv", "wincon", "minwindef", "winbase"] }
diff --git a/src/bin/client.rs b/src/bin/client.rs
new file mode 100644
index 0000000..45c5090
--- /dev/null
+++ b/src/bin/client.rs
@@ -0,0 +1,98 @@
1use std::io::{BufRead, BufReader, Write, stdin, stdout};
2use std::net::TcpStream;
3use std::time::Instant;
4
5#[cfg(windows)]
6mod win {
7 use std::io;
8 use std::os::windows::io::AsRawHandle;
9 use winapi::um::consoleapi::GetConsoleMode;
10 use winapi::um::consoleapi::SetConsoleMode;
11 use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
12 use winapi::um::winbase::STD_OUTPUT_HANDLE;
13 use winapi::um::processenv::GetStdHandle;
14 use winapi::shared::minwindef::DWORD;
15
16 pub fn enable_vt() -> io::Result<()> {
17 unsafe {
18 let h = GetStdHandle(STD_OUTPUT_HANDLE);
19 if h.is_null() { return Err(io::Error::last_os_error()); }
20
21 let mut mode: DWORD = 0;
22 if GetConsoleMode(h, &mut mode) == 0 {
23 return Err(io::Error::last_os_error());
24 }
25 let new = mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
26 if SetConsoleMode(h, new) == 0 {
27 return Err(io::Error::last_os_error());
28 }
29 Ok(())
30 }
31 }
32}
33
34fn main() {
35 #[cfg(windows)]
36 win::enable_vt().unwrap();
37
38 let mut addr: Option<String>;
39 let mut stream: Option<TcpStream> = None;
40 loop {
41 print!("Command: ");
42 stdout().flush().unwrap();
43 let mut line = String::new();
44 stdin().read_line(&mut line).unwrap();
45 let line = line.trim();
46 if line.is_empty() {
47 continue;
48 }
49 let parts: Vec<&str> = line.splitn(2, ' ').collect();
50 match parts[0] {
51 "connect" => {
52 if parts.len() < 2 {
53 println!("Usage: connect <addr>");
54 continue;
55 }
56 addr = Some(parts[1].to_string());
57 match TcpStream::connect(addr.as_ref().unwrap()) {
58 Ok(s) => {
59 let mut ping_writer = s.try_clone().unwrap();
60 let mut ping_reader = BufReader::new(s.try_clone().unwrap());
61 let start = Instant::now();
62 writeln!(ping_writer, "PING").unwrap();
63 let mut response = String::new();
64 ping_reader.read_line(&mut response).unwrap();
65 let elapsed = start.elapsed();
66 println!("Connected to {} with ping delay: {:?}", addr.as_ref().unwrap(), elapsed);
67 stream = Some(s);
68 }
69 Err(e) => {
70 println!("Failed to connect: {}", e);
71 }
72 }
73 }
74 "send" => {
75 if stream.is_none() {
76 println!("Not connected. Use 'connect <addr>' first.");
77 continue;
78 }
79 if parts.len() < 2 {
80 println!("Usage: send <message>");
81 continue;
82 }
83 let msg = parts[1];
84 let s = stream.as_mut().unwrap();
85 let writer_stream = s.try_clone().unwrap();
86 let mut writer = writer_stream;
87 let response_reader_stream = s.try_clone().unwrap();
88 let mut response_reader = BufReader::new(response_reader_stream);
89 writeln!(writer, "{}", msg).unwrap();
90 let mut response = String::new();
91 response_reader.read_line(&mut response).unwrap();
92 println!("Echo: {}", response.trim());
93 }
94 "quit" => break,
95 _ => println!("Unknown command. Available: connect, send, quit"),
96 }
97 }
98}
diff --git a/src/bin/server.rs b/src/bin/server.rs
new file mode 100644
index 0000000..215d2ae
--- /dev/null
+++ b/src/bin/server.rs
@@ -0,0 +1,66 @@
1use std::io::{BufRead, BufReader, Write};
2use std::net::TcpListener;
3use std::thread;
4
5fn handle_client(stream: std::net::TcpStream) {
6 println!("Client connected");
7 let reader_stream = stream.try_clone().unwrap();
8 let reader = BufReader::new(reader_stream);
9 let mut writer = stream;
10 for line in reader.lines() {
11 let line = line.unwrap();
12 println!("Received: {}", line);
13 writeln!(writer, "{}", line).unwrap();
14 }
15 println!("Client disconnected");
16}
17
18fn main() {
19 let args: Vec<String> = std::env::args().collect();
20 let mut ip = "127.0.0.1".to_string();
21 let mut port = 8080;
22 let mut i = 1;
23 while i < args.len() {
24 if args[i] == "-p" {
25 if i + 1 < args.len() {
26 port = args[i + 1].parse::<u16>().unwrap_or_else(|_| {
27 eprintln!("Invalid port number: {}", args[i + 1]);
28 std::process::exit(1);
29 });
30 i += 2;
31 } else {
32 eprintln!("-p requires a port number");
33 std::process::exit(1);
34 }
35 } else if args[i] == "-i" {
36 if i + 1 < args.len() {
37 ip = args[i + 1].clone();
38 if ip != "127.0.0.1" && ip != "0.0.0.0" {
39 eprintln!("Invalid IP address: {}. Must be 127.0.0.1 or 0.0.0.0", ip);
40 std::process::exit(1);
41 }
42 i += 2;
43 } else {
44 eprintln!("-i requires an IP address");
45 std::process::exit(1);
46 }
47 } else {
48 eprintln!("Unknown argument: {}", args[i]);
49 std::process::exit(1);
50 }
51 }
52 let listener = match TcpListener::bind(format!("{}:{}", ip, port)) {
53 Ok(l) => l,
54 Err(e) => {
55 eprintln!("Failed to bind to {}:{}: {}", ip, port, e);
56 std::process::exit(1);
57 }
58 };
59 println!("Server listening on {}", listener.local_addr().unwrap());
60 for stream in listener.incoming() {
61 let stream = stream.unwrap();
62 thread::spawn(move || {
63 handle_client(stream);
64 });
65 }
66}