muzzman_daemon/
lib.rs

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}