airmash_protocol/v5/
server.rs

1use crate::server::*;
2use crate::v5::{AirmashDeserializerV5, AirmashSerializerV5, DeserializeV5, Result, SerializeV5};
3use crate::ServerPacket;
4
5decl_serde! {
6  struct LoginPlayer {
7    id,
8    status,
9    level,
10    name => { serialize_text_small, deserialize_text_small },
11    ty,
12    team,
13    pos => { serialize_pos, deserialize_pos },
14    rot => { serialize_rot, deserialize_rot },
15    flag,
16    upgrades
17  }
18}
19
20decl_serde! {
21  struct Login {
22    success,
23    id,
24    team,
25    clock,
26    token => { serialize_text_small, deserialize_text_small },
27    ty,
28    room => { serialize_text_small, deserialize_text_small },
29    players => { serialize_array_large, deserialize_array_large },
30  }
31}
32
33decl_serde! {
34  struct LoginBot {
35    id
36  }
37}
38
39decl_serde! {
40  struct Login2 {
41    login,
42    config => { serialize_text_large, deserialize_text_large },
43    bots => { serialize_array_large, deserialize_array_large },
44  }
45}
46
47decl_serde! {
48  struct Ping {
49    clock,
50    num
51  }
52}
53
54decl_serde! {
55  struct PingResult {
56    ping,
57    players_total,
58    players_game,
59  }
60}
61
62decl_serde! {
63  struct CommandReply {
64    ty,
65    text => { serialize_text_large, deserialize_text_large }
66  }
67}
68
69decl_serde! {
70  struct PlayerNew {
71    id,
72    status,
73    name => { serialize_text_small, deserialize_text_small },
74    ty,
75    team,
76    pos => { serialize_pos, deserialize_pos },
77    rot => { serialize_rot, deserialize_rot },
78    flag,
79    upgrades,
80  }
81}
82
83decl_serde! {
84  struct PlayerLeave {
85    id
86  }
87}
88
89decl_serde! {
90  struct PlayerUpdate {
91    clock,
92    id,
93    keystate,
94    upgrades,
95    pos => { serialize_pos24, deserialize_pos24 },
96    rot => { serialize_rot, deserialize_rot },
97    speed => { serialize_vel, deserialize_vel }
98  }
99}
100
101decl_serde! {
102  struct PlayerFireProjectile {
103    id,
104    ty,
105    pos => { serialize_pos, deserialize_pos },
106    speed => { serialize_vel, deserialize_vel },
107    accel => { serialize_accel, deserialize_accel },
108    max_speed => { serialize_speed, deserialize_speed }
109  }
110}
111
112decl_serde! {
113  // Note: Need to implement this one manually
114  struct PlayerFire {
115    clock,
116    id,
117    energy => { serialize_energy, deserialize_energy },
118    energy_regen => { serialize_regen, deserialize_regen },
119    projectiles => { serialize_array_small, deserialize_array_small },
120  }
121}
122
123decl_serde! {
124  struct PlayerRespawn {
125    id,
126    pos => { serialize_pos24, deserialize_pos24 },
127    rot => { serialize_rot, deserialize_rot },
128    upgrades
129  }
130}
131
132decl_serde! {
133  struct PlayerFlag {
134    id,
135    flag
136  }
137}
138
139decl_serde! {
140  struct PlayerLevel {
141    id,
142    ty,
143    level
144  }
145}
146
147decl_serde! {
148  struct PlayerHitPlayer {
149    id,
150    health => { serialize_energy, deserialize_energy },
151    health_regen => { serialize_regen, deserialize_regen }
152  }
153}
154
155decl_serde! {
156  // TODO: Need manual fixup
157  struct PlayerHit {
158    id,
159    ty,
160    pos => { serialize_pos, deserialize_pos },
161    owner,
162    players => { serialize_array_small, deserialize_array_small }
163  }
164}
165
166decl_serde! {
167  // TODO: Needs to be done manually as well
168  struct PlayerKill {
169    id,
170    killer => { serialize_option_player, deserialize_option_player },
171    pos => { serialize_pos, deserialize_pos }
172  }
173}
174
175decl_serde! {
176  struct PlayerUpgrade {
177    upgrades,
178    ty,
179    speed,
180    defense,
181    energy,
182    missile
183  }
184}
185
186decl_serde! {
187  struct PlayerType {
188    id,
189    ty
190  }
191}
192
193decl_serde! {
194  struct PlayerPowerup {
195    ty,
196    duration
197  }
198}
199
200decl_serde! {
201  struct PlayerReteamPlayer {
202    id,
203    team
204  }
205}
206
207decl_serde! {
208  struct PlayerReteam {
209    players => { serialize_array_large, deserialize_array_large }
210  }
211}
212
213decl_serde! {
214  struct GameFlag {
215    ty,
216    flag,
217    id => { serialize_option_player, deserialize_option_player },
218    pos => { serialize_pos24, deserialize_pos24 },
219    blueteam,
220    redteam
221  }
222}
223
224decl_serde! {
225  struct GameSpectate {
226    id
227  }
228}
229
230decl_serde! {
231  struct GamePlayersAlive {
232    players
233  }
234}
235
236decl_serde! {
237  struct GameFirewall {
238    ty,
239    status,
240    pos => { serialize_pos, deserialize_pos },
241    radius,
242    speed
243  }
244}
245
246decl_serde! {
247  struct EventRepelPlayer {
248    id,
249    keystate,
250    pos => { serialize_pos, deserialize_pos },
251    rot => { serialize_rot, deserialize_rot },
252    speed => { serialize_vel, deserialize_vel },
253    energy => { serialize_energy, deserialize_energy },
254    energy_regen => { serialize_regen, deserialize_regen },
255    health => { serialize_energy, deserialize_energy },
256    health_regen => { serialize_regen, deserialize_regen }
257  }
258}
259
260decl_serde! {
261  struct EventRepelMob {
262    id,
263    ty,
264    pos => { serialize_pos, deserialize_pos },
265    speed => { serialize_vel, deserialize_vel },
266    accel => { serialize_accel, deserialize_accel },
267    max_speed => { serialize_speed, deserialize_speed }
268  }
269}
270
271decl_serde! {
272  struct EventRepel {
273    clock,
274    id,
275    pos => { serialize_pos, deserialize_pos },
276    rot => { serialize_rot, deserialize_rot },
277    speed => { serialize_vel, deserialize_vel },
278    energy => { serialize_energy, deserialize_energy },
279    energy_regen => { serialize_regen, deserialize_regen },
280    players => { serialize_array_small, deserialize_array_small },
281    mobs => { serialize_array_small, deserialize_array_small }
282  }
283}
284
285decl_serde! {
286  struct EventBoost {
287    clock,
288    id,
289    boost,
290    pos => { serialize_pos24, deserialize_pos24 },
291    rot => { serialize_rot, deserialize_rot },
292    speed => { serialize_vel, deserialize_vel },
293    energy => { serialize_energy, deserialize_energy },
294    energy_regen => { serialize_regen, deserialize_regen },
295  }
296}
297
298decl_serde! {
299  struct EventBounce {
300    clock,
301    id,
302    keystate,
303    pos => { serialize_pos24, deserialize_pos24 },
304    rot => { serialize_rot, deserialize_rot },
305    speed => { serialize_vel, deserialize_vel }
306  }
307}
308
309decl_serde! {
310  struct EventStealth {
311    id,
312    state,
313    energy => { serialize_energy, deserialize_energy },
314    energy_regen => { serialize_regen, deserialize_regen }
315  }
316}
317
318decl_serde! {
319  struct EventLeaveHorizon {
320    ty,
321    id
322  }
323}
324
325decl_serde! {
326  struct MobUpdate {
327    clock,
328    id,
329    ty,
330    pos => { serialize_pos, deserialize_pos },
331    speed => { serialize_vel, deserialize_vel },
332    accel => { serialize_accel, deserialize_accel },
333    max_speed => { serialize_speed, deserialize_speed }
334  }
335}
336
337decl_serde! {
338  struct MobUpdate2 {
339    update,
340    owner
341  }
342}
343
344decl_serde! {
345  struct MobUpdateStationary {
346    id,
347    ty,
348    pos => { serialize_pos_f32, deserialize_pos_f32 }
349  }
350}
351
352decl_serde! {
353  struct MobDespawn {
354    id,
355    ty
356  }
357}
358
359decl_serde! {
360  struct MobDespawnCoords {
361    id,
362    ty,
363    pos => { serialize_pos, deserialize_pos }
364  }
365}
366
367decl_serde! {
368  struct ScoreUpdate {
369    id,
370    score,
371    earnings,
372    upgrades,
373    total_kills,
374    total_deaths
375  }
376}
377
378decl_serde! {
379  struct ScoreBoardData {
380    id,
381    score,
382    level
383  }
384}
385
386decl_serde! {
387  struct ScoreBoardRanking {
388    id,
389    pos => { serialize_low_res_pos, deserialize_low_res_pos }
390  }
391}
392
393decl_serde! {
394  struct ScoreBoard {
395    data => { serialize_array_large, deserialize_array_large },
396    rankings => { serialize_array_large, deserialize_array_large }
397  }
398}
399
400decl_serde! {
401  struct ScoreDetailedFFAEntry {
402    id,
403    level,
404    score,
405    kills,
406    deaths,
407    damage,
408    ping
409  }
410}
411
412decl_serde! {
413  struct ScoreDetailedFFA {
414    scores => { serialize_array_large, deserialize_array_large }
415  }
416}
417
418decl_serde! {
419  struct ScoreDetailedCTFEntry {
420    id,
421    level,
422    captures,
423    score,
424    kills,
425    deaths,
426    damage,
427    ping
428  }
429}
430
431decl_serde! {
432  struct ScoreDetailedCTF {
433    scores => { serialize_array_large, deserialize_array_large }
434  }
435}
436
437decl_serde! {
438  struct ScoreDetailedBTREntry {
439    id,
440    level,
441    alive,
442    wins,
443    score,
444    kills,
445    deaths,
446    damage,
447    ping
448  }
449}
450
451decl_serde! {
452  struct ScoreDetailedBTR {
453    scores => { serialize_array_large, deserialize_array_large }
454  }
455}
456
457decl_serde! {
458  struct ChatTeam {
459    id,
460    text => { serialize_text_small, deserialize_text_small }
461  }
462}
463
464decl_serde! {
465  struct ChatPublic {
466    id,
467    text => { serialize_text_small, deserialize_text_small }
468  }
469}
470
471decl_serde! {
472  struct ChatSay {
473    id,
474    text => { serialize_text_small, deserialize_text_small }
475  }
476}
477
478decl_serde! {
479  struct ChatWhisper {
480    from,
481    to,
482    text => { serialize_text_small, deserialize_text_small }
483  }
484}
485
486decl_serde! {
487  struct ChatVoteMutePassed {
488    id
489  }
490}
491
492decl_serde! {
493  struct ServerMessage {
494    ty,
495    duration,
496    text => { serialize_text_large, deserialize_text_large }
497  }
498}
499
500decl_serde! {
501  struct ServerCustom {
502    ty,
503    data => { serialize_text_large, deserialize_text_large }
504  }
505}
506
507decl_serde! {
508  struct Error {
509    error
510  }
511}
512
513decl_consts! {
514  const Login = 0;
515  const Login2 = Login::V5_PACKET_NO;
516  const Backup = 1;
517  const Ping = 5;
518  const PingResult = 6;
519  const Ack = 7;
520  const Error = 8;
521  const CommandReply = 9;
522  const PlayerNew = 10;
523  const PlayerLeave = 11;
524  const PlayerUpdate = 12;
525  const PlayerFire = 13;
526  const PlayerHit = 14;
527  const PlayerRespawn = 15;
528  const PlayerFlag = 16;
529  const PlayerKill = 17;
530  const PlayerUpgrade = 18;
531  const PlayerType = 19;
532  const PlayerPowerup = 20;
533  const PlayerLevel = 21;
534  const PlayerReteam = 22;
535  const GameFlag = 30;
536  const GameSpectate = 31;
537  const GamePlayersAlive = 32;
538  const GameFirewall = 33;
539  const EventRepel = 40;
540  const EventBoost = 41;
541  const EventBounce = 42;
542  const EventStealth = 43;
543  const EventLeaveHorizon = 44;
544  const MobUpdate = 60;
545  const MobUpdate2 = MobUpdate::V5_PACKET_NO;
546  const MobUpdateStationary = 61;
547  const MobDespawn = 62;
548  const MobDespawnCoords = 63;
549  const ChatPublic = 70;
550  const ChatTeam = 71;
551  const ChatSay = 72;
552  const ChatWhisper = 73;
553  const ChatVoteMutePassed = 78;
554  const ChatVoteMuted = 79;
555  const ScoreUpdate = 80;
556  const ScoreBoard = 81;
557  const ScoreDetailedFFA = 82;
558  const ScoreDetailedCTF = 83;
559  const ScoreDetailedBTR = 84;
560  const ServerMessage = 90;
561  const ServerCustom = 91;
562}
563
564packet_serialize! {
565  enum ServerPacket {
566    Login(x),
567    Login2(x),
568    Backup,
569    Ping(x),
570    PingResult(x),
571    Ack,
572    Error(x),
573    CommandReply(x),
574    PlayerNew(x),
575    PlayerLeave(x),
576    PlayerUpdate(x),
577    PlayerFire(x),
578    PlayerRespawn(x),
579    PlayerFlag(x),
580    PlayerHit(x),
581    PlayerKill(x),
582    PlayerUpgrade(x),
583    PlayerType(x),
584    PlayerPowerup(x),
585    PlayerLevel(x),
586    PlayerReteam(x),
587    GameFlag(x),
588    GameSpectate(x),
589    GamePlayersAlive(x),
590    GameFirewall(x),
591    EventRepel(x),
592    EventBoost(x),
593    EventBounce(x),
594    EventStealth(x),
595    EventLeaveHorizon(x),
596    MobUpdate(x),
597    MobUpdate2(x),
598    MobUpdateStationary(x),
599    MobDespawn(x),
600    MobDespawnCoords(x),
601    ScoreUpdate(x),
602    ScoreBoard(x),
603    ScoreDetailedFFA(x),
604    ScoreDetailedCTF(x),
605    ScoreDetailedBTR(x),
606    ChatTeam(x),
607    ChatPublic(x),
608    ChatSay(x),
609    ChatWhisper(x),
610    ChatVoteMutePassed(x),
611    ChatVoteMuted,
612    ServerMessage(x),
613    ServerCustom(x)
614  }
615}
616
617packet_deserialize! {
618  enum ServerPacket {
619    // Login(x),
620    // Login2(x),
621    Backup,
622    Ping(x),
623    PingResult(x),
624    Ack,
625    Error(x),
626    CommandReply(x),
627    PlayerNew(x),
628    PlayerLeave(x),
629    PlayerUpdate(x),
630    PlayerFire(x),
631    PlayerRespawn(x),
632    PlayerFlag(x),
633    PlayerHit(x),
634    PlayerKill(x),
635    PlayerUpgrade(x),
636    PlayerType(x),
637    PlayerPowerup(x),
638    PlayerLevel(x),
639    PlayerReteam(x),
640    GameFlag(x),
641    GameSpectate(x),
642    GamePlayersAlive(x),
643    GameFirewall(x),
644    EventRepel(x),
645    EventBoost(x),
646    EventBounce(x),
647    EventStealth(x),
648    EventLeaveHorizon(x),
649    // MobUpdate(x),
650    // MobUpdate2(x),
651    MobUpdateStationary(x),
652    MobDespawn(x),
653    MobDespawnCoords(x),
654    ScoreUpdate(x),
655    ScoreBoard(x),
656    ScoreDetailedFFA(x),
657    ScoreDetailedCTF(x),
658    ScoreDetailedBTR(x),
659    ChatTeam(x),
660    ChatPublic(x),
661    ChatSay(x),
662    ChatWhisper(x),
663    ChatVoteMutePassed(x),
664    ChatVoteMuted,
665    ServerMessage(x),
666    ServerCustom(x)
667  }
668
669  match de {
670    Login::V5_PACKET_NO => {
671      let login = de.deserialize().with_context("Login")?;
672
673      if de.remainder().is_empty() {
674        return Ok(ServerPacket::Login(login));
675      }
676
677      Ok(ServerPacket::Login2(Login2 {
678        login,
679        config: de.deserialize_text_large()
680          .with_context("config")
681          .with_context("Login2")?,
682        bots: de.deserialize_array_large()
683          .with_context("bots")
684          .with_context("Login2")?,
685      }))
686    },
687    MobUpdate::V5_PACKET_NO => {
688      let update = de.deserialize().with_context("MobUpdate")?;
689
690      if de.remainder().is_empty() {
691        return Ok(ServerPacket::MobUpdate(update));
692      }
693
694      Ok(ServerPacket::MobUpdate2(MobUpdate2 {
695        update,
696        owner: de.deserialize_u16()
697          .with_context("owner")
698          .with_context("MobUpdate2")?,
699      }))
700    }
701  }
702}