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] = if ow == 0 {
54 0u16
55 } else {
56 t.units()[ow as usize]
57 }
58 .to_be();
59 tile[x][y] = TileClass::from(t) as u8;
60 }
61 }
62
63 S2CData {
64 player: player.0 as u8,
65 pause_request: 0,
66 gold: state.countries.each_ref().map(|c| (c.gold as u32).to_be()),
67 time: (state.time as u32).to_be(),
68 width: state.grid.width() as u8,
69 height: state.grid.height() as u8,
70 flag,
71 owner,
72 pop,
73 tile,
74 __pad0: [0; __S2C_PAD_0_LEN],
75 __pad1: [0; __S2C_PAD_1_LEN],
76 __pad2: [0; __S2C_PAD_2_LEN],
77 }
78 }
79
80 #[inline]
82 pub fn set_player(&mut self, player: Player) {
83 self.player = player.0 as u8;
84 }
85}
86
87pub fn apply_c2s_msg(
88 state: &mut State,
89 player: Player,
90 msg: u8,
91 data: C2SData,
92) -> curseofrust::Result<()> {
93 let pl = player.0 as usize;
94 let pos = Pos(data.x as i32, data.y as i32);
95
96 match msg {
97 BUILD => {
98 return state.grid.build(
99 state
100 .countries
101 .get_mut(pl)
102 .ok_or(curseofrust::Error::PlayerNotFound(player))?,
103 pos,
104 )
105 }
106 FLAG_ON => state
107 .fgs
108 .get_mut(pl)
109 .ok_or(curseofrust::Error::PlayerNotFound(player))?
110 .add(&state.grid, pos, FLAG_POWER),
111 FLAG_OFF => state
112 .fgs
113 .get_mut(pl)
114 .ok_or(curseofrust::Error::PlayerNotFound(player))?
115 .remove(&state.grid, pos, FLAG_POWER),
116 FLAG_OFF_ALL => state
117 .fgs
118 .get_mut(pl)
119 .ok_or(curseofrust::Error::PlayerNotFound(player))?
120 .remove_with_prob(&state.grid, 1.0),
121 FLAG_OFF_HALF => state
122 .fgs
123 .get_mut(pl)
124 .ok_or(curseofrust::Error::PlayerNotFound(player))?
125 .remove_with_prob(&state.grid, 0.5),
126 _ => {}
127 }
128 Ok(())
129}