106 room_id: RoomId, |
106 room_id: RoomId, |
107 message: HWProtocolMessage, |
107 message: HWProtocolMessage, |
108 ) { |
108 ) { |
109 use crate::protocol::messages::HWProtocolMessage::*; |
109 use crate::protocol::messages::HWProtocolMessage::*; |
110 match message { |
110 match message { |
111 Part(None) => server.react(client_id, vec![ |
111 Part(msg) => { |
112 MoveToLobby("part".to_string())]), |
112 let lobby_id = server.lobby_id; |
113 Part(Some(msg)) => server.react(client_id, vec![ |
113 if let (client, Some(room)) = server.client_and_room(client_id) { |
114 MoveToLobby(format!("part: {}", msg))]), |
114 let msg = match msg { |
|
115 Some(s) => format!("part: {}", s), |
|
116 None => "part".to_string() |
|
117 }; |
|
118 super::common::exit_room(client, room, response, &msg); |
|
119 client.room_id = Some(lobby_id); |
|
120 } |
|
121 }, |
115 Chat(msg) => { |
122 Chat(msg) => { |
116 let actions = { |
123 let client = &mut server.clients[client_id]; |
117 let c = &mut server.clients[client_id]; |
124 response.add(ChatMsg {nick: client.nick.clone(), msg}.send_all().in_room(room_id)); |
118 let chat_msg = ChatMsg {nick: c.nick.clone(), msg}; |
125 }, |
119 vec![chat_msg.send_all().in_room(room_id).but_self().action()] |
126 Fix => { |
|
127 if let (client, Some(room)) = server.client_and_room(client_id) { |
|
128 if client.is_admin() { room.set_is_fixed(true) } |
|
129 } |
|
130 } |
|
131 Unfix => { |
|
132 if let (client, Some(room)) = server.client_and_room(client_id) { |
|
133 if client.is_admin() { room.set_is_fixed(false) } |
|
134 } |
|
135 } |
|
136 Greeting(text) => { |
|
137 if let (clienr, Some(room)) = server.client_and_room(client_id) { |
|
138 if clienr.is_admin() || clienr.is_master() && !room.is_fixed() { |
|
139 room.greeting = text |
|
140 } |
|
141 } |
|
142 } |
|
143 RoomName(new_name) => { |
|
144 if is_name_illegal(&new_name) { |
|
145 response.add(Warning("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}".to_string()).send_self()); |
|
146 } else if server.rooms[room_id].is_fixed() { |
|
147 response.add(Warning("Access denied.".to_string()).send_self()); |
|
148 } else if server.has_room(&new_name) { |
|
149 response.add(Warning("A room with the same name already exists.".to_string()).send_self()); |
|
150 } else { |
|
151 let mut old_name = new_name.clone(); |
|
152 let client = &server.clients[client_id]; |
|
153 let room = &mut server.rooms[room_id]; |
|
154 swap(&mut room.name, &mut old_name); |
|
155 let update_msg = RoomUpdated(old_name, room.info(Some(client))); |
|
156 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
120 }; |
157 }; |
121 server.react(client_id, actions); |
|
122 }, |
|
123 Fix => { |
|
124 if let (c, Some(r)) = server.client_and_room(client_id) { |
|
125 if c.is_admin() { r.set_is_fixed(true) } |
|
126 } |
|
127 } |
|
128 Unfix => { |
|
129 if let (c, Some(r)) = server.client_and_room(client_id) { |
|
130 if c.is_admin() { r.set_is_fixed(false) } |
|
131 } |
|
132 } |
|
133 Greeting(text) => { |
|
134 if let (c, Some(r)) = server.client_and_room(client_id) { |
|
135 if c.is_admin() || c.is_master() && !r.is_fixed() { |
|
136 r.greeting = text |
|
137 } |
|
138 } |
|
139 } |
|
140 RoomName(new_name) => { |
|
141 let actions = |
|
142 if is_name_illegal(&new_name) { |
|
143 vec![Warn("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}".to_string())] |
|
144 } else if server.rooms[room_id].is_fixed() { |
|
145 vec![Warn("Access denied.".to_string())] |
|
146 } else if server.has_room(&new_name) { |
|
147 vec![Warn("A room with the same name already exists.".to_string())] |
|
148 } else { |
|
149 let mut old_name = new_name.clone(); |
|
150 swap(&mut server.rooms[room_id].name, &mut old_name); |
|
151 vec![SendRoomUpdate(Some(old_name))] |
|
152 }; |
|
153 server.react(client_id, actions); |
|
154 }, |
158 }, |
155 ToggleReady => { |
159 ToggleReady => { |
156 if let (c, Some(r)) = server.client_and_room(client_id) { |
160 if let (client, Some(room)) = server.client_and_room(client_id) { |
157 let flags = if c.is_ready() { |
161 let flags = if client.is_ready() { |
158 r.ready_players_number -= 1; |
162 room.ready_players_number -= 1; |
159 "-r" |
163 "-r" |
160 } else { |
164 } else { |
161 r.ready_players_number += 1; |
165 room.ready_players_number += 1; |
162 "+r" |
166 "+r" |
163 }; |
167 }; |
164 |
168 |
165 let msg = if c.protocol_number < 38 { |
169 let msg = if client.protocol_number < 38 { |
166 LegacyReady(c.is_ready(), vec![c.nick.clone()]) |
170 LegacyReady(client.is_ready(), vec![client.nick.clone()]) |
167 } else { |
171 } else { |
168 ClientFlags(flags.to_string(), vec![c.nick.clone()]) |
172 ClientFlags(flags.to_string(), vec![client.nick.clone()]) |
169 }; |
173 }; |
170 |
174 response.add(msg.send_all().in_room(room.id)); |
171 let mut v = vec![msg.send_all().in_room(r.id).action()]; |
175 if room.is_fixed() && room.ready_players_number == room.players_number { |
172 |
176 //StartRoomGame(r.id) |
173 if r.is_fixed() && r.ready_players_number == r.players_number { |
177 } |
174 v.push(StartRoomGame(r.id)) |
178 |
175 } |
179 client.set_is_ready(!client.is_ready()); |
176 |
|
177 c.set_is_ready(!c.is_ready()); |
|
178 server.react(client_id, v); |
|
179 } |
180 } |
180 } |
181 } |
181 AddTeam(info) => { |
182 AddTeam(info) => { |
182 let mut actions = Vec::new(); |
183 if let (client, Some(room)) = server.client_and_room(client_id) { |
183 if let (c, Some(r)) = server.client_and_room(client_id) { |
184 if room.teams.len() >= room.team_limit as usize { |
184 if r.teams.len() >= r.team_limit as usize { |
185 response.add(Warning("Too many teams!".to_string()).send_self()); |
185 actions.push(Warn("Too many teams!".to_string())) |
186 } else if room.addable_hedgehogs() == 0 { |
186 } else if r.addable_hedgehogs() == 0 { |
187 response.add(Warning("Too many hedgehogs!".to_string()).send_self()); |
187 actions.push(Warn("Too many hedgehogs!".to_string())) |
188 } else if room.find_team(|t| t.name == info.name) != None { |
188 } else if r.find_team(|t| t.name == info.name) != None { |
189 response.add(Warning("There's already a team with same name in the list.".to_string()).send_self()); |
189 actions.push(Warn("There's already a team with same name in the list.".to_string())) |
190 } else if room.game_info.is_some() { |
190 } else if r.game_info.is_some() { |
191 response.add(Warning("Joining not possible: Round is in progress.".to_string()).send_self()); |
191 actions.push(Warn("Joining not possible: Round is in progress.".to_string())) |
192 } else if room.is_team_add_restricted() { |
192 } else if r.is_team_add_restricted() { |
193 response.add(Warning("This room currently does not allow adding new teams.".to_string()).send_self()); |
193 actions.push(Warn("This room currently does not allow adding new teams.".to_string())); |
194 } else { |
194 } else { |
195 let team = room.add_team(client.id, *info, client.protocol_number < 42); |
195 let team = r.add_team(c.id, *info, c.protocol_number < 42); |
196 client.teams_in_game += 1; |
196 c.teams_in_game += 1; |
197 client.clan = Some(team.color); |
197 c.clan = Some(team.color); |
198 response.add(TeamAccepted(team.name.clone()) |
198 actions.push(TeamAccepted(team.name.clone()) |
199 .send_self()); |
199 .send_self().action()); |
200 response.add(TeamAdd(HWRoom::team_info(&client, team)) |
200 actions.push(TeamAdd(HWRoom::team_info(&c, team)) |
201 .send_all().in_room(room_id).but_self()); |
201 .send_all().in_room(room_id).but_self().action()); |
202 response.add(TeamColor(team.name.clone(), team.color) |
202 actions.push(TeamColor(team.name.clone(), team.color) |
203 .send_all().in_room(room_id)); |
203 .send_all().in_room(room_id).action()); |
204 response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
204 actions.push(HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
205 .send_all().in_room(room_id)); |
205 .send_all().in_room(room_id).action()); |
206 |
206 actions.push(SendRoomUpdate(None)); |
207 let update_msg = RoomUpdated(room.name.clone(), room.info(Some(client))); |
207 } |
208 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
208 } |
209 } |
209 server.react(client_id, actions); |
210 } |
210 }, |
211 }, |
211 RemoveTeam(name) => { |
212 RemoveTeam(name) => { |
212 let mut actions = Vec::new(); |
213 if let (client, Some(room)) = server.client_and_room(client_id) { |
213 if let (c, Some(r)) = server.client_and_room(client_id) { |
214 match room.find_team_owner(&name) { |
214 match r.find_team_owner(&name) { |
|
215 None => |
215 None => |
216 actions.push(Warn("Error: The team you tried to remove does not exist.".to_string())), |
216 response.add(Warning("Error: The team you tried to remove does not exist.".to_string()).send_self()), |
217 Some((id, _)) if id != client_id => |
217 Some((id, _)) if id != client_id => |
218 actions.push(Warn("You can't remove a team you don't own.".to_string())), |
218 response.add(Warning("You can't remove a team you don't own.".to_string()).send_self()), |
219 Some((_, name)) => { |
219 Some((_, name)) => { |
220 c.teams_in_game -= 1; |
220 client.teams_in_game -= 1; |
221 c.clan = r.find_team_color(c.id); |
221 client.clan = room.find_team_color(client.id); |
222 actions.push(Action::RemoveTeam(name.to_string())); |
222 super::common::remove_teams(room, vec![name.to_string()], client.is_in_game(), response); |
223 } |
223 } |
224 } |
224 } |
225 }; |
225 } |
226 server.react(client_id, actions); |
|
227 }, |
226 }, |
228 SetHedgehogsNumber(team_name, number) => { |
227 SetHedgehogsNumber(team_name, number) => { |
229 if let (c, Some(r)) = server.client_and_room(client_id) { |
228 if let (c, Some(r)) = server.client_and_room(client_id) { |
230 let addable_hedgehogs = r.addable_hedgehogs(); |
229 let addable_hedgehogs = r.addable_hedgehogs(); |
231 let actions = if let Some((_, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |
230 let actions = if let Some((_, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |