curseofrust_msg/
server.rs1use 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 pub player: Player,
16 pub id: u32,
17 pub name: Cow<'static, str>,
18 pub addr: SocketAddr,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[deprecated = "This should not be used"]
25pub enum ServerMode {
26 Lobby,
28 Play,
30}
31
32impl S2CData {
33 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 #[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}