rust/hedgewars-server/src/handlers/common.rs
author Wuzzy <Wuzzy2@mail.ru>
Thu, 11 Jul 2019 16:24:09 +0200
changeset 15231 c10e9261ab9c
parent 15111 1e45db229f9f
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:
13666
09f4a30e50cc Rust 2018 conversion
alfadur
parents: 13524
diff changeset
     1
use crate::{
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     2
    core::{
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     3
        client::HwClient,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     4
        room::HwRoom,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     5
        server::HwServer,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     6
        types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType},
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     7
    },
13666
09f4a30e50cc Rust 2018 conversion
alfadur
parents: 13524
diff changeset
     8
    protocol::messages::{
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
     9
        add_flags, remove_flags, server_chat,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    10
        HwProtocolMessage::{self, Rnd},
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    11
        HwServerMessage::{self, *},
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
    12
        ProtocolFlags as Flags,
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    13
    },
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
    14
    utils::to_engine_msg,
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
    15
};
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
    16
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
    17
use super::Response;
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
    18
15074
c5a6e8566425 shuffle server files
alfadur
parents: 14891
diff changeset
    19
use crate::core::types::RoomConfig;
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    20
use rand::{self, seq::SliceRandom, thread_rng, Rng};
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
    21
use std::{iter::once, mem::replace};
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
    22
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    23
pub fn rnd_reply(options: &[String]) -> HwServerMessage {
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
    24
    let mut rng = thread_rng();
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    25
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
    26
    let reply = if options.is_empty() {
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    27
        (*&["heads", "tails"].choose(&mut rng).unwrap()).to_string()
13445
d3c86ade3d4d Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13444
diff changeset
    28
    } else {
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    29
        options.choose(&mut rng).unwrap().clone()
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
    30
    };
13445
d3c86ade3d4d Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13444
diff changeset
    31
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
    32
    ChatMsg {
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    33
        nick: "[random]".to_string(),
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
    34
        msg: reply,
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
    35
    }
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
    36
}
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
    37
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
    38
pub fn join_lobby(server: &mut HwServer, response: &mut Response) {
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    39
    let client_id = response.client_id();
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    40
14791
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    41
    let client = &server.clients[client_id];
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    42
    let nick = vec![client.nick.clone()];
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    43
    let mut flags = vec![];
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    44
    if client.is_registered() {
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    45
        flags.push(Flags::Registered)
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    46
    }
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    47
    if client.is_admin() {
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    48
        flags.push(Flags::Admin)
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    49
    }
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    50
    if client.is_contributor() {
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    51
        flags.push(Flags::Contributor)
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    52
    }
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    53
14791
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    54
    let all_nicks: Vec<_> = server.collect_nicks(|_| true);
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    55
14791
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    56
    let mut flag_selectors = [
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    57
        (
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    58
            Flags::Registered,
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    59
            server.collect_nicks(|(_, c)| c.is_registered()),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    60
        ),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    61
        (Flags::Admin, server.collect_nicks(|(_, c)| c.is_admin())),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    62
        (
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    63
            Flags::Contributor,
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    64
            server.collect_nicks(|(_, c)| c.is_contributor()),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    65
        ),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    66
        (
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    67
            Flags::InRoom,
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    68
            server.collect_nicks(|(_, c)| c.room_id.is_some()),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    69
        ),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    70
    ];
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    71
14783
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
    72
    let server_msg = ServerMessage(server.get_greetings(client_id).to_string());
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    73
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    74
    let rooms_msg = Rooms(
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    75
        server
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    76
            .rooms
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    77
            .iter()
14801
da0cfeee9d96 don't show incompatible rooms
alfadur
parents: 14800
diff changeset
    78
            .filter(|(_, r)| r.protocol_number == client.protocol_number)
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    79
            .flat_map(|(_, r)| r.info(r.master_id.map(|id| &server.clients[id])))
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    80
            .collect(),
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    81
    );
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    82
14791
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    83
    response.add(LobbyJoined(nick).send_all().but_self());
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    84
    response.add(
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    85
        ClientFlags(add_flags(&flags), all_nicks.clone())
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    86
            .send_all()
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    87
            .but_self(),
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    88
    );
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    89
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    90
    response.add(LobbyJoined(all_nicks).send_self());
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    91
    for (flag, nicks) in &mut flag_selectors {
14891
e72d8c2299dd fix broken messages on lobby join
alfadur
parents: 14801
diff changeset
    92
        if !nicks.is_empty() {
e72d8c2299dd fix broken messages on lobby join
alfadur
parents: 14801
diff changeset
    93
            response.add(ClientFlags(add_flags(&[*flag]), replace(nicks, vec![])).send_self());
e72d8c2299dd fix broken messages on lobby join
alfadur
parents: 14801
diff changeset
    94
        }
14791
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    95
    }
b889d9e1115f improve lobby joining
alfadur
parents: 14790
diff changeset
    96
14781
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    97
    response.add(server_msg.send_self());
01f8ab45f806 fix lobby joining
alfadur
parents: 14697
diff changeset
    98
    response.add(rooms_msg.send_self());
14683
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
    99
}
932ff7683653 Server action refactoring part 8 of N
alfadur <mail@none>
parents: 14675
diff changeset
   100
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   101
pub fn remove_teams(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   102
    room: &mut HwRoom,
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   103
    team_names: Vec<String>,
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   104
    is_in_game: bool,
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   105
    response: &mut Response,
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   106
) {
14674
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   107
    if let Some(ref mut info) = room.game_info {
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   108
        for team_name in &team_names {
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   109
            info.left_teams.push(team_name.clone());
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   110
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   111
            if is_in_game {
14674
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   112
                let msg = once(b'F').chain(team_name.bytes());
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   113
                response.add(
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   114
                    ForwardEngineMessage(vec![to_engine_msg(msg)])
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   115
                        .send_all()
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   116
                        .in_room(room.id)
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   117
                        .but_self(),
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   118
                );
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   119
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   120
                info.teams_in_game -= 1;
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   121
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   122
                let remove_msg = to_engine_msg(once(b'F').chain(team_name.bytes()));
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   123
                if let Some(m) = &info.sync_msg {
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   124
                    info.msg_log.push(m.clone());
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   125
                    info.sync_msg = None
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   126
                }
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   127
                info.msg_log.push(remove_msg.clone());
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   128
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   129
                response.add(
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   130
                    ForwardEngineMessage(vec![remove_msg])
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   131
                        .send_all()
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   132
                        .in_room(room.id)
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   133
                        .but_self(),
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   134
                );
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   135
            }
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   136
        }
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   137
    }
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   138
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   139
    for team_name in team_names {
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   140
        room.remove_team(&team_name);
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   141
        response.add(TeamRemove(team_name).send_all().in_room(room.id));
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   142
    }
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   143
}
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   144
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   145
fn remove_client_from_room(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   146
    client: &mut HwClient,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   147
    room: &mut HwRoom,
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   148
    response: &mut Response,
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   149
    msg: &str,
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   150
) {
14798
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   151
    room.players_number -= 1;
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   152
    if room.players_number > 0 || room.is_fixed() {
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   153
        if client.is_ready() && room.ready_players_number > 0 {
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   154
            room.ready_players_number -= 1;
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   155
        }
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   156
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   157
        let team_names: Vec<_> = room
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   158
            .client_teams(client.id)
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   159
            .map(|t| t.name.clone())
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   160
            .collect();
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   161
        remove_teams(room, team_names, client.is_in_game(), response);
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   162
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   163
        if room.players_number > 0 {
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   164
            response.add(
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   165
                RoomLeft(client.nick.clone(), msg.to_string())
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   166
                    .send_all()
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   167
                    .in_room(room.id)
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   168
                    .but_self(),
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   169
            );
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   170
        }
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   171
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   172
        if client.is_master() && !room.is_fixed() {
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   173
            client.set_is_master(false);
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   174
            response.add(
14783
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   175
                ClientFlags(
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   176
                    remove_flags(&[Flags::RoomMaster]),
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   177
                    vec![client.nick.clone()],
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   178
                )
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   179
                .send_all()
b3adc030104b implement server vars
alfadur
parents: 14782
diff changeset
   180
                .in_room(room.id),
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   181
            );
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   182
            room.master_id = None;
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   183
        }
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   184
    }
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   185
14694
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14691
diff changeset
   186
    client.room_id = None;
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14691
diff changeset
   187
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   188
    let update_msg = if room.players_number == 0 && !room.is_fixed() {
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   189
        RoomRemove(room.name.clone())
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   190
    } else {
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   191
        RoomUpdated(room.name.clone(), room.info(Some(&client)))
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   192
    };
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   193
    response.add(update_msg.send_all().with_protocol(room.protocol_number));
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   194
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   195
    response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all());
14675
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   196
}
dfe652c53470 Server action refactoring part 6 of N
alfadur <mail@none>
parents: 14674
diff changeset
   197
14784
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   198
pub fn change_master(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   199
    server: &mut HwServer,
14784
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   200
    room_id: RoomId,
14790
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   201
    new_master_id: ClientId,
14784
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   202
    response: &mut Response,
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   203
) {
14790
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   204
    let room = &mut server.rooms[room_id];
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   205
    if let Some(master_id) = room.master_id {
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   206
        server.clients[master_id].set_is_master(false);
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   207
        response.add(
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   208
            ClientFlags(
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   209
                remove_flags(&[Flags::RoomMaster]),
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   210
                vec![server.clients[master_id].nick.clone()],
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   211
            )
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   212
            .send_all()
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   213
            .in_room(room_id),
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   214
        )
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   215
    }
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   216
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   217
    room.master_id = Some(new_master_id);
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   218
    server.clients[new_master_id].set_is_master(true);
14784
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   219
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   220
    response.add(
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   221
        ClientFlags(
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   222
            add_flags(&[Flags::RoomMaster]),
14790
e94fbf6cad2b fix room master change
alfadur
parents: 14789
diff changeset
   223
            vec![server.clients[new_master_id].nick.clone()],
14784
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   224
        )
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   225
        .send_all()
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   226
        .in_room(room_id),
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   227
    );
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   228
}
8390d5e4e39c implememg global&delegate messages
alfadur
parents: 14783
diff changeset
   229
14787
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   230
pub fn enter_room(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   231
    server: &mut HwServer,
14787
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   232
    client_id: ClientId,
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   233
    room_id: RoomId,
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   234
    response: &mut Response,
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   235
) {
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   236
    let nick = server.clients[client_id].nick.clone();
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   237
    server.move_to_room(client_id, room_id);
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   238
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   239
    response.add(RoomJoined(vec![nick.clone()]).send_all().in_room(room_id));
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   240
    response.add(ClientFlags(add_flags(&[Flags::InRoom]), vec![nick]).send_all());
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   241
    let nicks = server.collect_nicks(|(_, c)| c.room_id == Some(room_id));
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   242
    response.add(RoomJoined(nicks).send_self());
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   243
14799
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   244
    get_room_teams(server, room_id, client_id, response);
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   245
14787
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   246
    let room = &server.rooms[room_id];
14799
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   247
    get_room_config(room, client_id, response);
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   248
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   249
    let mut flag_selectors = [
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   250
        (
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   251
            Flags::RoomMaster,
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   252
            server.collect_nicks(|(_, c)| c.is_master()),
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   253
        ),
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   254
        (Flags::Ready, server.collect_nicks(|(_, c)| c.is_ready())),
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   255
        (Flags::InGame, server.collect_nicks(|(_, c)| c.is_in_game())),
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   256
    ];
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   257
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   258
    for (flag, nicks) in &mut flag_selectors {
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   259
        response.add(ClientFlags(add_flags(&[*flag]), replace(nicks, vec![])).send_self());
e41131607167 restore setup sending on room join
alfadur
parents: 14798
diff changeset
   260
    }
14787
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   261
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   262
    if !room.greeting.is_empty() {
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   263
        response.add(
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   264
            ChatMsg {
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   265
                nick: "[greeting]".to_string(),
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   266
                msg: room.greeting.clone(),
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   267
            }
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   268
            .send_self(),
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   269
        );
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   270
    }
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   271
}
0e64acbc3f8b implement follow message
alfadur
parents: 14785
diff changeset
   272
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   273
pub fn exit_room(server: &mut HwServer, client_id: ClientId, response: &mut Response, msg: &str) {
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   274
    let client = &mut server.clients[client_id];
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   275
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   276
    if let Some(room_id) = client.room_id {
14694
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14691
diff changeset
   277
        let room = &mut server.rooms[room_id];
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   278
14694
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14691
diff changeset
   279
        remove_client_from_room(client, room, response, msg);
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   280
14798
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   281
        if !room.is_fixed() {
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   282
            if room.players_number == 0 {
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   283
                server.rooms.remove(room_id);
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   284
            } else if room.master_id == None {
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   285
                let new_master_id = server.room_clients(room_id).next();
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   286
                if let Some(new_master_id) = new_master_id {
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   287
                    let new_master_nick = server.clients[new_master_id].nick.clone();
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   288
                    let room = &mut server.rooms[room_id];
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   289
                    room.master_id = Some(new_master_id);
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   290
                    server.clients[new_master_id].set_is_master(true);
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   291
14798
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   292
                    if room.protocol_number < 42 {
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   293
                        room.name = new_master_nick.clone();
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   294
                    }
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   295
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   296
                    room.set_join_restriction(false);
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   297
                    room.set_team_add_restriction(false);
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   298
                    room.set_unregistered_players_restriction(true);
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   299
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   300
                    response.add(
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   301
                        ClientFlags(add_flags(&[Flags::RoomMaster]), vec![new_master_nick])
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   302
                            .send_all()
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   303
                            .in_room(room.id),
d11481978633 fix room exiting
alfadur
parents: 14791
diff changeset
   304
                    );
14694
25c564f77b7d remove lobby room
alfadur <mail@none>
parents: 14691
diff changeset
   305
                }
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   306
            }
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   307
        }
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   308
    }
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   309
}
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   310
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   311
pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) {
14674
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   312
    let client_id = response.client_id();
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   313
    let client = &mut server.clients[client_id];
14697
f64e21f164a5 fix some warnings
alfadur
parents: 14696
diff changeset
   314
    let nick = client.nick.clone();
14674
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   315
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   316
    exit_room(server, client_id, response, &msg);
14674
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   317
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   318
    server.remove_client(client_id);
b87c71ccd17d Server action refactoring part 5 of N
alfadur <mail@none>
parents: 14673
diff changeset
   319
14673
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14457
diff changeset
   320
    response.add(LobbyLeft(nick, msg.to_string()).send_all());
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14457
diff changeset
   321
    response.add(Bye("User quit: ".to_string() + &msg).send_self());
14696
8a45c90f4580 fix client removal
alfadur
parents: 14694
diff changeset
   322
    response.remove_client(client_id);
14673
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14457
diff changeset
   323
}
08a8605bafaf Server action refactoring part 4 of N
alfadur <mail@none>
parents: 14457
diff changeset
   324
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   325
pub fn get_room_update(
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   326
    room_name: Option<String>,
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   327
    room: &HwRoom,
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   328
    master: Option<&HwClient>,
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   329
    response: &mut Response,
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   330
) {
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   331
    let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master));
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   332
    response.add(update_msg.send_all().with_protocol(room.protocol_number));
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   333
}
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   334
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   335
pub fn get_room_config_impl(config: &RoomConfig, to_client: ClientId, response: &mut Response) {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   336
    response.add(ConfigEntry("FULLMAPCONFIG".to_string(), config.to_map_config()).send(to_client));
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   337
    for cfg in config.to_game_config() {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   338
        response.add(cfg.to_server_msg().send(to_client));
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   339
    }
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   340
}
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   341
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   342
pub fn get_room_config(room: &HwRoom, to_client: ClientId, response: &mut Response) {
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   343
    get_room_config_impl(room.active_config(), to_client, response);
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   344
}
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   345
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   346
pub fn get_teams<'a, I>(teams: I, to_client: ClientId, response: &mut Response)
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   347
where
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   348
    I: Iterator<Item = &'a TeamInfo>,
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   349
{
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   350
    for team in teams {
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   351
        response.add(TeamAdd(team.to_protocol()).send(to_client));
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   352
        response.add(TeamColor(team.name.clone(), team.color).send(to_client));
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   353
        response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send(to_client));
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   354
    }
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   355
}
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   356
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   357
pub fn get_room_teams(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   358
    server: &HwServer,
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   359
    room_id: RoomId,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   360
    to_client: ClientId,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   361
    response: &mut Response,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   362
) {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   363
    let room = &server.rooms[room_id];
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   364
    let current_teams = match room.game_info {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   365
        Some(ref info) => &info.teams_at_start,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   366
        None => &room.teams,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   367
    };
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   368
14785
a1077e8d26f4 implement watch message apart from replay deserializing
alfadur
parents: 14784
diff changeset
   369
    get_teams(current_teams.iter().map(|(_, t)| t), to_client, response);
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   370
}
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   371
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   372
pub fn get_room_flags(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   373
    server: &HwServer,
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   374
    room_id: RoomId,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   375
    to_client: ClientId,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   376
    response: &mut Response,
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   377
) {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   378
    let room = &server.rooms[room_id];
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   379
    if let Some(id) = room.master_id {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   380
        response.add(
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   381
            ClientFlags(
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   382
                add_flags(&[Flags::RoomMaster]),
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   383
                vec![server.clients[id].nick.clone()],
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   384
            )
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   385
            .send(to_client),
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   386
        );
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   387
    }
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   388
    let nicks: Vec<_> = server
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   389
        .clients
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   390
        .iter()
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   391
        .filter(|(_, c)| c.room_id == Some(room_id) && c.is_ready())
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   392
        .map(|(_, c)| c.nick.clone())
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   393
        .collect();
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   394
    if !nicks.is_empty() {
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   395
        response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client));
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   396
    }
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   397
}
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   398
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   399
pub fn apply_voting_result(
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   400
    server: &mut HwServer,
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   401
    room_id: RoomId,
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   402
    response: &mut Response,
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   403
    kind: VoteType,
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   404
) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   405
    match kind {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   406
        VoteType::Kick(nick) => {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   407
            if let Some(client) = server.find_client(&nick) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   408
                if client.room_id == Some(room_id) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   409
                    let id = client.id;
14690
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   410
                    response.add(Kicked.send(id));
f61ce544d436 Server action refactoring part N of N
alfadur <mail@none>
parents: 14689
diff changeset
   411
                    exit_room(server, id, response, "kicked");
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   412
                }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   413
            }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   414
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   415
        VoteType::Map(None) => (),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   416
        VoteType::Map(Some(name)) => {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   417
            if let Some(location) = server.rooms[room_id].load_config(&name) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   418
                response.add(
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   419
                    server_chat(location.to_string())
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   420
                        .send_all()
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   421
                        .in_room(room_id),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   422
                );
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   423
                let room = &server.rooms[room_id];
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   424
                let room_master = if let Some(id) = room.master_id {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   425
                    Some(&server.clients[id])
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   426
                } else {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   427
                    None
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   428
                };
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   429
                get_room_update(None, room, room_master, response);
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   430
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   431
                for (_, client) in server.clients.iter() {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   432
                    if client.room_id == Some(room_id) {
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   433
                        super::common::get_room_config(&server.rooms[room_id], client.id, response);
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   434
                    }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   435
                }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   436
            }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   437
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   438
        VoteType::Pause => {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   439
            if let Some(ref mut info) = server.rooms[room_id].game_info {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   440
                info.is_paused = !info.is_paused;
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   441
                response.add(
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   442
                    server_chat("Pause toggled.".to_string())
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   443
                        .send_all()
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   444
                        .in_room(room_id),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   445
                );
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   446
                response.add(
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   447
                    ForwardEngineMessage(vec![to_engine_msg(once(b'I'))])
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   448
                        .send_all()
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   449
                        .in_room(room_id),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   450
                );
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   451
            }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   452
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   453
        VoteType::NewSeed => {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   454
            let seed = thread_rng().gen_range(0, 1_000_000_000).to_string();
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   455
            let cfg = GameCfg::Seed(seed);
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   456
            response.add(cfg.to_server_msg().send_all().in_room(room_id));
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   457
            server.rooms[room_id].set_config(cfg);
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   458
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   459
        VoteType::HedgehogsPerTeam(number) => {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   460
            let r = &mut server.rooms[room_id];
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   461
            let nicks = r.set_hedgehogs_number(number);
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   462
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   463
            response.extend(
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   464
                nicks
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   465
                    .into_iter()
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   466
                    .map(|n| HedgehogsNumber(n, number).send_all().in_room(room_id)),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   467
            );
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   468
        }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   469
    }
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   470
}
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   471
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   472
fn add_vote(room: &mut HwRoom, response: &mut Response, vote: Vote) -> Option<bool> {
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   473
    let client_id = response.client_id;
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   474
    let mut result = None;
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   475
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   476
    if let Some(ref mut voting) = room.voting {
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   477
        if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   478
            response.add(server_chat("Your vote has been counted.".to_string()).send_self());
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   479
            voting.votes.push((client_id, vote.is_pro));
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   480
            let i = voting.votes.iter();
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   481
            let pro = i.clone().filter(|(_, v)| *v).count();
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   482
            let contra = i.filter(|(_, v)| !*v).count();
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   483
            let success_quota = voting.voters.len() / 2 + 1;
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   484
            if vote.is_forced && vote.is_pro || pro >= success_quota {
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   485
                result = Some(true);
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   486
            } else if vote.is_forced && !vote.is_pro || contra > voting.voters.len() - success_quota
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   487
            {
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   488
                result = Some(false);
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   489
            }
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   490
        } else {
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   491
            response.add(server_chat("You already have voted.".to_string()).send_self());
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   492
        }
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   493
    } else {
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   494
        response.add(server_chat("There's no voting going on.".to_string()).send_self());
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   495
    }
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   496
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   497
    result
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   498
}
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   499
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   500
pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) {
14687
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   501
    let client_id = response.client_id;
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   502
    let client = &server.clients[client_id];
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   503
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   504
    if let Some(room_id) = client.room_id {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   505
        let room = &mut server.rooms[room_id];
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   506
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   507
        if let Some(res) = add_vote(room, response, vote) {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   508
            response.add(
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   509
                server_chat("Voting closed.".to_string())
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   510
                    .send_all()
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   511
                    .in_room(room.id),
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   512
            );
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   513
            let voting = replace(&mut room.voting, None).unwrap();
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   514
            if res {
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   515
                apply_voting_result(server, room_id, response, voting.kind);
5122c584804e Server action refactoring part A of N
alfadur <mail@none>
parents: 14686
diff changeset
   516
            }
14686
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   517
        }
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   518
    }
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   519
}
9f98086de1b6 Server action refactoring part 9 of N
alfadur <mail@none>
parents: 14683
diff changeset
   520
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   521
pub fn start_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) {
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   522
    let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   523
        .clients
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   524
        .iter()
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   525
        .map(|(id, c)| (id, c.nick.clone()))
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   526
        .unzip();
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   527
    let room = &mut server.rooms[room_id];
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   528
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   529
    if !room.has_multiple_clans() {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   530
        response.add(
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   531
            Warning("The game can't be started with less than two clans!".to_string()).send_self(),
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   532
        );
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   533
    } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   534
        response.add(Warning("Not all players are ready".to_string()).send_self());
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   535
    } else if room.game_info.is_some() {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   536
        response.add(Warning("The game is already in progress".to_string()).send_self());
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   537
    } else {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   538
        room.start_round();
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   539
        for id in room_clients {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   540
            let c = &mut server.clients[id];
14800
2107fd023733 fix client ingame flag
alfadur
parents: 14799
diff changeset
   541
            c.set_is_in_game(true);
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   542
            c.team_indices = room.client_team_indices(c.id);
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   543
        }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   544
        response.add(RunGame.send_all().in_room(room.id));
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   545
        response.add(
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   546
            ClientFlags(add_flags(&[Flags::InGame]), room_nicks)
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   547
                .send_all()
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   548
                .in_room(room.id),
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   549
        );
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   550
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   551
        let room_master = if let Some(id) = room.master_id {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   552
            Some(&server.clients[id])
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   553
        } else {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   554
            None
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   555
        };
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   556
        get_room_update(None, room, room_master, response);
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   557
    }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   558
}
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   559
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   560
pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) {
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   561
    let room = &mut server.rooms[room_id];
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   562
    room.ready_players_number = 1;
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   563
    let room_master = if let Some(id) = room.master_id {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   564
        Some(&server.clients[id])
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   565
    } else {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   566
        None
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   567
    };
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   568
    get_room_update(None, room, room_master, response);
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   569
    response.add(RoundFinished.send_all().in_room(room_id));
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   570
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   571
    if let Some(info) = replace(&mut room.game_info, None) {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   572
        for (_, client) in server.clients.iter() {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   573
            if client.room_id == Some(room_id) && client.is_joined_mid_game() {
14689
aae29ba56aec Server action refactoring part C of N
alfadur <mail@none>
parents: 14688
diff changeset
   574
                super::common::get_room_config(room, client.id, response);
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   575
                response.extend(
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   576
                    info.left_teams
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   577
                        .iter()
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   578
                        .map(|name| TeamRemove(name.clone()).send(client.id)),
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   579
                );
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   580
            }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   581
        }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   582
    }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   583
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   584
    let nicks: Vec<_> = server
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   585
        .clients
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   586
        .iter_mut()
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   587
        .filter(|(_, c)| c.room_id == Some(room_id))
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   588
        .map(|(_, c)| {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   589
            c.set_is_ready(c.is_master());
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   590
            c.set_is_joined_mid_game(false);
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   591
            c
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   592
        })
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   593
        .filter_map(|c| {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   594
            if !c.is_master() {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   595
                Some(c.nick.clone())
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   596
            } else {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   597
                None
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   598
            }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   599
        })
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   600
        .collect();
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   601
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   602
    if !nicks.is_empty() {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   603
        let msg = if room.protocol_number < 38 {
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   604
            LegacyReady(false, nicks)
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   605
        } else {
14782
50fcef24003f add typed protocol flags
alfadur
parents: 14781
diff changeset
   606
            ClientFlags(remove_flags(&[Flags::Ready]), nicks)
14688
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   607
        };
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   608
        response.add(msg.send_all().in_room(room_id));
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   609
    }
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   610
}
4569d8d50286 Server action refactoring part B of N
alfadur <mail@none>
parents: 14687
diff changeset
   611
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   612
#[cfg(test)]
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   613
mod tests {
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   614
    use super::*;
15111
1e45db229f9f make greeting argument optional
alfadur
parents: 15075
diff changeset
   615
    use crate::handlers::actions::PendingMessage;
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   616
    use crate::protocol::messages::HwServerMessage::ChatMsg;
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   617
15075
e935b1ad23f3 normalize type names
alfadur
parents: 15074
diff changeset
   618
    fn reply2string(r: HwServerMessage) -> String {
13445
d3c86ade3d4d Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13444
diff changeset
   619
        match r {
d3c86ade3d4d Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13444
diff changeset
   620
            ChatMsg { msg: p, .. } => String::from(p),
d3c86ade3d4d Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13444
diff changeset
   621
            _ => panic!("expected a ChatMsg"),
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   622
        }
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   623
    }
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   624
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   625
    fn run_handle_test(opts: Vec<String>) {
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   626
        let opts2 = opts.clone();
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   627
        for opt in opts {
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
   628
            while reply2string(rnd_reply(&opts2)) != opt {}
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   629
        }
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   630
    }
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   631
13446
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   632
    /// This test terminates almost surely.
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   633
    #[test]
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   634
    fn test_handle_rnd_empty() {
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   635
        run_handle_test(vec![])
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   636
    }
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   637
13446
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   638
    /// This test terminates almost surely.
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   639
    #[test]
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   640
    fn test_handle_rnd_nonempty() {
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   641
        run_handle_test(vec!["A".to_owned(), "B".to_owned(), "C".to_owned()])
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   642
    }
13446
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   643
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   644
    /// This test terminates almost surely (strong law of large numbers)
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   645
    #[test]
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   646
    fn test_distribution() {
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   647
        let eps = 0.000001;
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   648
        let lim = 0.5;
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   649
        let opts = vec![0.to_string(), 1.to_string()];
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   650
        let mut ones = 0;
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   651
        let mut tries = 0;
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   652
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   653
        while tries < 1000 || ((ones as f64 / tries as f64) - lim).abs() >= eps {
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   654
            tries += 1;
13521
ba5211dddb21 Assorted chat fixes
alfadur
parents: 13446
diff changeset
   655
            if reply2string(rnd_reply(&opts)) == 1.to_string() {
13446
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   656
                ones += 1;
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   657
            }
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   658
        }
dd2e51f7303d Add an extra test for Rnd's distribution
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents: 13445
diff changeset
   659
    }
13444
914f9b970f4d Implement server-side logic for Rnd
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
diff changeset
   660
}