X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/a251acd43adcd88388a00b7ebd7d8df0486adeba..c3c2f61b2fd90ab5c7fe6ec769644e9d66d40361:/hotline/server.go diff --git a/hotline/server.go b/hotline/server.go index b17102e..9e5f498 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -567,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 @@ -664,21 +687,28 @@ 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 - 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 }())) - - for _, t := range c.notifyOthers( - *NewTransaction( - tranNotifyChangeUser, nil, - NewField(fieldUserName, c.UserName), - NewField(fieldUserID, *c.ID), - NewField(fieldUserIconID, c.Icon), - NewField(fieldUserFlags, c.Flags), - ), - ) { - c.Server.outbox <- t + // 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", "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, + NewField(fieldUserName, c.UserName), + NewField(fieldUserID, *c.ID), + NewField(fieldUserIconID, c.Icon), + NewField(fieldUserFlags, c.Flags), + ), + ) { + c.Server.outbox <- t + } } c.Server.Stats.ConnectionCounter += 1