1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-07 06:40:54 +00:00

Implement version comparisons

This commit is contained in:
Kane York 2015-11-16 14:30:09 -08:00
parent d3fa1e6894
commit 71f08f3c53
3 changed files with 59 additions and 7 deletions

View file

@ -84,6 +84,8 @@ func callHandler(handler CommandHandler, conn *websocket.Conn, client *ClientInf
return handler(conn, client, cmsg) return handler(conn, client, cmsg)
} }
var lastVersionWithoutReplyWithServerTime = VersionFromString("ffz_3.5.78")
// C2SHello implements the `hello` C2S Command. // C2SHello implements the `hello` C2S Command.
// It calls SubscribeGlobal() and SubscribeDefaults() with the client, and fills out ClientInfo.Version and ClientInfo.ClientID. // It calls SubscribeGlobal() and SubscribeDefaults() with the client, and fills out ClientInfo.Version and ClientInfo.ClientID.
func C2SHello(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg ClientMessage, err error) { func C2SHello(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg ClientMessage, err error) {
@ -92,7 +94,9 @@ func C2SHello(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg
return return
} }
client.Version = version client.VersionString = version
client.Version = VersionFromString(version)
client.ClientID = uuid.FromStringOrNil(clientID) client.ClientID = uuid.FromStringOrNil(clientID)
if client.ClientID == uuid.Nil { if client.ClientID == uuid.Nil {
client.ClientID = uuid.NewV4() client.ClientID = uuid.NewV4()
@ -101,9 +105,18 @@ func C2SHello(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg
SubscribeGlobal(client) SubscribeGlobal(client)
SubscribeDefaults(client) SubscribeDefaults(client)
return ClientMessage{ if client.Version.After(lastVersionWithoutReplyWithServerTime) {
Arguments: client.ClientID.String(), return ClientMessage{
}, nil Arguments: []interface{}{
client.ClientID.String(),
time.Now().Unix(),
},
}
} else {
return ClientMessage{
Arguments: client.ClientID.String(),
}, nil
}
} }
func C2SReady(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg ClientMessage, err error) { func C2SReady(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg ClientMessage, err error) {

View file

@ -261,7 +261,7 @@ RunLoop:
break RunLoop break RunLoop
case msg := <-clientChan: case msg := <-clientChan:
if client.Version == "" && msg.Command != HelloCommand { if client.VersionString == "" && msg.Command != HelloCommand {
CloseConnection(conn, &CloseFirstMessageNotHello) CloseConnection(conn, &CloseFirstMessageNotHello)
Statistics.FirstNotHelloDisconnects++ Statistics.FirstNotHelloDisconnects++
break RunLoop break RunLoop

View file

@ -6,6 +6,7 @@ import (
"net" "net"
"sync" "sync"
"time" "time"
"fmt"
) )
const CryptoBoxKeyLength = 32 const CryptoBoxKeyLength = 32
@ -55,14 +56,22 @@ type AuthInfo struct {
UsernameValidated bool UsernameValidated bool
} }
type ClientVersion struct {
Major int
Minor int
Revision int
}
type ClientInfo struct { type ClientInfo struct {
// The client ID. // The client ID.
// This must be written once by the owning goroutine before the struct is passed off to any other goroutines. // This must be written once by the owning goroutine before the struct is passed off to any other goroutines.
ClientID uuid.UUID ClientID uuid.UUID
// The client's version. // The client's literal version string.
// This must be written once by the owning goroutine before the struct is passed off to any other goroutines. // This must be written once by the owning goroutine before the struct is passed off to any other goroutines.
Version string VersionString string
Version ClientVersion
// This mutex protects writable data in this struct. // This mutex protects writable data in this struct.
// If it seems to be a performance problem, we can split this. // If it seems to be a performance problem, we can split this.
@ -103,6 +112,36 @@ type ClientInfo struct {
pingCount int pingCount int
} }
func VersionFromString(v string) ClientVersion {
var cv ClientVersion
fmt.Sscanf(v, "ffz_%d.%d.%d", &cv.Major, &cv.Minor, &cv.Revision)
return cv
}
func (cv *ClientVersion) After(cv2 *ClientVersion) bool {
if cv.Major > cv2.Major {
return true
} else if cv.Major < cv2.Major {
return false
}
if cv.Minor > cv2.Minor {
return true
} else if cv.Minor < cv2.Minor {
return false
}
if cv.Revision > cv2.Revision {
return true
} else if cv.Revision < cv2.Revision {
return false
}
return false // equal
}
func (cv *ClientVersion) Equal(cv2 *ClientVersion) bool {
return cv.Major == cv2.Major && cv.Minor == cv2.Minor && cv.Revision == cv2.Revision
}
const usePendingSubscrptionsBacklog = false const usePendingSubscrptionsBacklog = false
type tgmarray []TimestampedGlobalMessage type tgmarray []TimestampedGlobalMessage