]> git.lizzy.rs Git - mt.git/blob - tocltcmds.go
Add high-level protocol (de)serialization
[mt.git] / tocltcmds.go
1 //go:generate ./cmdno.sh tocltcmds ToClt toClt uint16 Cmd newToCltCmd
2
3 package mt
4
5 import (
6         "crypto/sha1"
7         "fmt"
8         "image/color"
9         "io"
10         "math"
11 )
12
13 type ToCltCmd interface {
14         Cmd
15         toCltCmdNo() uint16
16 }
17
18 // ToCltHello is sent as a response to ToSrvInit.
19 // The client responds to ToCltHello by authenticating.
20 type ToCltHello struct {
21         SerializeVer uint8
22         Compression  CompressionModes
23         ProtoVer     uint16
24         AuthMethods
25         Username string
26 }
27
28 // ToCltAcceptAuth is sent after the client successfully authenticates.
29 // The client responds to ToCltAcceptAuth with ToSrvInit2.
30 type ToCltAcceptAuth struct {
31         // The client does the equivalent of
32         //      PlayerPos[1] -= 5
33         // before using PlayerPos.
34         PlayerPos Pos
35
36         MapSeed         uint64
37         SendInterval    float32
38         SudoAuthMethods AuthMethods
39 }
40
41 type ToCltAcceptSudoMode struct{}
42
43 type ToCltDenySudoMode struct{}
44
45 // ToCltDisco tells that the client that it has been disconnected by the server.
46 type ToCltDisco struct {
47         Reason DiscoReason
48         //mt:assert %s.Reason < maxDiscoReason
49
50         //mt:if dr := %s.Reason; dr == Custom || dr == Shutdown || dr == Crash
51         Custom string
52         //mt:end
53
54         //mt:if dr := %s.Reason; dr == Shutdown || dr == Crash
55         Reconnect bool
56         //mt:end
57 }
58
59 type DiscoReason uint8
60
61 const (
62         WrongPasswd DiscoReason = iota
63         UnexpectedData
64         SrvIsSingleplayer
65         UnsupportedVer
66         BadNameChars
67         BadName
68         TooManyClts
69         EmptyPasswd
70         AlreadyConnected
71         SrvErr
72         Custom
73         Shutdown
74         Crash
75         maxDiscoReason
76 )
77
78 func (cmd ToCltDisco) String() (msg string) {
79         switch cmd.Reason {
80         case WrongPasswd:
81                 return "wrong password"
82         case UnexpectedData:
83                 return "unexpected data"
84         case SrvIsSingleplayer:
85                 return "server is singleplayer"
86         case UnsupportedVer:
87                 return "unsupported client version"
88         case BadNameChars:
89                 return "disallowed character(s) in player name"
90         case BadName:
91                 return "disallowed player name"
92         case TooManyClts:
93                 return "too many clients"
94         case EmptyPasswd:
95                 return "empty password"
96         case AlreadyConnected:
97                 return "another client is already connected with the same name"
98         case SrvErr:
99                 return "server error"
100         case Custom:
101                 return cmd.Custom
102         case Shutdown:
103                 msg = "server shutdown"
104         case Crash:
105                 msg = "server crash"
106         default:
107                 msg = fmt.Sprintf("DiscoReason(%d)", cmd.Reason)
108         }
109
110         if cmd.Custom != "" {
111                 msg += ": " + cmd.Custom
112         }
113
114         return
115 }
116
117 // ToCltBlkData tells the client the contents of a nearby MapBlk.
118 type ToCltBlkData struct {
119         Blkpos [3]int16
120         Blk    MapBlk
121 }
122
123 // ToCltAddNode tells the client that a nearby node changed
124 // to something other than air.
125 type ToCltAddNode struct {
126         Pos [3]int16
127         Node
128         KeepMeta bool
129 }
130
131 // ToCltRemoveNode tells the client that a nearby node changed to air.
132 type ToCltRemoveNode struct {
133         Pos [3]int16
134 }
135
136 // ToCltInv updates the client's inventory.
137 type ToCltInv struct {
138         //mt:raw
139         Inv string
140 }
141
142 // ToCltTimeOfDay updates the client's in-game time of day.
143 type ToCltTimeOfDay struct {
144         Time  uint16  // %24000
145         Speed float32 // Speed times faster than real time
146 }
147
148 // ToCltCSMRestrictionFlags tells the client how use of CSMs should be restricted.
149 type ToCltCSMRestrictionFlags struct {
150         Flags CSMRestrictionFlags
151
152         // MapRange is the maximum distance from the player CSMs can read the map
153         // if Flags&LimitMapRange != 0.
154         MapRange uint32
155 }
156
157 type CSMRestrictionFlags uint64
158
159 const (
160         NoCSMs CSMRestrictionFlags = 1 << iota
161         NoChatMsgs
162         NoItemDefs
163         NoNodeDefs
164         LimitMapRange
165         NoPlayerList
166 )
167
168 // ToCltAddPlayerVel tells the client to add Vel to the player's velocity.
169 type ToCltAddPlayerVel struct {
170         Vel Vec
171 }
172
173 // ToCltMediaPush is sent when a media file is dynamically added.
174 type ToCltMediaPush struct {
175         //mt:const uint16(sha1.Size)
176         SHA1        [sha1.Size]byte
177         Filename    string
178         ShouldCache bool
179
180         //mt:len32
181         Data []byte
182 }
183
184 // ToCltChatMsg tells the client that is has received a chat message.
185 type ToCltChatMsg struct {
186         //mt:const uint8(1)
187
188         Type ChatMsgType
189
190         //mt:utf16
191         Sender, Text string
192
193         Timestamp int64 // Unix time.
194 }
195
196 type ChatMsgType uint8
197
198 const (
199         RawMsg ChatMsgType = iota
200         NormalMsg
201         AnnounceMsg
202         SysMsg
203         maxMsg
204 )
205
206 func (t ChatMsgType) String() string {
207         if t >= maxMsg {
208                 return fmt.Sprintf("ChatMsgType(%d)", t)
209         }
210
211         return [...]string{
212                 "raw",
213                 "normal",
214                 "announce",
215                 "sys",
216         }[t]
217 }
218
219 // ToCltAORmAdd tells the client that AOs have been removed from and/or added to
220 // the AOs that it can see.
221 type ToCltAORmAdd struct {
222         Remove []AOID
223         Add    []struct {
224                 ID AOID
225                 //mt:const genericCAO
226                 //mt:lenhdr 32
227                 InitData AOInitData
228                 //mt:end
229         }
230 }
231
232 // ToCltAOMsgs updates the client about nearby AOs.
233 type ToCltAOMsgs struct {
234         //mt:raw
235         Msgs []IDAOMsg
236 }
237
238 // ToCltHP updates the player's HP on the client.
239 type ToCltHP struct {
240         HP uint16
241 }
242
243 // ToCltMovePlayer tells the client that the player has been moved server-side.
244 type ToCltMovePlayer struct {
245         Pos
246         Pitch, Yaw float32
247 }
248
249 type ToCltDiscoLegacy struct {
250         //mt:utf16
251         Reason string
252 }
253
254 // ToCltFOV tells the client to change its FOV.
255 type ToCltFOV struct {
256         FOV            float32
257         Multiplier     bool
258         TransitionTime float32
259 }
260
261 // ToCltDeathScreen tells the client to show the death screen.
262 type ToCltDeathScreen struct {
263         PointCam bool
264         PointAt  Pos
265 }
266
267 // ToCltMedia responds to a ToSrvMedia packet with the requested media files.
268 type ToCltMedia struct {
269         // N is the total number of ToCltMedia packets.
270         // I is the index of this packet.
271         N, I uint16
272
273         //mt:len32
274         Files []struct {
275                 Name string
276
277                 //mt:len32
278                 Data []byte
279         }
280 }
281
282 // ToCltNodeDefs tells the client the definitions of nodes.
283 type ToCltNodeDefs struct {
284         //mt:lenhdr 32
285         //mt:zlib
286
287         // Version.
288         //mt:const uint8(1)
289
290         // See (de)serialize.fmt.
291         Defs []NodeDef
292
293         //mt:end
294         //mt:end
295 }
296
297 // ToCltAnnounceMedia tells the client what media is available on request.
298 // See ToSrvReqMedia.
299 type ToCltAnnounceMedia struct {
300         Files []struct {
301                 Name       string
302                 Base64SHA1 string
303         }
304         URL string
305 }
306
307 // ToCltItemDefs tells the client the definitions of items.
308 type ToCltItemDefs struct {
309         //mt:lenhdr 32
310         //mt:zlib
311
312         //mt:const uint8(0)
313
314         Defs    []ItemDef
315         Aliases []struct{ Alias, Orig string }
316
317         //mt:end
318         //mt:end
319 }
320
321 // ToCltPlaySound tells the client to play a sound.
322 type ToCltPlaySound struct {
323         ID      SoundID
324         Name    string
325         Gain    float32
326         SrcType SoundSrcType
327         Pos
328         SrcAOID   AOID
329         Loop      bool
330         Fade      float32
331         Pitch     float32
332         Ephemeral bool
333 }
334
335 // ToCltStopSound tells the client to stop playing a sound.
336 type ToCltStopSound struct {
337         ID SoundID
338 }
339
340 // ToCltPrivs tells the client its privs.
341 type ToCltPrivs struct {
342         Privs []string
343 }
344
345 // ToCltInvFormspec tells the client its inventory formspec.
346 type ToCltInvFormspec struct {
347         //mt:len32
348         Formspec string
349 }
350
351 // ToCltDetachedInv updates a detached inventory on the client.
352 type ToCltDetachedInv struct {
353         Name string
354         Keep bool
355         Len  uint16 // deprecated
356
357         //mt:raw
358         Inv string
359 }
360
361 // ToCltShowFormspec tells the client to show a formspec.
362 type ToCltShowFormspec struct {
363         //mt:len32
364         Formspec string
365
366         Formname string
367 }
368
369 // ToCltMovement tells the client how to move.
370 type ToCltMovement struct {
371         DefaultAccel, AirAccel, FastAccel,
372         WalkSpeed, CrouchSpeed, FastSpeed, ClimbSpeed, JumpSpeed,
373         Fluidity, Smoothing, Sink, // liquids
374         Gravity float32
375 }
376
377 // ToCltSpawnParticle tells the client to spawn a particle.
378 type ToCltSpawnParticle struct {
379         Pos, Vel, Acc  [3]float32
380         ExpirationTime float32 // in seconds.
381         Size           float32
382         Collide        bool
383
384         //mt:len32
385         Texture
386
387         Vertical    bool
388         CollisionRm bool
389         AnimParams  TileAnim
390         Glow        uint8
391         AOCollision bool
392         NodeParam0  Content
393         NodeParam2  uint8
394         NodeTile    uint8
395 }
396
397 type ParticleSpawnerID uint32
398
399 // ToCltAddParticleSpawner tells the client to add a particle spawner.
400 type ToCltAddParticleSpawner struct {
401         Amount         uint16
402         Duration       float32
403         Pos, Vel, Acc  [2][3]float32
404         ExpirationTime [2]float32 // in seconds.
405         Size           [2]float32
406         Collide        bool
407
408         //mt:len32
409         Texture
410
411         ID           ParticleSpawnerID
412         Vertical     bool
413         CollisionRm  bool
414         AttachedAOID AOID
415         AnimParams   TileAnim
416         Glow         uint8
417         AOCollision  bool
418         NodeParam0   Content
419         NodeParam2   uint8
420         NodeTile     uint8
421 }
422
423 type HUDID uint32
424
425 // ToCltHUDAdd tells the client to add a HUD.
426 type ToCltAddHUD struct {
427         ID HUDID
428
429         Type HUDType
430
431         Pos      [2]float32
432         Name     string
433         Scale    [2]float32
434         Text     string
435         Number   uint32
436         Item     uint32
437         Dir      uint32
438         Align    [2]float32
439         Offset   [2]float32
440         WorldPos Pos
441         Size     [2]int32
442         ZIndex   int16
443         Text2    string
444 }
445
446 type HUDType uint8
447
448 const (
449         ImgHUD HUDType = iota
450         TextHUD
451         StatbarHUD
452         InvHUD
453         WaypointHUD
454         ImgWaypointHUD
455 )
456
457 // ToCltRmHUD tells the client to remove a HUD.
458 type ToCltRmHUD struct {
459         ID HUDID
460 }
461
462 // ToCltChangeHUD tells the client to change a field in a HUD.
463 type ToCltChangeHUD struct {
464         ID HUDID
465
466         Field HUDField
467
468         //mt:assert %s.Field < hudMax
469
470         //mt:if %s.Field == HUDPos
471         Pos [2]float32
472         //mt:end
473
474         //mt:if %s.Field == HUDName
475         Name string
476         //mt:end
477
478         //mt:if %s.Field == HUDScale
479         Scale [2]float32
480         //mt:end
481
482         //mt:if %s.Field == HUDText
483         Text string
484         //mt:end
485
486         //mt:if %s.Field == HUDNumber
487         Number uint32
488         //mt:end
489
490         //mt:if %s.Field == HUDItem
491         Item uint32
492         //mt:end
493
494         //mt:if %s.Field == HUDDir
495         Dir uint32
496         //mt:end
497
498         //mt:if %s.Field == HUDAlign
499         Align [2]float32
500         //mt:end
501
502         //mt:if %s.Field == HUDOffset
503         Offset [2]float32
504         //mt:end
505
506         //mt:if %s.Field == HUDWorldPos
507         WorldPos Pos
508         //mt:end
509
510         //mt:if %s.Field == HUDSize
511         Size [2]int32
512         //mt:end
513
514         //mt:if %s.Field == HUDZIndex
515         ZIndex uint32
516         //mt:end
517
518         //mt:if %s.Field == HUDText2
519         Text2 string
520         //mt:end
521 }
522
523 type HUDField uint8
524
525 const (
526         HUDPos HUDField = iota
527         HUDName
528         HUDScale
529         HUDText
530         HUDNumber
531         HUDItem
532         HUDDir
533         HUDAlign
534         HUDOffset
535         HUDWorldPos
536         HUDSize
537         HUDZIndex
538         HUDText2
539         hudMax
540 )
541
542 // ToCltHUDFlags tells the client to update its HUD flags.
543 type ToCltHUDFlags struct {
544         // &^= Mask
545         // |= Flags
546         Flags, Mask HUDFlags
547 }
548
549 type HUDFlags uint32
550
551 const (
552         ShowHotbar HUDFlags = 1 << iota
553         ShowHealthBar
554         ShowCrosshair
555         ShowWieldedItem
556         ShowBreathBar
557         ShowMinimap
558         ShowRadarMinimap
559 )
560
561 // ToCltSetHotbarParam tells the client to set a hotbar parameter.
562 type ToCltSetHotbarParam struct {
563         Param HotbarParam
564
565         //mt:if %s.Param == HotbarSize
566         //mt:const uint16(4) // Size of Size field.
567         Size int32
568         //mt:end
569
570         //mt:if %s.Param != HotbarSize
571         Img Texture
572         //mt:end
573 }
574
575 type HotbarParam uint16
576
577 const (
578         HotbarSize HotbarParam = 1 + iota
579         HotbarImg
580         HotbarSelImg
581 )
582
583 // ToCltBreath tells the client how much breath it has.
584 type ToCltBreath struct {
585         Breath uint16
586 }
587
588 // ToCltSkyParams tells the client how to render the sky.
589 type ToCltSkyParams struct {
590         BgColor     color.NRGBA
591         Type        string
592         Clouds      bool
593         SunFogTint  color.NRGBA
594         MoonFogTint color.NRGBA
595         FogTintType string
596
597         //mt:if %s.Type == "skybox"
598         Textures []Texture
599         //mt:end
600
601         //mt:if %s.Type == "regular"
602         DaySky, DayHorizon,
603         DawnSky, DawnHorizon,
604         NightSky, NightHorizon,
605         Indoor color.NRGBA
606         //mt:end
607 }
608
609 // ToCltOverrideDayNightRatio overrides the client's day-night ratio
610 type ToCltOverrideDayNightRatio struct {
611         Override bool
612         Ratio    uint16
613 }
614
615 // ToCltLocalPlayerAnim tells the client how to animate the player.
616 type ToCltLocalPlayerAnim struct {
617         Idle, Walk, Dig, WalkDig [2]int32
618         Speed                    float32
619 }
620
621 // ToCltEyeOffset tells the client where to position the camera
622 // relative to the player.
623 type ToCltEyeOffset struct {
624         First, Third Vec
625 }
626
627 // ToCltDelParticleSpawner tells the client to delete a particle spawner.
628 type ToCltDelParticleSpawner struct {
629         ID ParticleSpawnerID
630 }
631
632 // ToCltCloudParams tells the client how to render the clouds.
633 type ToCltCloudParams struct {
634         Density      float32
635         DiffuseColor color.NRGBA
636         AmbientColor color.NRGBA
637         Height       float32
638         Thickness    float32
639         Speed        [2]float32
640 }
641
642 // ToCltFadeSound tells the client to fade a sound.
643 type ToCltFadeSound struct {
644         ID   SoundID
645         Step float32
646         Gain float32
647 }
648
649 // ToCltUpdatePlayerList informs the client of players leaving or joining.
650 type ToCltUpdatePlayerList struct {
651         Type    PlayerListUpdateType
652         Players []string
653 }
654
655 type PlayerListUpdateType uint8
656
657 const (
658         InitPlayers PlayerListUpdateType = iota
659         AddPlayers
660         RemovePlayers
661 )
662
663 // ToCltModChanMsg tells the client it has been sent a message on a mod channel.
664 type ToCltModChanMsg struct {
665         Channel string
666         Sender  string
667         Msg     string
668 }
669
670 // ToCltModChanMsg tells the client it has received a signal on a mod channel.
671 type ToCltModChanSig struct {
672         Signal  ModChanSig
673         Channel string
674 }
675
676 type ModChanSig uint8
677
678 const (
679         JoinOK ModChanSig = iota
680         JoinFail
681         LeaveOK
682         LeaveFail
683         NotRegistered
684         SetState
685 )
686
687 // ToCltModChanMsg is sent when node metadata near the client changes.
688 type ToCltNodeMetasChanged struct {
689         //mt:lenhdr 32
690         Changed map[[3]int16]*NodeMeta
691         //mt:end
692 }
693
694 // ToCltSunParams tells the client how to render the sun.
695 type ToCltSunParams struct {
696         Visible bool
697         Texture
698         ToneMap Texture
699         Rise    Texture
700         Rising  bool
701         Size    float32
702 }
703
704 // ToCltMoonParams tells the client how to render the moon.
705 type ToCltMoonParams struct {
706         Visible bool
707         Texture
708         ToneMap Texture
709         Size    float32
710 }
711
712 // ToCltStarParams tells the client how to render the stars.
713 type ToCltStarParams struct {
714         Visible bool
715         Count   uint32
716         Color   color.NRGBA
717         Size    float32
718 }
719
720 type ToCltSRPBytesSaltB struct {
721         Salt, B []byte
722 }
723
724 // ToCltFormspecPrepend tells the client to prepend a string to all formspecs.
725 type ToCltFormspecPrepend struct {
726         Prepend string
727 }
728
729 // ToCltMinimapModes tells the client the set of available minimap modes.
730 type ToCltMinimapModes struct {
731         Current uint16
732         Modes   []MinimapMode
733 }
734
735 func (cmd *ToCltMinimapModes) serialize(w io.Writer) error {
736         buf := make([]byte, 4)
737         if len(cmd.Modes) > math.MaxUint16 {
738                 return ErrTooLong
739         }
740         be.PutUint16(buf[0:2], uint16(len(cmd.Modes)))
741         be.PutUint16(buf[2:4], cmd.Current)
742         if _, err := w.Write(buf); err != nil {
743                 return err
744         }
745         for i := range cmd.Modes {
746                 if err := serialize(w, &cmd.Modes[i]); err != nil {
747                         return err
748                 }
749         }
750         return nil
751 }
752
753 func (cmd *ToCltMinimapModes) deserialize(r io.Reader) error {
754         buf := make([]byte, 4)
755         if _, err := io.ReadFull(r, buf); err != nil {
756                 return err
757         }
758         cmd.Modes = make([]MinimapMode, be.Uint16(buf[0:2]))
759         cmd.Current = be.Uint16(buf[2:4])
760         for i := range cmd.Modes {
761                 if err := deserialize(r, &cmd.Modes[i]); err != nil {
762                         return err
763                 }
764         }
765         return nil
766 }