crystal_server/
types.rs

1use chrono::{DateTime, Utc};
2use integer_hasher::IntMap;
3use num_enum::TryFromPrimitive;
4
5use super::{
6    buffer::{Buffer, Serialize},
7    leb::Leb,
8};
9use std::{
10    collections::{HashMap, HashSet},
11    io::{Error, ErrorKind, Result},
12};
13
14// TODO: Do a macro or something that builds this more easily
15/// A structure that represents a dynamic value.
16#[derive(Default, Debug, Clone, PartialEq)]
17pub enum Value {
18    #[default]
19    Null,
20    Bool(bool),
21    Int(i64),
22    Float(f64),
23    String(String),
24    Array(Vec<Value>),
25    Struct(HashMap<String, Value>),
26    Buffer(Vec<u8>),
27}
28
29#[derive(Debug, Clone)]
30pub struct Achievement {
31    pub name: String,
32    pub description: String,
33    pub unlocked: Option<i64>,
34}
35
36#[derive(Debug, Clone)]
37pub struct Highscore {
38    pub name: String,
39    pub scores: IntMap<Leb<u64>, f64>,
40}
41
42#[derive(Default, Debug, Copy, Clone, PartialEq)]
43pub struct Administrator {
44    pub can_kick: bool,
45    pub can_ban: bool,
46    pub can_unban: bool,
47}
48
49#[derive(Debug, Default, Clone, PartialEq, Eq)]
50pub struct Ban {
51    pub unban_time: i64,
52    pub reason: String,
53}
54
55/// Contains the data of a connected Player
56#[derive(Debug, Clone)]
57pub struct Player {
58    pub name: String,
59    pub room: String,
60    pub syncs: Vec<Option<Sync>>,
61    pub variables: HashMap<String, Value>,
62}
63
64#[derive(Default, Debug, Clone)]
65pub(crate) struct PlayerQueue {
66    pub variables: HashMap<String, OptionalValue>,
67    pub syncs: IntMap<usize, HashMap<String, OptionalValue>>,
68    pub remove_syncs: Vec<usize>,
69    pub new_syncs: Vec<NewSync>,
70}
71
72#[derive(Debug, Clone)]
73pub(crate) struct NewSync {
74    pub slot: usize,
75    pub sync_type: SyncType,
76    pub kind: i16,
77    pub variables: HashMap<String, Value>,
78}
79
80#[derive(Debug, Clone)]
81pub(crate) struct NewSyncQueue {
82    pub slot: usize,
83    pub kind: i16,
84    pub sync_type: SyncType,
85}
86
87#[derive(Debug)]
88pub(crate) struct CallbackServerUpdate {
89    pub name: String,
90    pub callback: ServerUpdateCallback,
91}
92
93pub type PlayerVariableServerUpdate =
94    Box<dyn FnMut(u64, String, OptionalValue) + core::marker::Sync + Send>;
95
96pub type SyncVariableServerUpdate =
97    Box<dyn FnMut(u64, String, OptionalValue) + core::marker::Sync + Send>;
98
99pub type FetchBdbServerUpdate = Box<dyn FnMut(String, Option<Vec<u8>>) + core::marker::Sync + Send>;
100
101pub(crate) enum ServerUpdateCallback {
102    /// Callback, Player ID
103    PlayerVariable(Option<PlayerVariableServerUpdate>, u64),
104    /// Callback, Player ID, Sync Slot
105    SyncVariable(Option<SyncVariableServerUpdate>, u64, usize),
106    /// Callback, BDB Name
107    FetchBdb(Option<FetchBdbServerUpdate>),
108}
109
110#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, TryFromPrimitive)]
111#[repr(u8)]
112pub enum SyncEvent {
113    #[default]
114    New = 0,
115    Step = 1,
116    End = 2,
117    Once = 3,
118}
119
120/// The target syncronization type
121#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, TryFromPrimitive)]
122#[repr(u8)]
123pub enum SyncType {
124    Once = 0,
125    #[default]
126    Normal = 1,
127}
128
129/// Data updates that have been triggered from the server.
130#[derive(Debug, Clone, PartialEq)]
131pub enum DataUpdate {
132    /// Return Code
133    Registration(RegistrationCode),
134    /// Return Code
135    Login(LoginCode),
136    /// Player ID, Player Name
137    LoginOk(u64, String),
138    /// Return Code, Reason, Unix unban time
139    LoginBan(LoginCode, String, i64),
140    /// Player ID, Player Name, Room
141    PlayerLoggedIn(u64, String, String),
142    /// Player ID
143    PlayerLoggedOut(u64),
144    /// Player ID or Server, Message ID, Payload
145    P2P(Option<u64>, i16, Vec<Value>),
146    /// Player ID, Variable Name, Variable Value
147    UpdateVariable(u64, String, OptionalValue),
148    /// Player ID, Sync ID, Variable Name, Variable Value
149    UpdateSyncVariable(u64, usize, String, OptionalValue),
150    /// Player ID, Sync ID
151    UpdateSyncRemoval(u64, usize),
152    /// (Optional) File, Section, Key, Value
153    UpdateGameIni(Option<String>, String, String, OptionalValue),
154    /// (Optional) File, Section, Key, Value
155    UpdatePlayerIni(Option<String>, String, String, OptionalValue),
156    /// Version
157    UpdateGameVersion(f64),
158    /// Admin Action
159    AdminAction(AdminAction),
160    /// Player ID, Administrator Permissions
161    UpdateAdministrator(u64, Option<Administrator>),
162    /// Name, Value
163    FetchBdb(String, Option<Vec<u8>>),
164    /// Player ID
165    ChangeFriendStatus(u64),
166    /// Message
167    ServerMessage(String),
168    Reconnecting(),
169    Disconnected(),
170    /// Reason
171    Kicked(String),
172    /// Reason, Unban Unix Time
173    Banned(String, DateTime<Utc>),
174    /// Notification Message
175    ServerNotification(String),
176    /// Login Token
177    LoginToken(String),
178}
179
180/// The return success value of a registration attempt
181#[derive(Default, Copy, Clone, Debug, TryFromPrimitive, PartialEq, Eq, PartialOrd, Ord)]
182#[repr(u8)]
183pub enum RegistrationCode {
184    Ok = 0,
185    AccountExists = 1,
186    UsedEmail = 2,
187    InvalidEmail = 3,
188    ShortPassword = 4,
189    InvalidName = 5,
190    ShortName = 6,
191    DifferentPasswords = 7,
192    #[default]
193    Error = 8,
194    LongName = 9,
195    GlobalBan = 10,
196    LongPassword = 11,
197    MaxAccounts = 12,
198}
199
200/// The return success value of a login attempt
201#[derive(Default, Copy, Clone, Debug, TryFromPrimitive, PartialEq, Eq, PartialOrd, Ord)]
202#[repr(u8)]
203pub enum LoginCode {
204    Ok = 0,
205    NoUser = 1,
206    WrongPassword = 2,
207    Unauthenticated = 3,
208    Unverified = 4,
209    AlreadyIn = 5,
210    GameBan = 6,
211    GlobalBan = 7,
212    #[default]
213    Error = 8,
214    MaxPlayers = 9,
215}
216
217/// The target it should request something from/to
218#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
219pub enum PlayerRequestCode {
220    AllGame,
221    PlayerId(u64),
222}
223
224#[derive(Debug, Clone)]
225pub(crate) enum LoginPassw {
226    Passw(String),
227    Token(String),
228}
229
230/// The target it should request something from/to
231#[derive(Debug, Clone, Copy)]
232pub enum PlayerRequest {
233    ID(u64),
234    AllGame,
235    CurrentSession,
236    CurrentRoom,
237    Server,
238}
239
240#[derive(Debug, Clone, PartialEq)]
241pub enum AdminAction {
242    Unban,
243    /// Reason, Unix unban time
244    Ban(String, i64),
245    /// Reason
246    Kick(String),
247}
248
249#[derive(Debug, Clone)]
250pub(crate) struct VariableUpdate {
251    pub name: String,
252    pub value: OptionalValue,
253}
254
255#[derive(Debug, Clone)]
256pub(crate) struct SyncUpdate {
257    pub slot: usize,
258    pub remove_sync: bool,
259    pub variables: Option<HashMap<String, OptionalValue>>,
260}
261
262#[derive(Debug, Clone, PartialEq)]
263pub enum OptionalValue {
264    Some(Value),
265    None,
266}
267
268/// An object that's being synced between players
269#[derive(Debug, Clone, Default)]
270pub struct Sync {
271    pub kind: i16,
272    pub sync_type: SyncType,
273    pub variables: HashMap<String, Value>,
274    pub event: SyncEvent,
275    pub is_ending: bool,
276}
277
278#[derive(Debug, Clone, Default)]
279pub(crate) struct SelfSync {
280    pub kind: i16,
281    pub sync_type: SyncType,
282    pub variables: HashMap<String, Value>,
283    pub to_sync: HashSet<String>,
284}
285
286/// A return value from an iterator containing data about a Sync from another player
287#[derive(Debug, Clone, Default)]
288pub struct SyncIter {
289    pub player_id: u64,
290    pub player_name: String,
291    pub slot: usize,
292    pub event: SyncEvent,
293    pub kind: i16,
294    pub variables: HashMap<String, Value>,
295}
296
297#[derive(Default, Debug, Copy, Clone, TryFromPrimitive)]
298#[repr(u8)]
299pub(crate) enum ChangeFriendStatus {
300    // Outgoing
301    Request = 0,
302    Cancel = 1,
303    // Incoming
304    Accept = 2,
305    Deny = 3,
306    //
307    Remove = 4,
308    // Misc
309    Friend = 5,
310    #[default]
311    NotFriend = 6,
312}
313
314impl std::fmt::Debug for ServerUpdateCallback {
315    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
316        write!(
317            f,
318            "{}",
319            match self {
320                Self::FetchBdb(_) => "FetchBdb(...)",
321                Self::PlayerVariable(_, _) => "PlayerVariable(...)",
322                Self::SyncVariable(_, _, _) => "SyncVariable(...)",
323            }
324        )
325    }
326}
327
328impl Serialize for Sync {
329    #[inline(always)]
330    fn write(&self, buffer: &mut Buffer) -> Result<()> {
331        buffer.write_i16(self.kind)?;
332        buffer.write_u8(self.sync_type as u8)?;
333        buffer.write(&self.variables)?;
334
335        Ok(())
336    }
337
338    #[inline(always)]
339    fn read(buffer: &mut Buffer) -> Result<Self> {
340        Ok({
341            let mut s = Self {
342                kind: buffer.read_i16()?,
343                sync_type: SyncType::try_from_primitive(buffer.read_u8()?).unwrap_or_default(),
344                variables: buffer.read()?,
345                event: SyncEvent::New,
346                is_ending: false,
347            };
348            if s.sync_type == SyncType::Once {
349                s.event = SyncEvent::Once;
350            }
351            s
352        })
353    }
354}
355
356impl Serialize for SelfSync {
357    #[inline(always)]
358    fn write(&self, buffer: &mut Buffer) -> Result<()> {
359        buffer.write_i16(self.kind)?;
360        buffer.write_u8(self.sync_type as u8)?;
361        buffer.write(&self.variables)?;
362
363        Ok(())
364    }
365
366    #[inline(always)]
367    fn read(buffer: &mut Buffer) -> Result<Self> {
368        Ok(Self {
369            kind: buffer.read_i16()?,
370            sync_type: SyncType::try_from_primitive(buffer.read_u8()?).unwrap_or_default(),
371            variables: buffer.read()?,
372            to_sync: HashSet::new(),
373        })
374    }
375}
376
377impl Serialize for SyncUpdate {
378    #[inline(always)]
379    fn write(&self, buffer: &mut Buffer) -> Result<()> {
380        buffer.write_leb_u64(self.slot as u64)?;
381        buffer.write_bool(self.remove_sync)?;
382        if let Some(data) = &self.variables {
383            assert!(
384                !self.remove_sync,
385                "unable to sync variables when remove sync is enabled"
386            );
387            buffer.write(data)?;
388        }
389
390        Ok(())
391    }
392
393    #[inline(always)]
394    fn read(buffer: &mut Buffer) -> Result<Self> {
395        let slot = buffer.read_leb_u64()? as usize;
396        let remove_sync = buffer.read_bool()?;
397        let variables = if remove_sync {
398            None
399        } else {
400            Some(buffer.read()?)
401        };
402        Ok(Self {
403            slot,
404            remove_sync,
405            variables,
406        })
407    }
408}
409
410impl Serialize for OptionalValue {
411    #[inline(always)]
412    fn write(&self, buffer: &mut Buffer) -> Result<()> {
413        match self {
414            OptionalValue::Some(vari) => {
415                buffer.write(vari)?;
416            }
417            OptionalValue::None => {
418                buffer.write_u8(0xff)?;
419            }
420        }
421
422        Ok(())
423    }
424
425    #[inline(always)]
426    fn read(buffer: &mut Buffer) -> Result<Self> {
427        let has_data = buffer.read_u8()? != 0xff;
428        buffer.seek_relative(-1)?;
429        let vari = buffer.read::<Value>()?;
430        Ok(if has_data {
431            OptionalValue::Some(vari)
432        } else {
433            OptionalValue::None
434        })
435    }
436}
437
438impl Serialize for VariableUpdate {
439    #[inline(always)]
440    fn write(&self, buffer: &mut Buffer) -> Result<()> {
441        buffer.write_string(&self.name)?;
442        buffer.write(&self.value)?;
443
444        Ok(())
445    }
446
447    #[inline(always)]
448    fn read(buffer: &mut Buffer) -> Result<Self> {
449        Ok(Self {
450            name: buffer.read_string()?,
451            value: buffer.read()?,
452        })
453    }
454}
455
456impl From<Option<Value>> for OptionalValue {
457    #[inline(always)]
458    fn from(value: Option<Value>) -> Self {
459        match value {
460            Some(value) => OptionalValue::Some(value),
461            None => OptionalValue::None,
462        }
463    }
464}
465
466impl Serialize for PlayerRequest {
467    fn write(&self, buffer: &mut Buffer) -> Result<()> {
468        match self {
469            PlayerRequest::ID(pid) => {
470                buffer.write_u8(0)?;
471                buffer.write_leb_u64(*pid)?;
472            }
473            PlayerRequest::AllGame => {
474                buffer.write_u8(1)?;
475            }
476            PlayerRequest::CurrentSession => {
477                buffer.write_u8(2)?;
478            }
479            PlayerRequest::CurrentRoom => {
480                buffer.write_u8(3)?;
481            }
482            PlayerRequest::Server => {
483                buffer.write_u8(4)?;
484            }
485        }
486
487        Ok(())
488    }
489
490    fn read(buffer: &mut Buffer) -> Result<Self> {
491        match buffer.read_u8()? {
492            0 => Ok(PlayerRequest::ID(buffer.read_leb_u64()?)),
493            1 => Ok(PlayerRequest::AllGame),
494            2 => Ok(PlayerRequest::CurrentSession),
495            3 => Ok(PlayerRequest::CurrentRoom),
496            4 => Ok(PlayerRequest::Server),
497            _ => Err(Error::new(
498                ErrorKind::InvalidData,
499                "Invalid PlayerRequest handle",
500            )),
501        }
502    }
503}
504
505impl Serialize for Value {
506    #[inline(always)]
507    fn write(&self, buffer: &mut Buffer) -> Result<()> {
508        match self {
509            Self::Null => {
510                buffer.write_u8(0)?;
511            }
512            Self::Bool(value) => {
513                buffer.write_u8(1)?;
514                buffer.write_bool(*value)?;
515            }
516            Self::Int(value) => {
517                buffer.write_u8(2)?;
518                buffer.write_i64(*value)?;
519            }
520            Self::Float(value) => {
521                buffer.write_u8(3)?;
522                buffer.write_f64(*value)?;
523            }
524            Self::String(value) => {
525                buffer.write_u8(4)?;
526                buffer.write_string(value)?;
527            }
528            Self::Array(value) => {
529                buffer.write_u8(5)?;
530                buffer.write(value)?;
531            }
532            Self::Struct(value) => {
533                buffer.write_u8(6)?;
534                buffer.write(value)?;
535            }
536            Self::Buffer(value) => {
537                buffer.write_u8(7)?;
538                buffer.write_bytes(value)?;
539            }
540        }
541
542        Ok(())
543    }
544
545    #[inline(always)]
546    fn read(buffer: &mut Buffer) -> Result<Self> {
547        Ok(match buffer.read_u8()? {
548            1 => Self::Bool(buffer.read_bool()?),
549            2 => Self::Int(buffer.read_i64()?),
550            3 => Self::Float(buffer.read_f64()?),
551            4 => Self::String(buffer.read_string()?),
552            5 => Self::Array(buffer.read()?),
553            6 => Self::Struct(buffer.read()?),
554            7 => Self::Buffer(buffer.read_bytes()?),
555
556            // Both 0 and any other unidentified values
557            // will be recognized as Null
558            _ => Self::Null,
559        })
560    }
561}
562
563impl Serialize for Achievement {
564    #[inline(always)]
565    fn write(&self, buffer: &mut Buffer) -> Result<()> {
566        buffer.write_string(&self.name)?;
567        buffer.write_string(&self.description)?;
568        buffer.write(&self.unlocked)?;
569
570        Ok(())
571    }
572
573    #[inline(always)]
574    fn read(buffer: &mut Buffer) -> Result<Self> {
575        Ok(Self {
576            name: buffer.read_string()?,
577            description: buffer.read_string()?,
578            unlocked: buffer.read()?,
579        })
580    }
581}
582
583impl Serialize for Highscore {
584    #[inline(always)]
585    fn write(&self, buffer: &mut Buffer) -> Result<()> {
586        buffer.write_string(&self.name)?;
587        buffer.write(&self.scores)?;
588
589        Ok(())
590    }
591
592    #[inline(always)]
593    fn read(buffer: &mut Buffer) -> Result<Self> {
594        Ok(Self {
595            name: buffer.read_string()?,
596            scores: buffer.read()?,
597        })
598    }
599}
600
601impl Serialize for Administrator {
602    #[inline(always)]
603    fn write(&self, buffer: &mut Buffer) -> Result<()> {
604        buffer.write_bool(self.can_kick)?;
605        buffer.write_bool(self.can_ban)?;
606        buffer.write_bool(self.can_unban)?;
607
608        Ok(())
609    }
610
611    #[inline(always)]
612    fn read(buffer: &mut Buffer) -> Result<Self> {
613        Ok(Self {
614            can_kick: buffer.read_bool()?,
615            can_ban: buffer.read_bool()?,
616            can_unban: buffer.read_bool()?,
617        })
618    }
619}
620
621impl Serialize for Ban {
622    #[inline(always)]
623    fn write(&self, buffer: &mut Buffer) -> Result<()> {
624        buffer.write_i64(self.unban_time)?;
625        buffer.write_string(&self.reason)?;
626
627        Ok(())
628    }
629
630    #[inline(always)]
631    fn read(buffer: &mut Buffer) -> Result<Self> {
632        Ok(Self {
633            unban_time: buffer.read_i64()?,
634            reason: buffer.read_string()?,
635        })
636    }
637}
638
639impl From<Vec<Value>> for Value {
640    fn from(value: Vec<Value>) -> Self {
641        Self::Array(value)
642    }
643}
644
645impl From<HashMap<String, Value>> for Value {
646    fn from(value: HashMap<String, Value>) -> Self {
647        Self::Struct(value)
648    }
649}
650
651impl From<Option<Value>> for Value {
652    fn from(value: Option<Value>) -> Self {
653        if let Some(value) = value {
654            value
655        } else {
656            Self::Null
657        }
658    }
659}
660
661impl From<f64> for Value {
662    fn from(value: f64) -> Self {
663        Self::Float(value)
664    }
665}
666
667impl From<f32> for Value {
668    fn from(value: f32) -> Self {
669        Self::Float(value as f64)
670    }
671}
672
673impl From<i64> for Value {
674    fn from(value: i64) -> Self {
675        Self::Int(value)
676    }
677}
678
679impl From<i32> for Value {
680    fn from(value: i32) -> Self {
681        Self::Int(value as i64)
682    }
683}
684
685impl From<u32> for Value {
686    fn from(value: u32) -> Self {
687        Self::Int(value as i64)
688    }
689}
690
691impl From<i16> for Value {
692    fn from(value: i16) -> Self {
693        Self::Int(value as i64)
694    }
695}
696
697impl From<u16> for Value {
698    fn from(value: u16) -> Self {
699        Self::Int(value as i64)
700    }
701}
702
703impl From<i8> for Value {
704    fn from(value: i8) -> Self {
705        Self::Int(value as i64)
706    }
707}
708
709impl From<u8> for Value {
710    fn from(value: u8) -> Self {
711        Self::Int(value as i64)
712    }
713}
714
715impl From<bool> for Value {
716    fn from(value: bool) -> Self {
717        Self::Bool(value)
718    }
719}
720
721impl From<String> for Value {
722    fn from(value: String) -> Self {
723        Self::String(value)
724    }
725}
726
727impl From<&Vec<Value>> for Value {
728    fn from(value: &Vec<Value>) -> Self {
729        Self::Array(value.clone())
730    }
731}
732
733impl From<&HashMap<String, Value>> for Value {
734    fn from(value: &HashMap<String, Value>) -> Self {
735        Self::Struct(value.clone())
736    }
737}
738
739impl From<&Option<Value>> for Value {
740    fn from(value: &Option<Value>) -> Self {
741        if let Some(value) = value {
742            value.clone()
743        } else {
744            Self::Null
745        }
746    }
747}
748
749impl From<&f64> for Value {
750    fn from(value: &f64) -> Self {
751        Self::Float(*value)
752    }
753}
754
755impl From<&f32> for Value {
756    fn from(value: &f32) -> Self {
757        Self::Float(*value as f64)
758    }
759}
760
761impl From<&i64> for Value {
762    fn from(value: &i64) -> Self {
763        Self::Int(*value)
764    }
765}
766
767impl From<&i32> for Value {
768    fn from(value: &i32) -> Self {
769        Self::Int(*value as i64)
770    }
771}
772
773impl From<&u32> for Value {
774    fn from(value: &u32) -> Self {
775        Self::Int(*value as i64)
776    }
777}
778
779impl From<&i16> for Value {
780    fn from(value: &i16) -> Self {
781        Self::Int(*value as i64)
782    }
783}
784
785impl From<&u16> for Value {
786    fn from(value: &u16) -> Self {
787        Self::Int(*value as i64)
788    }
789}
790
791impl From<&i8> for Value {
792    fn from(value: &i8) -> Self {
793        Self::Int(*value as i64)
794    }
795}
796
797impl From<&u8> for Value {
798    fn from(value: &u8) -> Self {
799        Self::Int(*value as i64)
800    }
801}
802
803impl From<&bool> for Value {
804    fn from(value: &bool) -> Self {
805        Self::Bool(*value)
806    }
807}
808
809impl From<&String> for Value {
810    fn from(value: &String) -> Self {
811        Self::String(value.clone())
812    }
813}
814
815impl From<&Value> for Value {
816    fn from(value: &Value) -> Self {
817        value.clone()
818    }
819}
820
821impl From<&str> for Value {
822    fn from(value: &str) -> Self {
823        Self::String(value.to_string())
824    }
825}
826
827impl From<&[Value]> for Value {
828    fn from(value: &[Value]) -> Self {
829        Self::Array(value.to_vec())
830    }
831}
832
833impl<const N: usize> From<&&[u8; N]> for Value {
834    fn from(value: &&[u8; N]) -> Self {
835        Self::Buffer(value.to_vec())
836    }
837}
838
839impl From<&[u8]> for Value {
840    fn from(value: &[u8]) -> Self {
841        Self::Buffer(value.to_vec())
842    }
843}
844
845impl From<&Vec<u8>> for Value {
846    fn from(value: &Vec<u8>) -> Self {
847        Self::Buffer(value.clone())
848    }
849}
850
851impl From<Vec<u8>> for Value {
852    fn from(value: Vec<u8>) -> Self {
853        Self::Buffer(value)
854    }
855}