1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
FrankerFaceZ/socketserver/server/types.go

267 lines
6.4 KiB
Go
Raw Normal View History

package server
import (
"encoding/json"
2015-11-16 20:35:03 -08:00
"fmt"
"github.com/satori/go.uuid"
2015-11-01 13:17:35 -08:00
"net"
"sync"
2015-10-25 03:21:50 -07:00
"time"
)
const NegativeOne = ^uint64(0)
type ConfigFile struct {
// Numeric server id known to the backend
2015-12-02 19:08:19 -08:00
ServerID int
2016-01-15 20:59:33 -08:00
// Address to bind the HTTP server to on startup.
2015-12-02 19:08:19 -08:00
ListenAddr string
2016-01-15 20:59:33 -08:00
// Address to bind the TLS server to on startup.
SSLListenAddr string
// URL to the backend server
2015-11-15 18:43:34 -08:00
BackendURL string
2015-11-17 11:01:42 -08:00
// Minimum memory to accept a new connection
2015-11-17 11:11:14 -08:00
MinMemoryKBytes uint64
2016-01-15 20:59:33 -08:00
// Maximum # of clients that can be connected. 0 to disable.
MaxClientCount uint64
2015-11-17 11:01:42 -08:00
// SSL/TLS
2016-01-15 20:59:33 -08:00
// Enable the use of SSL.
UseSSL bool
2016-01-15 20:59:33 -08:00
// Path to certificate file.
SSLCertificateFile string
2016-01-15 20:59:33 -08:00
// Path to key file.
SSLKeyFile string
2015-12-16 11:48:37 -08:00
UseESLogStashing bool
2015-11-17 19:53:58 -08:00
ESServer string
ESIndexPrefix string
ESHostName string
// Nacl keys
OurPrivateKey []byte
OurPublicKey []byte
BackendPublicKey []byte
2015-11-08 16:44:16 -08:00
2016-01-15 20:59:33 -08:00
// Request username validation from all new clients.
2015-11-08 16:44:16 -08:00
SendAuthToNewClients bool
2015-10-25 12:40:07 -07:00
}
type ClientMessage struct {
// Message ID. Increments by 1 for each message sent from the client.
// When replying to a command, the message ID must be echoed.
// When sending a server-initiated message, this is -1.
2015-11-05 23:24:35 -08:00
MessageID int `json:"m"`
// The command that the client wants from the server.
// When sent from the server, the literal string 'True' indicates success.
// Before sending, a blank Command will be converted into SuccessCommand.
2015-11-05 23:24:35 -08:00
Command Command `json:"c"`
// Result of json.Unmarshal on the third field send from the client
2015-11-05 23:24:35 -08:00
Arguments interface{} `json:"a"`
origArguments string
}
type AuthInfo struct {
// The client's claimed username on Twitch.
TwitchUsername string
// Whether or not the server has validated the client's claimed username.
UsernameValidated bool
}
2015-11-16 14:30:09 -08:00
type ClientVersion struct {
2015-11-16 20:35:03 -08:00
Major int
Minor int
2015-11-16 14:30:09 -08:00
Revision int
}
type ClientInfo struct {
// The client ID.
// This must be written once by the owning goroutine before the struct is passed off to any other goroutines.
ClientID uuid.UUID
2015-11-16 14:30:09 -08:00
// 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.
2015-11-16 14:30:09 -08:00
VersionString string
Version ClientVersion
// This mutex protects writable data in this struct.
// If it seems to be a performance problem, we can split this.
Mutex sync.Mutex
2016-01-17 18:01:21 -08:00
// Info about the client's username and whether or not we have verified it.
AuthInfo
2015-11-01 13:17:35 -08:00
RemoteAddr net.Addr
// Username validation nonce.
ValidationNonce string
// The list of chats this client is currently in.
2015-10-25 03:21:50 -07:00
// Protected by Mutex.
CurrentChannels []string
2015-10-25 03:21:50 -07:00
// List of channels that we have not yet checked current chat-related channel info for.
// This lets us batch the backlog requests.
// Protected by Mutex.
PendingSubscriptionsBacklog []string
2015-10-25 03:21:50 -07:00
// A timer that, when fired, will make the pending backlog requests.
// Usually nil. Protected by Mutex.
MakePendingRequests *time.Timer
// Server-initiated messages should be sent here
// This field will be nil before it is closed.
MessageChannel chan<- ClientMessage
2015-10-28 22:59:27 -07:00
2015-11-03 16:44:42 -08:00
MsgChannelIsDone <-chan struct{}
// Take out an Add() on this during a command if you need to use the MessageChannel later.
MsgChannelKeepalive sync.WaitGroup
2015-11-16 12:50:00 -08:00
// The number of pings sent without a response.
// Protected by Mutex
2015-10-28 22:59:27 -07:00
pingCount int
}
2015-11-16 14:30:09 -08:00
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
}
2015-11-16 12:50:00 -08:00
const usePendingSubscrptionsBacklog = false
func (bct BacklogCacheType) Name() string {
switch bct {
case CacheTypeInvalid:
return ""
case CacheTypeNever:
return "never"
case CacheTypeLastOnly:
return "last"
case CacheTypePersistent:
return "persist"
}
panic("Invalid BacklogCacheType value")
}
var CacheTypesByName = map[string]BacklogCacheType{
"never": CacheTypeNever,
"last": CacheTypeLastOnly,
"persist": CacheTypePersistent,
}
func BacklogCacheTypeByName(name string) (bct BacklogCacheType) {
// CacheTypeInvalid is the zero value so it doesn't matter
bct, _ = CacheTypesByName[name]
return
}
2016-01-17 18:01:21 -08:00
// String implements Stringer
func (bct BacklogCacheType) String() string { return bct.Name() }
2016-01-17 18:01:21 -08:00
// MarshalJSON implements json.Marshaler
func (bct BacklogCacheType) MarshalJSON() ([]byte, error) {
return json.Marshal(bct.Name())
}
2016-01-17 18:01:21 -08:00
// UnmarshalJSON implements json.Unmarshaler
2015-11-15 18:43:34 -08:00
func (bct *BacklogCacheType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)
if err != nil {
return err
}
if str == "" {
2015-11-15 18:43:34 -08:00
*bct = CacheTypeInvalid
return nil
}
2015-11-16 12:50:00 -08:00
newBct := BacklogCacheTypeByName(str)
if newBct != CacheTypeInvalid {
*bct = newBct
return nil
}
return ErrorUnrecognizedCacheType
}
func (mtt MessageTargetType) Name() string {
switch mtt {
case MsgTargetTypeInvalid:
return ""
case MsgTargetTypeChat:
return "chat"
case MsgTargetTypeMultichat:
return "multichat"
case MsgTargetTypeGlobal:
return "global"
}
panic("Invalid MessageTargetType value")
}
var TargetTypesByName = map[string]MessageTargetType{
"chat": MsgTargetTypeChat,
"multichat": MsgTargetTypeMultichat,
"global": MsgTargetTypeGlobal,
}
func MessageTargetTypeByName(name string) (mtt MessageTargetType) {
// MsgTargetTypeInvalid is the zero value so it doesn't matter
mtt, _ = TargetTypesByName[name]
return
}
2016-01-17 18:01:21 -08:00
// String implements Stringer
func (mtt MessageTargetType) String() string { return mtt.Name() }
2016-01-17 18:01:21 -08:00
// MarshalJSON implements json.Marshaler
func (mtt MessageTargetType) MarshalJSON() ([]byte, error) {
return json.Marshal(mtt.Name())
}
2016-01-17 18:01:21 -08:00
// UnmarshalJSON implements json.Unmarshaler
2015-11-15 18:43:34 -08:00
func (mtt *MessageTargetType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)
if err != nil {
return err
}
if str == "" {
2015-11-15 18:43:34 -08:00
*mtt = MsgTargetTypeInvalid
return nil
}
2015-11-16 12:50:00 -08:00
newMtt := MessageTargetTypeByName(str)
if newMtt != MsgTargetTypeInvalid {
*mtt = newMtt
return nil
}
return ErrorUnrecognizedTargetType
2015-10-25 03:21:50 -07:00
}