]> git.r.bdr.sh - rbdr/mobius/commitdiff
Add support for server banner
authorJeff Halter <redacted>
Tue, 21 Jun 2022 23:10:19 +0000 (16:10 -0700)
committerJeff Halter <redacted>
Tue, 21 Jun 2022 23:10:19 +0000 (16:10 -0700)
cmd/mobius-hotline-server/mobius/config/config.yaml
hotline/config.go
hotline/field.go
hotline/file_transfer.go
hotline/server.go
hotline/transaction.go
hotline/transaction_handlers.go
hotline/transfer.go

index 50c3fa35341570fca9fe6ad24f8127707d04e82b..a903023f587a442dd3c694e747efafc44eee2ffb 100644 (file)
@@ -4,8 +4,12 @@ Name: My Hotline server
 # Description of the server as it appears on the tracker
 Description: A default configured Hotline server running Mobius
 
-# Server banner ID; currently implemented
-BannerID: 0
+# Path to server banner image.  Only known to work in the 1.8 clients.
+#  * The banner must be under 256K (262,140 bytes specifically)
+#  * The standard size for a banner is 468 pixels wide and 60 pixels tall.
+#  * The banner must be saved in the same folder this file.
+#  * The banner must be a jpg
+BannerFile: "banner.jpg"
 
 # Path to the Files directory, by default in a subdirectory of the config root named Files
 FileRoot: Files
index 55d68e9ad3db153fdf6c9c50a176d34c220c6578..d6d801e92a9956edcdf9b16e1b65d917103b5751 100644 (file)
@@ -3,7 +3,7 @@ package hotline
 type Config struct {
        Name                      string   `yaml:"Name" validate:"required,max=50"`         // Name used for Tracker registration
        Description               string   `yaml:"Description" validate:"required,max=200"` // Description used for Tracker registration
-       BannerID                  int      `yaml:"BannerID"`                                // Unimplemented
+       BannerFile                string   `yaml:"BannerFile"`                              // Path to banner jpg
        FileRoot                  string   `yaml:"FileRoot" validate:"required"`            // Path to Files
        EnableTrackerRegistration bool     `yaml:"EnableTrackerRegistration"`               // Toggle Tracker Registration
        Trackers                  []string `yaml:"Trackers" validate:"dive,hostname_port"`  // List of trackers that the server should register with
index 2be4c4a7b96faff1f74f3f47782096eb69c8fa06..aef790d171351e3c78ce8e362a01166e4a3beb74 100644 (file)
@@ -23,6 +23,7 @@ const fieldOptions = 113
 const fieldChatID = 114
 const fieldChatSubject = 115
 const fieldWaitingCount = 116
+const fieldBannerType = 152
 const fieldVersion = 160
 const fieldCommunityBannerID = 161
 const fieldServerName = 162
index 90dbbe669a2c9391afbb481f81f5c27bcded0eaa..c7c1a62456e4c73162d99bbfdc8b4a2d4246ab43 100644 (file)
@@ -12,6 +12,7 @@ const (
        FileUpload     = 1
        FolderDownload = 2
        FolderUpload   = 3
+       bannerDownload = 4
 )
 
 type FileTransfer struct {
index 11ec21d1b9625501cb72e6d9e2d9b5458fe813aa..21b1316d4f233b0e36ae11e6d12b928e9d0f0bc6 100644 (file)
@@ -591,7 +591,7 @@ func (s *Server) handleNewConnection(ctx context.Context, conn io.ReadWriteClose
 
        s.outbox <- c.NewReply(clientLogin,
                NewField(fieldVersion, []byte{0x00, 0xbe}),
-               NewField(fieldCommunityBannerID, []byte{0x00, 0x01}),
+               NewField(fieldCommunityBannerID, []byte{0, 0}),
                NewField(fieldServerName, []byte(s.Config.Name)),
        )
 
@@ -716,6 +716,10 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
        )
 
        switch fileTransfer.Type {
+       case bannerDownload:
+               if err := s.bannerDownload(rwc); err != nil {
+                       return err
+               }
        case FileDownload:
                s.Stats.DownloadCounter += 1
 
index 077e6f3050f0a75942bbac83f25921df87831943..ece2924da5969f6441ba1bb75188f7c6504d6f9f 100644 (file)
@@ -31,6 +31,7 @@ const (
        tranNotifyChatSubject    = 119
        tranSetChatSubject       = 120
        tranAgreed               = 121
+       tranServerBanner         = 122
        tranGetFileNameList      = 200
        tranDownloadFile         = 202
        tranUploadFile           = 203
@@ -42,7 +43,7 @@ const (
        tranMakeFileAlias        = 209
        tranDownloadFldr         = 210
        // tranDownloadInfo         = 211 TODO: implement file transfer queue
-       // tranDownloadBanner     = 212 TODO: figure out what this is used for
+       tranDownloadBanner     = 212
        tranUploadFldr         = 213
        tranGetUserNameList    = 300
        tranNotifyChangeUser   = 301
index cad33700d26d52730342534d01170da9c98b342a..9f07fe1860d014a3d21a8b48ac0f96e6a1d5422d 100644 (file)
@@ -231,6 +231,10 @@ var TransactionHandlers = map[uint16]TransactionType{
                Name:    "tranUserBroadcast",
                Handler: HandleUserBroadcast,
        },
+       tranDownloadBanner: {
+               Name:    "tranDownloadBanner",
+               Handler: HandleDownloadBanner,
+       },
 }
 
 func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
@@ -976,6 +980,10 @@ func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err er
                cc.Server.outbox <- t
        }
 
+       if cc.Server.Config.BannerFile != "" {
+               cc.Server.outbox <- *NewTransaction(tranServerBanner, cc.ID, NewField(fieldBannerType, []byte("JPEG")))
+       }
+
        res = append(res, cc.NewReply(t))
 
        return res, err
@@ -1927,3 +1935,33 @@ func HandleMakeAlias(cc *ClientConn, t *Transaction) (res []Transaction, err err
        res = append(res, cc.NewReply(t))
        return res, err
 }
+
+func HandleDownloadBanner(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
+       transactionRef := cc.Server.NewTransactionRef()
+       data := binary.BigEndian.Uint32(transactionRef)
+
+       ft := &FileTransfer{
+               ReferenceNumber: transactionRef,
+               Type:            bannerDownload,
+       }
+
+       fi, err := cc.Server.FS.Stat(filepath.Join(cc.Server.ConfigDir, cc.Server.Config.BannerFile))
+       if err != nil {
+               return res, err
+       }
+
+       size := make([]byte, 4)
+       binary.BigEndian.PutUint32(size, uint32(fi.Size()))
+
+       cc.Server.mux.Lock()
+       defer cc.Server.mux.Unlock()
+       cc.Server.FileTransfers[data] = ft
+
+       res = append(res, cc.NewReply(t,
+               NewField(fieldRefNum, transactionRef),
+               NewField(fieldTransferSize, size),
+       ))
+
+       res = append(res, cc.NewReply(t))
+       return res, err
+}
index 73331970e33648900b0642de8754a234da933f0f..9d2a97f732afc80bcad3997f6f88023d0256c114 100644 (file)
@@ -6,6 +6,8 @@ import (
        "encoding/binary"
        "errors"
        "io"
+       "os"
+       "path/filepath"
 )
 
 type transfer struct {
@@ -96,5 +98,14 @@ func sendFile(w io.Writer, r io.Reader, offset int) (err error) {
                        return err
                }
        }
+}
+
+func (s *Server) bannerDownload(w io.Writer) error {
+       bannerBytes, err := os.ReadFile(filepath.Join(s.ConfigDir, s.Config.BannerFile))
+       if err != nil {
+               return err
+       }
+       _, err = w.Write(bannerBytes)
 
+       return err
 }