Skip to main content

why2_chat/
options.rs

1/*
2This is part of WHY2
3Copyright (C) 2022-2026 Václav Šmejkal
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 3 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*/
18
19use std::sync::
20{
21    OnceLock,
22    atomic::{ AtomicBool, Ordering },
23};
24
25#[cfg(feature = "client")]
26use std::
27{
28    collections::HashSet,
29    sync::
30    {
31        Arc,
32        Mutex,
33        RwLock,
34        LazyLock,
35        atomic::AtomicUsize,
36    },
37};
38
39#[cfg(feature = "client")]
40use crate::consts::SharedKeys;
41
42//SETTINGS
43static SERVER_USERNAME: OnceLock<String> = OnceLock::new();
44
45#[cfg(feature = "server")]
46static VOICE_CHAT: AtomicBool = AtomicBool::new(false);
47
48#[cfg(feature = "client")]
49static KEYS: LazyLock<RwLock<Option<SharedKeys>>> = LazyLock::new(|| //SHARED SYMMETRIC KEY
50{
51    RwLock::new(None)
52});
53
54#[cfg(feature = "client")]
55static ASKING_PASSWORD: AtomicBool = AtomicBool::new(false); //CLIENT IS SENDING PASSWORD (DISABLE ECHO)
56
57#[cfg(feature = "client")]
58static EXTRA_SPACE: AtomicBool = AtomicBool::new(false); //CLIENT DISPLAYED SOME MENU (/help ETC.), ADD EXTRA SPACE ON NEXT MESSAGE
59
60#[cfg(feature = "client")]
61static SENDING_MESSAGES: AtomicBool = AtomicBool::new(false); //SENDING MESSAGES BOOL (CONDITION FOR ADDING MESSAGES TO HISTORY)
62
63#[cfg(feature = "client")]
64pub static INPUT_READ: LazyLock<Arc<Mutex<Vec<char>>>> = LazyLock::new(|| //INPUT READ FROM CLIENT
65{
66    Arc::new(Mutex::new(Vec::new()))
67});
68
69#[cfg(feature = "client")]
70static SEQ: AtomicUsize = AtomicUsize::new(0); //PACKET SEQUENCE NUMBER (CLIENT -> SERVER)
71
72#[cfg(feature = "client")]
73static SERVER_SEQ: AtomicUsize = AtomicUsize::new(0); //PACKET SEQUENCE NUMBER (SERVER -> CLIENT)
74
75#[cfg(feature = "client")]
76static SERVER_ADDRESS: OnceLock<String> = OnceLock::new();
77
78#[cfg(feature = "client")]
79static MUTE: AtomicBool = AtomicBool::new(false); //MUTE LOCAL CLIENT
80#[cfg(feature = "client")]
81static MUTED: LazyLock<Mutex<HashSet<usize>>> = LazyLock::new(|| Mutex::new(HashSet::new())); //MUTED CLIENTS
82
83#[cfg(feature = "client")]
84static SOCKS5: AtomicBool = AtomicBool::new(false); //USE SOCKS5 (TOR)
85
86//FUNCTIONS
87//SERVER USERNAME
88pub fn get_server_username() -> String //GET SERVER USERNAME
89{
90    SERVER_USERNAME.get().unwrap().to_owned()
91}
92
93pub fn set_server_username(username: &str) //SET SERVER USERNAME
94{
95    SERVER_USERNAME.set(username.to_owned()).unwrap();
96}
97
98//VOICE CHAT
99#[cfg(feature = "server")]
100pub fn enable_voice_chat() //SET VOICE CHAT TO TRUE
101{
102    VOICE_CHAT.store(true, Ordering::Relaxed);
103}
104
105#[cfg(feature = "server")]
106pub fn voice_chat_enabled() -> bool //GET VOICE CHAT
107{
108    VOICE_CHAT.load(Ordering::Relaxed)
109}
110
111//SHARED KEYS
112#[cfg(feature = "client")]
113pub fn set_keys(keys: SharedKeys) //SET KEY
114{
115    let mut shared_key = KEYS.write().unwrap();
116    *shared_key = Some(keys);
117}
118
119#[cfg(feature = "client")]
120pub fn get_keys() -> Option<SharedKeys> //RETURN KEY
121{
122    let shared_key = KEYS.read().unwrap();
123    shared_key.clone()
124}
125
126//ASKING PASSWORD
127#[cfg(feature = "client")]
128pub fn set_asking_password(value: bool) //SET ASKING_PASSWORD
129{
130    ASKING_PASSWORD.store(value, Ordering::Relaxed);
131}
132
133#[cfg(feature = "client")]
134pub fn get_asking_password() -> bool //GET ASKING_PASSWORD
135{
136    ASKING_PASSWORD.load(Ordering::Relaxed)
137}
138
139//ADD EXTRA SPACE
140#[cfg(feature = "client")]
141pub fn set_extra_space(value: bool) //SET EXTRA_SPACE
142{
143    EXTRA_SPACE.store(value, Ordering::Relaxed);
144}
145
146#[cfg(feature = "client")]
147pub fn get_extra_space() -> bool //GET EXTRA_SPACE
148{
149    EXTRA_SPACE.load(Ordering::Relaxed)
150}
151
152//SENDING MESSAGES
153#[cfg(feature = "client")]
154pub fn get_sending_messages() -> bool //GET SENDING_MESSAGES
155{
156    SENDING_MESSAGES.load(Ordering::Relaxed)
157}
158
159#[cfg(feature = "client")]
160pub fn set_sending_messages(value: bool) //SET SENDING_MESSAGES
161{
162    SENDING_MESSAGES.store(value, Ordering::Relaxed);
163}
164
165#[cfg(feature = "client")]
166pub fn get_seq() -> usize //GET SEQUENCE NUMBER
167{
168    SEQ.load(Ordering::Relaxed)
169}
170
171#[cfg(feature = "client")]
172pub fn set_seq(value: usize) //SET SEQUENCE NUMBER
173{
174    SEQ.store(value, Ordering::Relaxed)
175}
176
177#[cfg(feature = "client")]
178pub fn get_server_seq() -> usize //GET SERVER SEQUENCE NUMBER
179{
180    SERVER_SEQ.load(Ordering::Relaxed)
181}
182
183#[cfg(feature = "client")]
184pub fn set_server_seq(value: usize) //SET SERVER SEQUENCE NUMBER
185{
186    SERVER_SEQ.store(value, Ordering::Relaxed)
187}
188
189//SERVER ADDRESS
190#[cfg(feature = "client")]
191pub fn get_server_address() -> String //GET SERVER ADDRESS
192{
193    SERVER_ADDRESS.get().unwrap().to_owned()
194}
195
196#[cfg(feature = "client")]
197pub fn set_server_address(address: &str) //SET SERVER ADDRESS
198{
199    SERVER_ADDRESS.set(address.to_owned()).unwrap();
200}
201
202//MUTING
203#[cfg(feature = "client")]
204pub fn toggle_mute(id: Option<usize>) -> bool //ENABLE/DISABLE MUTE
205{
206    if let Some(id) = id //MUTE CLIENT
207    {
208        let mut muted = MUTED.lock().unwrap();
209
210        if muted.remove(&id)
211        {
212            false
213        } else
214        {
215            muted.insert(id);
216            true
217        }
218
219    } else //MUTE LOCAL CLIENT
220    {
221        !MUTE.fetch_xor(true, Ordering::Relaxed)
222    }
223}
224
225#[cfg(feature = "client")]
226pub fn is_muted(id: Option<usize>) -> bool //CHECK IF CLIENT IS MUTED
227{
228    if let Some(id) = id
229    {
230        MUTED.lock().unwrap().contains(&id)
231    } else
232    {
233        MUTE.load(Ordering::Relaxed)
234    }
235}
236
237//SOCKS5
238#[cfg(feature = "client")]
239pub fn enable_socks5() //SET SOCKS5 TO TRUE
240{
241    SOCKS5.store(true, Ordering::Relaxed);
242}
243
244#[cfg(feature = "client")]
245pub fn socks5_enabled() -> bool //GET SOCKS5
246{
247    SOCKS5.load(Ordering::Relaxed)
248}