1use std::{
2 net::UdpSocket,
3 ops::{AddAssign, Sub},
4 sync::{Arc, RwLock},
5 thread::{self, JoinHandle},
6 time::{Duration, SystemTime},
7};
8
9use bytes_kman::TBytes;
10use muzzman_lib::prelude::*;
11use packets::{ClientPackets, ServerPackets};
12
13pub mod common;
14pub mod daemon;
15pub mod packets;
16pub mod row;
17pub mod session;
18
19pub const DAEMON_PORT: u16 = 2118;
20
21pub mod prelude {
22 pub use crate::common::get_modules;
23 pub use crate::DaemonSession;
24 pub use muzzman_lib::prelude::*;
25}
26
27pub struct DaemonSession {
28 pub conn: UdpSocket,
29 pub packets: Vec<ClientPackets>,
30 pub generator: u128,
31 pub locations_refs: Vec<LRef>,
32 pub element_refs: Vec<ERef>,
33 pub module_refs: Vec<MRef>,
34 pub watcher_thread: JoinHandle<()>,
35}
36
37unsafe impl Send for DaemonSession {}
38unsafe impl Sync for DaemonSession {}
39
40impl DaemonSession {
41 pub fn new() -> Result<Self, std::io::Error> {
42 let conn = UdpSocket::bind("127.0.0.1:0")?;
43 conn.connect(format!("127.0.0.1:{DAEMON_PORT}"))?;
44 let _ = conn.set_nonblocking(true);
45 let _ = conn.set_read_timeout(Some(Duration::new(10, 0)));
46 Ok(Self {
47 conn,
48 packets: Vec::new(),
49 generator: 1,
50 locations_refs: Vec::new(),
51 element_refs: Vec::new(),
52 module_refs: Vec::new(),
53 watcher_thread: thread::spawn(|| {}),
54 })
55 }
56
57 pub fn pull_packets(&mut self) {
58 let mut buffer = [0; 4096];
59
60 if let Ok(len) = self.conn.recv(&mut buffer) {
61 let mut buffer = buffer[0..len].to_vec();
62
63 while !buffer.is_empty() {
64 if let Some(packet) = ClientPackets::from_bytes(&mut buffer) {
65 if let ClientPackets::NewSessionEvent(event) = packet {
66 match event {
67 SessionEvent::DestroyedElement(id) => {
68 self.element_refs.retain(|eref| eref.id() != id);
69 }
70 SessionEvent::DestroyedLocation(id) => {
71 self.locations_refs.retain(|lref| lref.id() != id)
72 }
73 SessionEvent::DestroyedModule(id) => {
74 self.module_refs.retain(|mref| mref.id() != id)
75 }
76 SessionEvent::ElementIdChanged(last, new) => {
77 for eref in self.element_refs.iter_mut() {
78 if eref.id() == last {
79 eref.write().unwrap().id = new.clone();
80 break;
81 }
82 }
83 }
84 SessionEvent::LocationIdChanged(last, new) => {
85 for lref in self.locations_refs.iter_mut() {
86 if lref.id() == last {
87 lref.write().unwrap().id = new;
88 break;
89 }
90 }
91 }
92 SessionEvent::ModuleIdChanged(last, new) => {
93 for mref in self.module_refs.iter_mut() {
94 if mref.id() == last {
95 mref.write().unwrap().uid = new;
96 }
97 }
98 }
99 _ => {}
100 }
101 } else {
102 self.packets.push(packet)
103 }
104 }
105 }
106 }
107 }
108
109 pub fn gc_refs(&mut self) {
110 self.module_refs.retain(|mref| {
111 let count = Arc::strong_count(mref);
112 count > 1
113 });
114
115 self.locations_refs.retain(|lref| {
116 let count = Arc::strong_count(lref);
117 count > 1
118 });
119
120 self.element_refs.retain(|eref| {
121 let count = Arc::strong_count(eref);
122 count > 1
123 });
124 }
125
126 pub fn create_session(self) -> Box<dyn TSession> {
127 let s = Arc::new(RwLock::new(self));
128
129 let sc = s.clone();
130
131 s.write().unwrap().watcher_thread = thread::spawn(move || {
132 let sc = sc;
133 loop {
134 thread::sleep(Duration::new(1, 0));
135 let count = Arc::strong_count(&sc);
136 sc.write().unwrap().gc_refs();
137 if count == 1 {
138 break;
139 }
140 sc.pull_packets();
141 let mut bytes = ServerPackets::Tick.to_bytes();
142 bytes.reverse();
143 let _ = sc.read().unwrap().conn.send(&bytes);
144 }
145 });
146
147 Box::new(Box::new(s) as Box<dyn TDaemonSession>)
148 }
149}
150
151pub trait TDaemonSession {
152 fn pull_packets(&self);
153
154 fn waiting_for(&self, id: u128) -> Option<ClientPackets>;
155 fn send(&self, packet: ServerPackets);
156 fn generate(&self) -> u128;
157
158 fn eref_get_or_add(&self, element_id: ElementId) -> ERef;
159 fn lref_get_or_add(&self, location_id: LocationId) -> LRef;
160 fn mref_get_or_add(&self, module_id: ModuleId) -> MRef;
161
162 fn cl(&self) -> Box<dyn TDaemonSession>;
163}
164
165impl TDaemonSession for Arc<RwLock<DaemonSession>> {
166 fn pull_packets(&self) {
167 self.write().unwrap().pull_packets()
168 }
169
170 fn waiting_for(&self, id: u128) -> Option<ClientPackets> {
171 let start_time = SystemTime::now();
172 let mut index = None;
173 'm: loop {
174 if start_time.elapsed().unwrap() > Duration::from_secs(1) {
175 println!("Time Out!");
176 break;
177 }
178 for (i, packet) in self.read().unwrap().packets.iter().enumerate() {
179 if packet.id() == id {
180 index = Some(i);
181 break 'm;
182 }
183 }
184 self.pull_packets();
185 }
186
187 index.map(|index| self.write().unwrap().packets.remove(index))
188 }
189
190 fn send(&self, packet: ServerPackets) {
191 let mut bytes = packet.to_bytes();
192 bytes.reverse();
193 let _ = self.write().unwrap().conn.send(&bytes);
194 }
195
196 fn generate(&self) -> u128 {
197 self.write().unwrap().generator.add_assign(1);
198 self.read().unwrap().generator.sub(1)
199 }
200
201 fn eref_get_or_add(&self, element_id: ElementId) -> ERef {
202 for eref in self.read().unwrap().element_refs.iter() {
203 if eref.id() == element_id {
204 return eref.clone();
205 }
206 }
207
208 let eref = Arc::new(RwLock::new(RefElement {
209 session: Some(Box::new(self.cl())),
210 id: element_id,
211 }));
212
213 self.write().unwrap().element_refs.push(eref.clone());
214 eref
215 }
216
217 fn lref_get_or_add(&self, location_id: LocationId) -> LRef {
218 for lref in self.read().unwrap().locations_refs.iter() {
219 if lref.id() == location_id {
220 return lref.clone();
221 }
222 }
223
224 let lref = Arc::new(RwLock::new(RefLocation {
225 session: Some(Box::new(self.cl())),
226 id: location_id,
227 }));
228
229 self.write().unwrap().locations_refs.push(lref.clone());
230 lref
231 }
232
233 fn mref_get_or_add(&self, module_id: ModuleId) -> MRef {
234 for mref in self.read().unwrap().module_refs.iter() {
235 if mref.id() == module_id {
236 return mref.clone();
237 }
238 }
239
240 let mref = Arc::new(RwLock::new(RefModule {
241 session: Some(Box::new(self.cl())),
242 uid: module_id,
243 }));
244
245 self.write().unwrap().module_refs.push(mref.clone());
246 mref
247 }
248
249 fn cl(&self) -> Box<dyn TDaemonSession> {
250 Box::new(self.clone())
251 }
252}