85 lines
2.0 KiB
Go
85 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/google/uuid"
|
|
"os"
|
|
)
|
|
|
|
type AllowDenyLists struct {
|
|
Allowlist []PlayerInfo
|
|
Denylist []PlayerInfo
|
|
}
|
|
|
|
type AllowDenyConfig struct {
|
|
Global AllowDenyLists
|
|
Servers map[string]AllowDenyLists
|
|
}
|
|
|
|
func ParseAllowDenyConfig(allowDenyListPath string) (*AllowDenyConfig, error) {
|
|
allowDenyConfig := AllowDenyConfig{}
|
|
data, err := os.ReadFile(allowDenyListPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = json.Unmarshal(data, &allowDenyConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &allowDenyConfig, nil
|
|
}
|
|
|
|
func entryMatchesPlayer(entry *PlayerInfo, userInfo *PlayerInfo) bool {
|
|
// User has added an "empty" entry
|
|
// This should never match player info
|
|
if entry.Name == "" && entry.Uuid == uuid.Nil {
|
|
return false
|
|
}
|
|
|
|
if entry.Name != "" && entry.Uuid != uuid.Nil {
|
|
return *entry == *userInfo
|
|
}
|
|
|
|
if entry.Uuid != uuid.Nil {
|
|
return entry.Uuid == userInfo.Uuid
|
|
}
|
|
|
|
return entry.Name == userInfo.Name
|
|
}
|
|
|
|
func (allowDenyConfig *AllowDenyConfig) ServerAllowsPlayer(serverAddress string, userInfo *PlayerInfo) bool {
|
|
if allowDenyConfig == nil {
|
|
return true
|
|
}
|
|
|
|
allowlist := allowDenyConfig.Global.Allowlist
|
|
denylist := allowDenyConfig.Global.Denylist
|
|
serverAllowDenyConfig, ok := allowDenyConfig.Servers[serverAddress]
|
|
// Merges global allow/deny lists with server-specific allow/deny lists if provided
|
|
if ok {
|
|
allowlist = append(allowlist, serverAllowDenyConfig.Allowlist...)
|
|
denylist = append(denylist, serverAllowDenyConfig.Denylist...)
|
|
}
|
|
|
|
// If the allowlist is not empty, the player must have an entry or they will be denied
|
|
// If the allowlist is empty, then the denylist is checked
|
|
// If the allowlist is empty and the player was not in the denylist, then they are allowed
|
|
for _, allowedPlayer := range allowlist {
|
|
if entryMatchesPlayer(&allowedPlayer, userInfo) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
if len(allowlist) > 0 {
|
|
return false
|
|
}
|
|
|
|
for _, deniedPlayer := range denylist {
|
|
if entryMatchesPlayer(&deniedPlayer, userInfo) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|