]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/server.go
Improve Frogblast client compatibility
[rbdr/mobius] / hotline / server.go
index 06a0695771d5e8fdfac7b717f366b240a82f54d7..8d6803b274f411c3a0b1eb4d360a9f9daeccd8b3 100644 (file)
@@ -33,13 +33,8 @@ type requestCtx struct {
        name       string
 }
 
-const (
-       userIdleSeconds        = 300 // time in seconds before an inactive user is marked idle
-       idleCheckInterval      = 10  // time in seconds to check for idle users
-       trackerUpdateFrequency = 300 // time in seconds between tracker re-registration
-)
-
 var nostalgiaVersion = []byte{0, 0, 2, 0x2c} // version ID used by the Nostalgia client
+var frogblastVersion = []byte{0, 0, 0, 0xb9} // version ID used by the Frogblast 1.2.4 client
 
 type Server struct {
        Port          int
@@ -57,7 +52,9 @@ type Server struct {
 
        NextGuestID   *uint16
        TrackerPassID [4]byte
-       Stats         *Stats
+
+       StatsMu sync.Mutex
+       Stats   *Stats
 
        FS FileStore // Storage backend to use for File storage
 
@@ -74,6 +71,16 @@ type Server struct {
        banList   map[string]*time.Time
 }
 
+func (s *Server) CurrentStats() Stats {
+       s.StatsMu.Lock()
+       defer s.StatsMu.Unlock()
+
+       stats := s.Stats
+       stats.CurrentlyConnected = len(s.Clients)
+
+       return *stats
+}
+
 type PrivateChat struct {
        Subject    string
        ClientConn map[uint16]*ClientConn
@@ -219,7 +226,7 @@ func NewServer(configDir string, netPort int, logger *zap.SugaredLogger, FS File
                Logger:        logger,
                NextGuestID:   new(uint16),
                outbox:        make(chan Transaction),
-               Stats:         &Stats{StartTime: time.Now()},
+               Stats:         &Stats{Since: time.Now()},
                ThreadedNews:  &ThreadedNews{},
                FS:            FS,
                banList:       make(map[string]*time.Time),
@@ -661,7 +668,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
        }
 
        // Used simplified hotline v1.2.3 login flow for clients that do not send login info in tranAgreed
-       if c.Version == nil || bytes.Equal(c.Version, nostalgiaVersion) {
+       if c.Version == nil || bytes.Equal(c.Version, nostalgiaVersion) || bytes.Equal(c.Version, frogblastVersion) {
                c.Agreed = true
                c.logger = c.logger.With("name", string(c.UserName))
                c.logger.Infow("Login successful", "clientVersion", fmt.Sprintf("%v", func() int { i, _ := byteToInt(c.Version); return i }()))
@@ -679,7 +686,10 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                }
        }
 
-       c.Server.Stats.LoginCount += 1
+       c.Server.Stats.ConnectionCounter += 1
+       if len(s.Clients) > c.Server.Stats.ConnectionPeak {
+               c.Server.Stats.ConnectionPeak = len(s.Clients)
+       }
 
        // Scan for new transactions and handle them as they come in.
        for scanner.Scan() {
@@ -772,6 +782,8 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                }
        case FileDownload:
                s.Stats.DownloadCounter += 1
+               s.Stats.DownloadsInProgress += 1
+               defer func() { s.Stats.DownloadsInProgress -= 1 }()
 
                var dataOffset int64
                if fileTransfer.fileResumeData != nil {
@@ -826,6 +838,8 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
 
        case FileUpload:
                s.Stats.UploadCounter += 1
+               s.Stats.UploadsInProgress += 1
+               defer func() { s.Stats.UploadsInProgress -= 1 }()
 
                var file *os.File
 
@@ -882,7 +896,12 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                }
 
                rLogger.Infow("File upload complete", "dstFile", fullPath)
+
        case FolderDownload:
+               s.Stats.DownloadCounter += 1
+               s.Stats.DownloadsInProgress += 1
+               defer func() { s.Stats.DownloadsInProgress -= 1 }()
+
                // Folder Download flow:
                // 1. Get filePath from the transfer
                // 2. Iterate over files
@@ -1046,6 +1065,9 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                }
 
        case FolderUpload:
+               s.Stats.UploadCounter += 1
+               s.Stats.UploadsInProgress += 1
+               defer func() { s.Stats.UploadsInProgress -= 1 }()
                rLogger.Infow(
                        "Folder upload started",
                        "dstPath", fullPath,