rust/hedgewars-server/src/handlers.rs
author Wuzzy <Wuzzy2@mail.ru>
Thu, 11 Jul 2019 16:24:09 +0200
changeset 15231 c10e9261ab9c
parent 15216 387345a14b3f
child 15439 a158ff8f84ef
permissions -rw-r--r--
Make lowest line of Splash image frames transparent to work around scaling issues The Splash image is scaled. Sometimes, the lowest line is repeated on the top, which caused some weird lines to appear above big splashes (e.g. piano). This has been done fully automated with a script. Only the alpha channel was changed. The color information is preserved.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12149
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
     1
use mio;
15163
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     2
use std::{
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     3
    cmp::PartialEq,
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     4
    collections::HashMap,
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     5
    fmt::{Formatter, LowerHex},
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     6
    iter::Iterator,
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
     7
};
12149
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
     8
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
     9
use self::{
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    10
    actions::{Destination, DestinationGroup, PendingMessage},
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    11
    inanteroom::LoginResult,
14694
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14693
diff changeset
    12
};
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
    13
use crate::{
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    14
    core::{
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    15
        room::RoomSave,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    16
        server::HwServer,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    17
        types::{ClientId, GameCfg, Replay, RoomId, TeamInfo},
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    18
    },
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    19
    protocol::messages::{
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    20
        global_chat, server_chat, HwProtocolMessage, HwProtocolMessage::EngineMessage,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    21
        HwServerMessage, HwServerMessage::*,
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    22
    },
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
    23
    utils,
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
    24
};
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
    25
use base64::encode;
13805
0463a4221327 cleanup crate imports
alfadur
parents: 13798
diff changeset
    26
use log::*;
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
    27
use rand::{thread_rng, RngCore};
13666
09f4a30e50cc Rust 2018 conversion
alfadur
parents: 13521
diff changeset
    28
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    29
mod actions;
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    30
mod checker;
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    31
mod common;
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    32
mod inanteroom;
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
    33
mod inlobby;
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    34
mod inroom;
12149
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
    35
15102
80ff12edf5e6 handle response from IO result handler
alfadur
parents: 15075
diff changeset
    36
#[derive(PartialEq, Debug)]
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    37
pub struct Sha1Digest([u8; 20]);
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    38
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    39
impl Sha1Digest {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    40
    pub fn new(digest: [u8; 20]) -> Self {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    41
        Self(digest)
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    42
    }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    43
}
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    44
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    45
impl LowerHex for Sha1Digest {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    46
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    47
        for byte in &self.0 {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    48
            write!(f, "{:02x}", byte)?;
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    49
        }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    50
        Ok(())
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    51
    }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    52
}
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    53
15163
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    54
impl PartialEq<&str> for Sha1Digest {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    55
    fn eq(&self, other: &&str) -> bool {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    56
        if other.len() != self.0.len() * 2 {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    57
            false
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    58
        } else {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    59
            #[inline]
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    60
            fn convert(c: u8) -> u8 {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    61
                if c > b'9' {
15216
387345a14b3f replace overflowing_sub with wrapping_sub
alfadur
parents: 15176
diff changeset
    62
                    c.wrapping_sub(b'a').saturating_add(10)
15163
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    63
                } else {
15216
387345a14b3f replace overflowing_sub with wrapping_sub
alfadur
parents: 15176
diff changeset
    64
                    c.wrapping_sub(b'0')
15163
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    65
                }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    66
            }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    67
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    68
            other
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    69
                .as_bytes()
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    70
                .chunks_exact(2)
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    71
                .zip(&self.0)
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    72
                .all(|(chars, byte)| {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    73
                    if let [hi, lo] = chars {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    74
                        convert(*lo) == byte & 0x0f && convert(*hi) == (byte & 0xf0) >> 4
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    75
                    } else {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    76
                        unreachable!()
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    77
                    }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    78
                })
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    79
        }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    80
    }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    81
}
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
    82
15102
80ff12edf5e6 handle response from IO result handler
alfadur
parents: 15075
diff changeset
    83
#[derive(Debug)]
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    84
pub struct AccountInfo {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    85
    pub is_registered: bool,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    86
    pub is_admin: bool,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    87
    pub is_contributor: bool,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    88
    pub server_hash: Sha1Digest,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    89
}
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    90
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    91
pub enum IoTask {
15103
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
    92
    CheckRegistered {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
    93
        nick: String,
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
    94
    },
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    95
    GetAccount {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    96
        nick: String,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    97
        protocol: u16,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    98
        password_hash: String,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
    99
        client_salt: String,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   100
        server_salt: String,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   101
    },
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   102
    GetReplay {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   103
        id: u32,
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   104
    },
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   105
    SaveRoom {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   106
        room_id: RoomId,
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   107
        filename: String,
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   108
        contents: String,
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   109
    },
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   110
    LoadRoom {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   111
        room_id: RoomId,
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   112
        filename: String,
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   113
    },
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   114
}
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   115
15102
80ff12edf5e6 handle response from IO result handler
alfadur
parents: 15075
diff changeset
   116
#[derive(Debug)]
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   117
pub enum IoResult {
15103
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   118
    AccountRegistered(bool),
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   119
    Account(Option<AccountInfo>),
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   120
    Replay(Option<Replay>),
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   121
    SaveRoom(RoomId, bool),
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   122
    LoadRoom(RoomId, Option<String>),
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   123
}
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   124
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   125
pub struct Response {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   126
    client_id: ClientId,
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   127
    messages: Vec<PendingMessage>,
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   128
    io_tasks: Vec<IoTask>,
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   129
    removed_clients: Vec<ClientId>,
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   130
}
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   131
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   132
impl Response {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   133
    pub fn new(client_id: ClientId) -> Self {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   134
        Self {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   135
            client_id,
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   136
            messages: vec![],
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   137
            io_tasks: vec![],
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   138
            removed_clients: vec![],
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   139
        }
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   140
    }
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   141
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   142
    #[inline]
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   143
    pub fn is_empty(&self) -> bool {
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   144
        self.messages.is_empty() && self.removed_clients.is_empty() && self.io_tasks.is_empty()
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   145
    }
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   146
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   147
    #[inline]
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   148
    pub fn len(&self) -> usize {
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   149
        self.messages.len()
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   150
    }
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   151
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   152
    #[inline]
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   153
    pub fn client_id(&self) -> ClientId {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   154
        self.client_id
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   155
    }
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   156
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   157
    #[inline]
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   158
    pub fn add(&mut self, message: PendingMessage) {
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   159
        self.messages.push(message)
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   160
    }
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   161
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   162
    #[inline]
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   163
    pub fn request_io(&mut self, task: IoTask) {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   164
        self.io_tasks.push(task)
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   165
    }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   166
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   167
    pub fn extract_messages<'a, 'b: 'a>(
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   168
        &'b mut self,
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   169
        server: &'a HwServer,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   170
    ) -> impl Iterator<Item = (Vec<ClientId>, HwServerMessage)> + 'a {
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   171
        let client_id = self.client_id;
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   172
        self.messages.drain(..).map(move |m| {
14788
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   173
            let ids = get_recipients(server, client_id, m.destination);
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   174
            (ids, m.message)
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   175
        })
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   176
    }
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   177
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   178
    pub fn remove_client(&mut self, client_id: ClientId) {
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   179
        self.removed_clients.push(client_id);
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   180
    }
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   181
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   182
    pub fn extract_removed_clients(&mut self) -> impl Iterator<Item = ClientId> + '_ {
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   183
        self.removed_clients.drain(..)
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   184
    }
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   185
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   186
    pub fn extract_io_tasks(&mut self) -> impl Iterator<Item = IoTask> + '_ {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   187
        self.io_tasks.drain(..)
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   188
    }
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   189
}
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   190
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   191
impl Extend<PendingMessage> for Response {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   192
    fn extend<T: IntoIterator<Item = PendingMessage>>(&mut self, iter: T) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   193
        for msg in iter {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   194
            self.add(msg)
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   195
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   196
    }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   197
}
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14673
diff changeset
   198
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   199
fn get_recipients(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   200
    server: &HwServer,
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   201
    client_id: ClientId,
14788
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   202
    destination: Destination,
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   203
) -> Vec<ClientId> {
14788
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   204
    match destination {
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   205
        Destination::ToSelf => vec![client_id],
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   206
        Destination::ToId(id) => vec![id],
14788
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   207
        Destination::ToIds(ids) => ids,
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   208
        Destination::ToAll { group, skip_self } => {
14789
18240b308505 implement stats message
alfadur
parents: 14788
diff changeset
   209
            let mut ids: Vec<_> = match group {
18240b308505 implement stats message
alfadur
parents: 14788
diff changeset
   210
                DestinationGroup::All => server.all_clients().collect(),
18240b308505 implement stats message
alfadur
parents: 14788
diff changeset
   211
                DestinationGroup::Lobby => server.lobby_clients().collect(),
18240b308505 implement stats message
alfadur
parents: 14788
diff changeset
   212
                DestinationGroup::Protocol(proto) => server.protocol_clients(proto).collect(),
18240b308505 implement stats message
alfadur
parents: 14788
diff changeset
   213
                DestinationGroup::Room(id) => server.room_clients(id).collect(),
14788
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   214
            };
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   215
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   216
            if skip_self {
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   217
                if let Some(index) = ids.iter().position(|id| *id == client_id) {
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   218
                    ids.remove(index);
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   219
                }
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   220
            }
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   221
6dea1ca64992 implement maxteams and teamchat messages
alfadur
parents: 14786
diff changeset
   222
            ids
14672
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   223
        }
6e6632068a33 Server action refactoring part 3 of N
alfadur <mail@none>
parents: 14671
diff changeset
   224
    }
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   225
}
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   226
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   227
pub fn handle(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   228
    server: &mut HwServer,
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   229
    client_id: ClientId,
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   230
    response: &mut Response,
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   231
    message: HwProtocolMessage,
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   232
) {
12149
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
   233
    match message {
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   234
        HwProtocolMessage::Ping => response.add(Pong.send_self()),
15113
7d6e519a88c5 consume pongs
alfadur
parents: 15103
diff changeset
   235
        HwProtocolMessage::Pong => (),
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   236
        _ => {
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   237
            if server.anteroom.clients.contains(client_id) {
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
   238
                match inanteroom::handle(server, client_id, response, message) {
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   239
                    LoginResult::Unchanged => (),
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   240
                    LoginResult::Complete => {
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   241
                        if let Some(client) = server.anteroom.remove_client(client_id) {
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   242
                            server.add_client(client_id, client);
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   243
                            common::join_lobby(server, response);
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   244
                        }
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   245
                    }
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   246
                    LoginResult::Exit => {
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   247
                        server.anteroom.remove_client(client_id);
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   248
                        response.remove_client(client_id);
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   249
                    }
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   250
                }
14796
f5d43f007970 start by actually handling client messages
alfadur
parents: 14795
diff changeset
   251
            } else if server.clients.contains(client_id) {
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   252
                match message {
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   253
                    HwProtocolMessage::Quit(Some(msg)) => {
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   254
                        common::remove_client(server, response, "User quit: ".to_string() + &msg);
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   255
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   256
                    HwProtocolMessage::Quit(None) => {
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   257
                        common::remove_client(server, response, "User quit".to_string());
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   258
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   259
                    HwProtocolMessage::Info(nick) => {
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   260
                        if let Some(client) = server.find_client(&nick) {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   261
                            let admin_sign = if client.is_admin() { "@" } else { "" };
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   262
                            let master_sign = if client.is_master() { "+" } else { "" };
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   263
                            let room_info = match client.room_id {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   264
                                Some(room_id) => {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   265
                                    let room = &server.rooms[room_id];
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   266
                                    let status = match room.game_info {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   267
                                        Some(_) if client.teams_in_game == 0 => "(spectating)",
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   268
                                        Some(_) => "(playing)",
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   269
                                        None => "",
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   270
                                    };
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   271
                                    format!(
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   272
                                        "[{}{}room {}]{}",
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   273
                                        admin_sign, master_sign, room.name, status
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   274
                                    )
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   275
                                }
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   276
                                None => format!("[{}lobby]", admin_sign),
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   277
                            };
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   278
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   279
                            let info = vec![
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   280
                                client.nick.clone(),
14802
a40139603cde fix info response
alfadur
parents: 14796
diff changeset
   281
                                "[]".to_string(),
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   282
                                utils::protocol_version_string(client.protocol_number).to_string(),
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   283
                                room_info,
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   284
                            ];
14802
a40139603cde fix info response
alfadur
parents: 14796
diff changeset
   285
                            response.add(Info(info).send_self())
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   286
                        } else {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   287
                            response
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   288
                                .add(server_chat("Player is not online.".to_string()).send_self())
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   289
                        }
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   290
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   291
                    HwProtocolMessage::ToggleServerRegisteredOnly => {
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   292
                        if !server.clients[client_id].is_admin() {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   293
                            response.add(Warning("Access denied.".to_string()).send_self());
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   294
                        } else {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   295
                            server.set_is_registered_only(server.is_registered_only());
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   296
                            let msg = if server.is_registered_only() {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   297
                                "This server no longer allows unregistered players to join."
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   298
                            } else {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   299
                                "This server now allows unregistered players to join."
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   300
                            };
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   301
                            response.add(server_chat(msg.to_string()).send_all());
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   302
                        }
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   303
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   304
                    HwProtocolMessage::Global(msg) => {
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   305
                        if !server.clients[client_id].is_admin() {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   306
                            response.add(Warning("Access denied.".to_string()).send_self());
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   307
                        } else {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   308
                            response.add(global_chat(msg).send_all())
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   309
                        }
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   310
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   311
                    HwProtocolMessage::SuperPower => {
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   312
                        if !server.clients[client_id].is_admin() {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   313
                            response.add(Warning("Access denied.".to_string()).send_self());
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   314
                        } else {
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   315
                            server.clients[client_id].set_has_super_power(true);
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   316
                            response
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   317
                                .add(server_chat("Super power activated.".to_string()).send_self())
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   318
                        }
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   319
                    }
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   320
                    HwProtocolMessage::Watch(id) => {
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   321
                        #[cfg(feature = "official-server")]
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   322
                        {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   323
                            response.request_io(IoTask::GetReplay { id })
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   324
                        }
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   325
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   326
                        #[cfg(not(feature = "official-server"))]
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   327
                        {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   328
                            response.add(
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   329
                                Warning("This server does not support replays!".to_string())
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   330
                                    .send_self(),
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   331
                            );
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   332
                        }
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   333
                    }
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   334
                    _ => match server.clients[client_id].room_id {
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14907
diff changeset
   335
                        None => inlobby::handle(server, client_id, response, message),
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   336
                        Some(room_id) => {
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   337
                            inroom::handle(server, client_id, response, room_id, message)
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   338
                        }
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   339
                    },
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   340
                }
14671
455865ccd36c Server action refactoring part 2 of N
alfadur <mail@none>
parents: 14457
diff changeset
   341
            }
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   342
        }
12149
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
   343
    }
44b06731278b Fix handlers module
unc0rr
parents:
diff changeset
   344
}
14673
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14672
diff changeset
   345
15176
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   346
pub fn handle_client_accept(
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   347
    server: &mut HwServer,
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   348
    client_id: ClientId,
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   349
    response: &mut Response,
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   350
    is_local: bool,
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   351
) {
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   352
    let mut salt = [0u8; 18];
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   353
    thread_rng().fill_bytes(&mut salt);
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   354
15176
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   355
    server
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   356
        .anteroom
f6115638aa92 enable local admins for non-official servers
alfadur
parents: 15163
diff changeset
   357
        .add_client(client_id, encode(&salt), is_local);
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   358
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   359
    response.add(HwServerMessage::Connected(utils::SERVER_VERSION).send_self());
14693
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   360
}
6a2e13e36b7f add server anteroom
alfadur <mail@none>
parents: 14690
diff changeset
   361
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   362
pub fn handle_client_loss(server: &mut HwServer, client_id: ClientId, response: &mut Response) {
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   363
    if server.anteroom.remove_client(client_id).is_none() {
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   364
        common::remove_client(server, response, "Connection reset".to_string());
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   365
    }
14673
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14672
diff changeset
   366
}
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   367
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   368
pub fn handle_io_result(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   369
    server: &mut HwServer,
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   370
    client_id: ClientId,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   371
    response: &mut Response,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   372
    io_result: IoResult,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   373
) {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   374
    match io_result {
15103
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   375
        IoResult::AccountRegistered(is_registered) => {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   376
            if !is_registered && server.is_registered_only() {
14786
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   377
                response.add(
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   378
                    Bye("This server only allows registered users to join.".to_string())
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   379
                        .send_self(),
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   380
                );
8ecdb5c6bb2a implement info, registered only & super power messages
alfadur
parents: 14785
diff changeset
   381
                response.remove_client(client_id);
15103
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   382
            } else if is_registered {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   383
                let salt = server.anteroom.clients[client_id].server_salt.clone();
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   384
                response.add(AskPassword(salt).send_self());
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   385
            } else if let Some(client) = server.anteroom.remove_client(client_id) {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   386
                server.add_client(client_id, client);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   387
                common::join_lobby(server, response);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   388
            }
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   389
        }
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   390
        IoResult::Account(Some(info)) => {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   391
            response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self());
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   392
            if let Some(client) = server.anteroom.remove_client(client_id) {
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   393
                server.add_client(client_id, client);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   394
                let client = &mut server.clients[client_id];
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   395
                client.set_is_registered(info.is_registered);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   396
                client.set_is_admin(info.is_admin);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   397
                client.set_is_contributor(info.is_contributor);
823052e66611 check for account existence before asking passwords
alfadur
parents: 15102
diff changeset
   398
                common::join_lobby(server, response);
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   399
            }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   400
        }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   401
        IoResult::Account(None) => {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   402
            response.add(Error("Authentication failed.".to_string()).send_self());
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   403
            response.remove_client(client_id);
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   404
        }
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   405
        IoResult::Replay(Some(replay)) => {
14907
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   406
            let protocol = server.clients[client_id].protocol_number;
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   407
            let start_msg = if protocol < 58 {
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   408
                RoomJoined(vec![server.clients[client_id].nick.clone()])
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   409
            } else {
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   410
                ReplayStart
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   411
            };
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   412
            response.add(start_msg.send_self());
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   413
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   414
            common::get_room_config_impl(&replay.config, client_id, response);
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   415
            common::get_teams(replay.teams.iter(), client_id, response);
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   416
            response.add(RunGame.send_self());
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   417
            response.add(ForwardEngineMessage(replay.message_log).send_self());
14907
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   418
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   419
            if protocol < 58 {
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   420
                response.add(Kicked.send_self());
c156273b57de add REPLAY_START support
alfadur
parents: 14802
diff changeset
   421
            }
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   422
        }
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   423
        IoResult::Replay(None) => {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   424
            response.add(Warning("Could't load the replay".to_string()).send_self())
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   425
        }
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   426
        IoResult::SaveRoom(_, true) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   427
            response.add(server_chat("Room configs saved successfully.".to_string()).send_self());
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   428
        }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   429
        IoResult::SaveRoom(_, false) => {
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   430
            response.add(Warning("Unable to save the room configs.".to_string()).send_self());
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   431
        }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   432
        IoResult::LoadRoom(room_id, Some(contents)) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   433
            if let Some(ref mut room) = server.rooms.get_mut(room_id) {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   434
                match room.set_saves(&contents) {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   435
                    Ok(_) => response.add(
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   436
                        server_chat("Room configs loaded successfully.".to_string()).send_self(),
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   437
                    ),
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   438
                    Err(e) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   439
                        warn!("Error while deserializing the room configs: {}", e);
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   440
                        response.add(
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   441
                            Warning("Unable to deserialize the room configs.".to_string())
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   442
                                .send_self(),
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   443
                        );
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   444
                    }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   445
                }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   446
            }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   447
        }
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   448
        IoResult::LoadRoom(_, None) => {
01f8ab45f806 fix lobby joining
alfadur
parents: 14780
diff changeset
   449
            response.add(Warning("Unable to load the room configs.".to_string()).send_self());
14780
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14779
diff changeset
   450
        }
14779
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   451
    }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14696
diff changeset
   452
}
15163
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   453
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   454
#[cfg(test)]
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   455
mod test {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   456
    use super::Sha1Digest;
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   457
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   458
    #[test]
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   459
    fn hash_cmp_test() {
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   460
        let hash = Sha1Digest([
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   461
            0x37, 0xC4, 0x9F, 0x5C, 0xC3, 0xC9, 0xDB, 0xFC, 0x54, 0xAC, 0x22, 0x04, 0xF6, 0x12,
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   462
            0x9A, 0xED, 0x69, 0xB1, 0xC4, 0x5C,
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   463
        ]);
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   464
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   465
        assert_eq!(hash, &format!("{:x}", hash)[..]);
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   466
    }
bcb98009ad39 avoid allocation in hash comparison
alfadur
parents: 15113
diff changeset
   467
}