curseofrust_msg/
server.rs

1//! Server utils.
2
3use std::{borrow::Cow, net::SocketAddr};
4
5use curseofrust::{state::State, Player, Pos, FLAG_POWER, MAX_HEIGHT, MAX_WIDTH};
6
7use crate::{
8    client_msg::*, C2SData, S2CData, TileClass, __S2C_PAD_0_LEN, __S2C_PAD_1_LEN, __S2C_PAD_2_LEN,
9};
10
11#[derive(Debug, Clone)]
12#[deprecated = "use self-defined client struct instead"]
13pub struct ClientRecord {
14    /// Player of the client.
15    pub player: Player,
16    pub id: u32,
17    pub name: Cow<'static, str>,
18    /// Socket address of the client.
19    pub addr: SocketAddr,
20}
21
22/// Mode of a server.
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[deprecated = "This should not be used"]
25pub enum ServerMode {
26    /// Waiting for clients.
27    Lobby,
28    /// Playing
29    Play,
30}
31
32impl S2CData {
33    /// Creates a new `S2CData` from the given `State`.
34    pub fn new(player: Player, state: &State) -> Self {
35        let mut flag = [[0u8; MAX_HEIGHT as usize]; MAX_WIDTH as usize];
36        for (x, arr) in flag.iter_mut().enumerate() {
37            for (y, flag) in arr.iter_mut().enumerate() {
38                for (p, f) in state.fgs.iter().enumerate() {
39                    if f.is_flagged(Pos(x as i32, y as i32)) {
40                        *flag |= 1 << p;
41                    }
42                }
43            }
44        }
45
46        let mut owner = [[0u8; MAX_HEIGHT as usize]; MAX_WIDTH as usize];
47        let mut pop = [[0u16; MAX_HEIGHT as usize]; MAX_WIDTH as usize];
48        let mut tile = [[0u8; MAX_HEIGHT as usize]; MAX_WIDTH as usize];
49        for (x, arr) in state.grid.raw_tiles().iter().enumerate() {
50            for (y, t) in arr.iter().enumerate() {
51                let ow = t.owner().0;
52                owner[x][y] = ow as u8;
53                pop[x][y] = t.units()[ow as usize].to_be();
54                tile[x][y] = TileClass::from(t) as u8;
55            }
56        }
57
58        S2CData {
59            player: player.0 as u8,
60            pause_request: 0,
61            gold: state.countries.each_ref().map(|c| (c.gold as u32).to_be()),
62            time: (state.time as u32).to_be(),
63            width: state.grid.width() as u8,
64            height: state.grid.height() as u8,
65            flag,
66            owner,
67            pop,
68            tile,
69            __pad0: [0; __S2C_PAD_0_LEN],
70            __pad1: [0; __S2C_PAD_1_LEN],
71            __pad2: [0; __S2C_PAD_2_LEN],
72        }
73    }
74
75    /// Sets the player of the data.
76    #[inline]
77    pub fn set_player(&mut self, player: Player) {
78        self.player = player.0 as u8;
79    }
80}
81
82pub fn apply_c2s_msg(
83    state: &mut State,
84    player: Player,
85    msg: u8,
86    data: C2SData,
87) -> curseofrust::Result<()> {
88    let pl = player.0 as usize;
89    let pos = Pos(data.x as i32, data.y as i32);
90
91    match msg {
92        BUILD => {
93            return state.grid.build(
94                state
95                    .countries
96                    .get_mut(pl)
97                    .ok_or(curseofrust::Error::PlayerNotFound(player))?,
98                pos,
99            )
100        }
101        FLAG_ON => state
102            .fgs
103            .get_mut(pl)
104            .ok_or(curseofrust::Error::PlayerNotFound(player))?
105            .add(&state.grid, pos, FLAG_POWER),
106        FLAG_OFF => state
107            .fgs
108            .get_mut(pl)
109            .ok_or(curseofrust::Error::PlayerNotFound(player))?
110            .remove(&state.grid, pos, FLAG_POWER),
111        FLAG_OFF_ALL => state
112            .fgs
113            .get_mut(pl)
114            .ok_or(curseofrust::Error::PlayerNotFound(player))?
115            .remove_with_prob(&state.grid, 1.0),
116        FLAG_OFF_HALF => state
117            .fgs
118            .get_mut(pl)
119            .ok_or(curseofrust::Error::PlayerNotFound(player))?
120            .remove_with_prob(&state.grid, 0.5),
121        _ => {}
122    }
123    Ok(())
124}