1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::sync::Arc;
use broadcasts::Broadcast;
use commands::handle_commands;
use state::ServerState;
use tokio::{
io::{self, AsyncReadExt, AsyncWriteExt},
net::TcpListener,
spawn,
};
pub mod broadcasts;
pub mod commands;
pub mod messages;
pub mod routines;
pub mod state;
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("0.0.0.0:7426").await.unwrap();
let state = Arc::new(ServerState::new());
{
let state = state.clone();
spawn(async move {
let mut rx = state.broadcasts.subscribe();
loop {
let broadcast = rx.recv().await.unwrap();
print!("{broadcast}");
}
});
}
loop {
let (mut socket, _) = listener.accept().await.unwrap();
let state = state.clone();
spawn(async move {
match routines::prejoin(&mut socket, &state).await {
Ok(_) => (),
Err(_) => return,
};
let mut user = match routines::get_nickname(&mut socket, &state).await {
Ok(Some(u)) => u,
Ok(None) | Err(_) => return,
};
match routines::postjoin(&mut socket).await {
Ok(_) => (),
Err(_) => return,
};
let (mut rsocket, mut wsocket) = io::split(socket);
let mut rx = state.broadcasts.subscribe();
let mut buffer = [0u8; 256];
loop {
buffer.fill(0);
tokio::select! {
res = rx.recv() => {
let res = res.unwrap();
match res.send_to_all() {
true => {
let res = res.to_string();
match wsocket.write_all(res.as_bytes()).await {
Ok(_) => (),
Err(_) => break,
}
}
false => {
if let Broadcast::UserPoke{poker, poked} = &res {
if &user.name == &poker.name {
let res = res.actor_string();
match wsocket.write_all(res.as_bytes()).await {
Ok(_) => (),
Err(_) => break,
}
}
if &user.name == &poked.name {
let res = res.target_string();
match wsocket.write_all(res.as_bytes()).await {
Ok(_) => (),
Err(_) => break,
}
}
}
}
}
}
res = rsocket.read(&mut buffer) => {
match res {
Ok(0) | Err(_) => break,
Ok(_) => {
let msg: String = String::from_utf8_lossy(&buffer).chars()
.filter(|c| {
c.is_alphabetic() || c.is_digit(10) || c.is_ascii_punctuation() || *c == ' '
}).collect();
match msg.starts_with('/') {
true => {
match handle_commands(msg, &mut wsocket, &mut user, &state).await {
Ok(_) => (),
Err(_) => return,
}
},
false => {
state.broadcasts.send(Broadcast::UserMessage {
user: user.clone(),
message: msg,
}).unwrap();
}
}
},
}
}
}
}
let mut users = state.users.write().await;
users.retain(|u| u.name != user.name);
state.broadcasts.send(Broadcast::UserLeft(user)).unwrap();
});
}
}