1use crate::*;
2
3packet_struct!(
4 PacketId::BANCHO_USER_LOGIN_REPLY,
5 LoginReply { login_result: LoginResult }
7);
8
9impl From<LoginResult> for LoginReply {
10 fn from(login_result: LoginResult) -> Self {
11 Self { login_result }
12 }
13}
14
15impl LoginReply {
16 #[inline]
17 pub fn success(user_id: i32) -> Self {
18 Self::new(LoginResult::Success(user_id))
19 }
20
21 #[inline]
22 pub fn failed_invalid_credentials() -> Self {
23 Self::new(LoginFailedReason::InvalidCredentials.into())
24 }
25
26 #[inline]
27 pub fn failed_outdated_client() -> Self {
28 Self::new(LoginFailedReason::OutdatedClient.into())
29 }
30
31 #[inline]
32 pub fn failed_user_banned() -> Self {
33 Self::new(LoginFailedReason::UserBanned.into())
34 }
35
36 #[inline]
37 pub fn failed_multiaccount_detected() -> Self {
38 Self::new(LoginFailedReason::MultiaccountDetected.into())
39 }
40
41 #[inline]
42 pub fn failed_server_error() -> Self {
43 Self::new(LoginFailedReason::ServerError.into())
44 }
45
46 #[inline]
47 pub fn failed_cutting_edge_multiplayer() -> Self {
48 Self::new(LoginFailedReason::CuttingEdgeMultiplayer.into())
49 }
50
51 #[inline]
52 pub fn failed_account_password_rest() -> Self {
53 Self::new(LoginFailedReason::AccountPasswordRest.into())
54 }
55
56 #[inline]
57 pub fn failed_verification_required() -> Self {
58 Self::new(LoginFailedReason::VerificationRequired.into())
59 }
60}
61
62packet_struct!(
63 PacketId::BANCHO_SEND_MESSAGE,
64 SendMessage<'a> {
66 sender: CowStr<'a>,
67 content: CowStr<'a>,
68 target: CowStr<'a>,
69 sender_id: i32,
70 }
71);
72
73packet_struct!(
74 PacketId::BANCHO_PONG,
75 Pong {}
77);
78
79packet_struct!(
80 PacketId::BANCHO_HANDLE_IRC_CHANGE_USERNAME,
81 ChangeUsername<'a> {
83 username_old: CowStr<'a>,
84 username_new: CowStr<'a>,
85 },
86 fn into_packet_data(self) -> Vec<u8> {
87 packet!(
88 Self::ID,
89 format!("{}>>>>{}", self.username_old, self.username_new)
90 )
91 }
92);
93
94packet_struct!(
95 PacketId::BANCHO_USER_STATS,
96 UserStats<'a> {
98 user_id: i32,
99 online_status: u8,
100 description: CowStr<'a>,
101 beatmap_md5: CowStr<'a>,
102 mods: u32,
103 mode: u8,
104 beatmap_id: i32,
105 ranked_score: i64,
106 accuracy: f32,
107 playcount: i32,
108 total_score: i64,
109 rank: i32,
110 pp: i16,
111 },
112 fn into_packet_data(self) -> Vec<u8> {
113 packet!(
114 Self::ID,
115 self.user_id,
116 self.online_status,
117 self.description,
118 self.beatmap_md5,
119 self.mods,
120 self.mode,
121 self.beatmap_id,
122 self.ranked_score,
123 self.accuracy / 100f32,
124 self.playcount,
125 self.total_score,
126 self.rank,
127 self.pp
128 )
129 }
130);
131
132packet_struct!(
133 PacketId::BANCHO_USER_LOGOUT,
134 UserLogout { user_id: i32 },
136 fn into_packet_data(self) -> Vec<u8> {
137 packet!(Self::ID, self.user_id, 0_u8)
138 }
139);
140
141packet_struct!(
142 PacketId::BANCHO_SPECTATOR_JOINED,
143 SpectatorJoined { user_id: i32 }
145);
146
147packet_struct!(
148 PacketId::BANCHO_SPECTATOR_LEFT,
149 SpectatorLeft { user_id: i32 }
151);
152
153packet_struct!(
154 PacketId::BANCHO_SPECTATE_FRAMES,
155 SpectatorFrames { data: Vec<u8> }
157);
158
159packet_struct!(
160 PacketId::BANCHO_VERSION_UPDATE,
161 VersionUpdate {}
163);
164
165packet_struct!(
166 PacketId::BANCHO_SPECTATOR_CANT_SPECTATE,
167 SpectatorCantSpectate { user_id: i32 }
169);
170
171packet_struct!(
172 PacketId::BANCHO_GET_ATTENTION,
173 GetAttention {}
175);
176
177packet_struct!(
178 PacketId::BANCHO_NOTIFICATION,
179 Notification<'a> { msg: CowStr<'a> }
181);
182
183packet_struct!(
184 PacketId::BANCHO_UPDATE_MATCH,
185 UpdateMatch { match_data: MatchData },
187 fn into_packet_data(self) -> Vec<u8> {
188 let data = MatchUpdate { data: self.match_data, send_password: false };
189 packet!(Self::ID, data)
190 }
191);
192
193packet_struct!(
194 PacketId::BANCHO_NEW_MATCH,
195 NewMatch { match_data: MatchData }
197);
198
199packet_struct!(
200 PacketId::BANCHO_DISBAND_MATCH,
201 DisbandMatch { match_id: i32 }
203);
204
205packet_struct!(
206 PacketId::BANCHO_TOGGLE_BLOCK_NON_FRIEND_DMS,
207 ToggleBlockNonFriendPm {}
209);
210
211packet_struct!(
212 PacketId::BANCHO_MATCH_JOIN_SUCCESS,
213 MatchJoinSuccess { match_data: MatchData }
215);
216
217packet_struct!(
218 PacketId::BANCHO_MATCH_JOIN_FAIL,
219 MatchJoinFail {}
221);
222
223packet_struct!(
224 PacketId::BANCHO_FELLOW_SPECTATOR_JOINED,
225 FellowSpectatorJoined { user_id: i32 }
227);
228
229packet_struct!(
230 PacketId::BANCHO_FELLOW_SPECTATOR_LEFT,
231 FellowSpectatorLeft { user_id: i32 }
233);
234
235packet_struct!(
236 PacketId::BANCHO_MATCH_START,
237 MatchStart { match_data: MatchData }
239);
240
241packet_struct!(
242 PacketId::BANCHO_MATCH_SCORE_UPDATE,
243 MatchScoreUpdate { scoreframe: ScoreFrame }
245);
246
247packet_struct!(
248 PacketId::BANCHO_MATCH_TRANSFER_HOST,
249 MatchTransferHost {}
251);
252
253packet_struct!(
254 PacketId::BANCHO_MATCH_ALL_PLAYERS_LOADED,
255 MatchAllPlayerLoaded {}
257);
258
259packet_struct!(
260 PacketId::BANCHO_MATCH_PLAYER_FAILED,
261 MatchPlayerFailed { slot_id: i32 }
263);
264
265packet_struct!(
266 PacketId::BANCHO_MATCH_COMPLETE,
267 MatchComplete {}
269);
270
271packet_struct!(
272 PacketId::BANCHO_MATCH_SKIP,
273 MatchSkip {}
275);
276
277packet_struct!(
278 PacketId::BANCHO_CHANNEL_JOIN_SUCCESS,
279 ChannelJoin<'a> { channel_name: CowStr<'a> }
281);
282
283packet_struct!(
284 PacketId::BANCHO_CHANNEL_INFO,
285 ChannelInfo<'a> {
287 name: CowStr<'a>,
288 title: CowStr<'a>,
289 player_count: i16,
290 }
291);
292
293packet_struct!(
294 PacketId::BANCHO_CHANNEL_KICK,
295 ChannelKick<'a> {
297 channel_name: CowStr<'a>
298 }
299);
300
301packet_struct!(
302 PacketId::BANCHO_CHANNEL_AUTO_JOIN,
303 ChannelAutoJoin<'a> {
305 name: CowStr<'a>,
306 title: CowStr<'a>,
307 player_count: i16,
308 }
309);
310
311packet_struct!(
312 PacketId::BANCHO_BEATMAP_INFO_REPLY,
313 BeatmapInfoReply {},
316 fn into_packet_data(self) -> Vec<u8> {
317 unimplemented!()
318 }
319);
320
321packet_struct!(
322 PacketId::BANCHO_PRIVILEGES,
323 BanchoPrivileges { privileges: i32 }
325);
326
327packet_struct!(
328 PacketId::BANCHO_FRIENDS_LIST,
329 FriendsList<'a> { friends: &'a [i32] }
331);
332
333packet_struct!(
334 PacketId::BANCHO_PROTOCOL_VERSION,
335 ProtocolVersion { version: i32 }
337);
338
339packet_struct!(
340 PacketId::BANCHO_MAIN_MENU_ICON,
341 MainMenuIcon<'a> {
343 image_url: CowStr<'a>,
344 link_url: CowStr<'a>
345 },
346 fn into_packet_data(self) -> Vec<u8> {
347 packet!(
348 Self::ID,
349 format!("{}|{}", self.image_url, self.link_url)
350 )
351 }
352);
353
354packet_struct!(
355 PacketId::BANCHO_MONITOR,
356 Monitor {}
359);
360
361packet_struct!(
362 PacketId::BANCHO_MATCH_PLAYER_SKIPPED,
363 MatchPlayerSkipped { slot_id: i32 }
365);
366
367packet_struct!(
368 PacketId::BANCHO_USER_PRESENCE,
369 UserPresence<'a> {
371 user_id: i32,
372 username: CowStr<'a>,
373 utc_offset: u8,
374 country_code: u8,
375 bancho_priv: i32,
376 longitude: f32,
377 latitude: f32,
378 rank: i32,
379 },
380 fn into_packet_data(self) -> Vec<u8> {
381 packet!(
382 Self::ID,
383 self.user_id,
384 self.username,
385 self.utc_offset + 24,
386 self.country_code,
387 self.bancho_priv as u8,
388 self.longitude,
389 self.latitude,
390 self.rank
391 )
392 }
393);
394
395packet_struct!(
396 PacketId::BANCHO_RESTART,
397 BanchoRestart { millis: i32 }
399);
400
401packet_struct!(
402 PacketId::BANCHO_MATCH_INVITE,
403 MatchInvite<'a> {
405 welcome: CowStr<'a>,
406 match_id: i32,
407 match_password: Option<CowStr<'a>>,
408 },
409 fn into_packet_data(self) -> Vec<u8> {
410 let data = format!(
411 "{} osump://{}/{}.",
412 self.welcome,
413 self.match_id,
414 self.match_password.unwrap_or(Cow::Borrowed(""))
415 );
416 packet!(
417 Self::ID,
418 data
419 )
420 }
421);
422
423packet_struct!(
424 PacketId::BANCHO_CHANNEL_INFO_END,
425 ChannelInfoEnd {}
427);
428
429packet_struct!(
430 PacketId::BANCHO_MATCH_CHANGE_PASSWORD,
431 MatchChangePassword<'a> {
433 password: CowStr<'a>
434 }
435);
436
437packet_struct!(
438 PacketId::BANCHO_SILENCE_END,
439 SilenceEnd { duration: i32 }
441);
442
443packet_struct!(
444 PacketId::BANCHO_USER_SILENCED,
445 UserSilenced { user_id: i32 }
447);
448
449packet_struct!(
450 PacketId::BANCHO_USER_PRESENCE_SINGLE,
451 UserPresenceSingle { user_id: i32 }
453);
454
455packet_struct!(
456 PacketId::BANCHO_USER_PRESENCE_BUNDLE,
457 UserPresenceBundle<'a> { player_ids: &'a [i32] }
459);
460
461packet_struct!(
462 PacketId::BANCHO_USER_DM_BLOCKED,
463 UserDmBlocked<'a> {
465 target: CowStr<'a>
466 },
467 fn into_packet_data(self) -> Vec<u8> {
468 packet!(
469 PacketId::BANCHO_USER_DM_BLOCKED,
470 "", "", self.target, 0_i32
471 )
472 }
473);
474
475packet_struct!(
476 PacketId::BANCHO_TARGET_IS_SILENCED,
477 TargetSilenced<'a> {
479 target: CowStr<'a>
480 },
481 fn into_packet_data(self) -> Vec<u8> {
482 packet!(
483 PacketId::BANCHO_USER_DM_BLOCKED,
484 "", "", self.target, 0_i32
485 )
486 }
487);
488
489packet_struct!(
490 PacketId::BANCHO_VERSION_UPDATE_FORCED,
491 VersionUpdateForced {}
493);
494
495packet_struct!(
496 PacketId::BANCHO_SWITCH_SERVER,
497 SwitchServer { time: i32 }
499);
500
501packet_struct!(
502 PacketId::BANCHO_ACCOUNT_RESTRICTED,
503 AccountRestricted {}
505);
506
507packet_struct!(
508 PacketId::BANCHO_RTX,
509 Rtx<'a> {
512 msg: CowStr<'a>
513 }
514);
515
516packet_struct!(
517 PacketId::BANCHO_MATCH_ABORT,
518 MatchAbort {}
520);
521
522packet_struct!(
523 PacketId::BANCHO_SWITCH_TOURNAMENT_SERVER,
524 SwitchTournamentServer<'a> {
526 ip: CowStr<'a>
527 }
528);