X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/d8aeb2dea5395514ad49c6271bc7d62e201f371b..e9c043c0361e0e56e9b9adfea894c7834a99bade:/hotline/server.go?ds=sidebyside diff --git a/hotline/server.go b/hotline/server.go index bda0c2a..9e5f498 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -2,7 +2,6 @@ package hotline import ( "bufio" - "bytes" "context" "encoding/binary" "errors" @@ -33,11 +32,6 @@ type requestCtx struct { name string } -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 - -var obsessionVersion = []byte{0xbe, 0x00} // version ID used by the Obsession client - type Server struct { Port int Accounts map[string]*Account @@ -383,7 +377,6 @@ func (s *Server) NewClientConn(conn io.ReadWriteCloser, remoteAddr string) *Clie Version: []byte{}, AutoReply: []byte{}, transfers: map[int]map[[4]byte]*FileTransfer{}, - Agreed: false, RemoteAddr: remoteAddr, } clientConn.transfers = map[int]map[[4]byte]*FileTransfer{ @@ -470,9 +463,6 @@ func (s *Server) connectedUsers() []Field { var connectedUsers []Field for _, c := range sortedClients(s.Clients) { - if !c.Agreed { - continue - } user := User{ ID: *c.ID, Icon: c.Icon, @@ -577,32 +567,55 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser return err } - c := s.NewClientConn(rwc, remoteAddr) - // check if remoteAddr is present in the ban list if banUntil, ok := s.banList[strings.Split(remoteAddr, ":")[0]]; ok { // permaban if banUntil == nil { - s.outbox <- *NewTransaction( + t := NewTransaction( tranServerMsg, - c.ID, + &[]byte{0, 0}, NewField(fieldData, []byte("You are permanently banned on this server")), NewField(fieldChatOptions, []byte{0, 0}), ) + + b, err := t.MarshalBinary() + if err != nil { + return err + } + + _, err = rwc.Write(b) + if err != nil { + return err + } + time.Sleep(1 * time.Second) return nil - } else if time.Now().Before(*banUntil) { - s.outbox <- *NewTransaction( + } + + // temporary ban + if time.Now().Before(*banUntil) { + t := NewTransaction( tranServerMsg, - c.ID, + &[]byte{0, 0}, NewField(fieldData, []byte("You are temporarily banned on this server")), NewField(fieldChatOptions, []byte{0, 0}), ) + b, err := t.MarshalBinary() + if err != nil { + return err + } + + _, err = rwc.Write(b) + if err != nil { + return err + } + time.Sleep(1 * time.Second) return nil } - } + + c := s.NewClientConn(rwc, remoteAddr) defer c.Disconnect() encodedLogin := clientLogin.GetField(fieldUserLogin).Data @@ -674,13 +687,17 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser c.Server.outbox <- *NewTransaction(tranShowAgreement, c.ID, NewField(fieldData, s.Agreement)) } - // Used simplified hotline v1.2.3 login flow for clients that do not send login info in tranAgreed - // TODO: figure out a generalized solution that doesn't require playing whack-a-mole for specific client versions - if c.Version == nil || bytes.Equal(c.Version, nostalgiaVersion) || bytes.Equal(c.Version, frogblastVersion) || bytes.Equal(c.Version, obsessionVersion) { - c.Agreed = true + // If the client has provided a username as part of the login, we can infer that it is using the 1.2.3 login + // flow and not the 1.5+ flow. + if len(c.UserName) != 0 { + // Add the client username to the logger. For 1.5+ clients, we don't have this information yet as it comes as + // part of tranAgreed 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 }())) + c.logger.Infow("Login successful", "clientVersion", "Not sent (probably 1.2.3)") + + // Notify other clients on the server that the new user has logged in. For 1.5+ clients we don't have this + // information yet, so we do it in tranAgreed instead for _, t := range c.notifyOthers( *NewTransaction( tranNotifyChangeUser, nil,