feat(scum): add local game player intelligence
This commit is contained in:
+109
-29
@@ -3,6 +3,7 @@ package repo
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
@@ -224,6 +225,41 @@ type GameClientBridgeSnapshotStreamRepository interface {
|
||||
Delete(id string) error
|
||||
}
|
||||
|
||||
type GamePlayerRepository interface {
|
||||
Create(domain.GamePlayer) error
|
||||
Get(string) (domain.GamePlayer, error)
|
||||
List(domain.GamePlayerFilter) ([]domain.GamePlayer, error)
|
||||
Update(domain.GamePlayer) error
|
||||
}
|
||||
type GamePlayerAliasRepository interface {
|
||||
Create(domain.GamePlayerAlias) error
|
||||
Get(string) (domain.GamePlayerAlias, error)
|
||||
List(domain.GamePlayerAliasFilter) ([]domain.GamePlayerAlias, error)
|
||||
Update(domain.GamePlayerAlias) error
|
||||
Delete(string) error
|
||||
}
|
||||
type GamePlayerSessionRepository interface {
|
||||
Create(domain.GamePlayerSession) error
|
||||
Get(string) (domain.GamePlayerSession, error)
|
||||
List(domain.GamePlayerSessionFilter) ([]domain.GamePlayerSession, error)
|
||||
Update(domain.GamePlayerSession) error
|
||||
Delete(string) error
|
||||
}
|
||||
type GameAccessAttemptRepository interface {
|
||||
Create(domain.GameAccessAttempt) error
|
||||
Get(string) (domain.GameAccessAttempt, error)
|
||||
List(domain.GameAccessAttemptFilter) ([]domain.GameAccessAttempt, error)
|
||||
Update(domain.GameAccessAttempt) error
|
||||
Delete(string) error
|
||||
}
|
||||
type GameSecuritySignalRepository interface {
|
||||
Create(domain.GameSecuritySignal) error
|
||||
Get(string) (domain.GameSecuritySignal, error)
|
||||
List(domain.GameSecuritySignalFilter) ([]domain.GameSecuritySignal, error)
|
||||
Update(domain.GameSecuritySignal) error
|
||||
Delete(string) error
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Users() UserRepository
|
||||
AuthSessions() AuthSessionRepository
|
||||
@@ -254,38 +290,48 @@ type Store interface {
|
||||
GameClientBridgeCommands() GameClientBridgeCommandRepository
|
||||
GameClientBridgeSnapshots() GameClientBridgeSnapshotRepository
|
||||
GameClientBridgeSnapshotStreams() GameClientBridgeSnapshotStreamRepository
|
||||
GamePlayers() GamePlayerRepository
|
||||
GamePlayerAliases() GamePlayerAliasRepository
|
||||
GamePlayerSessions() GamePlayerSessionRepository
|
||||
GameAccessAttempts() GameAccessAttemptRepository
|
||||
GameSecuritySignals() GameSecuritySignalRepository
|
||||
}
|
||||
|
||||
type MemoryStore struct {
|
||||
users *memoryRepository[domain.User, domain.UserFilter]
|
||||
authSessions *memoryRepository[domain.AuthSessionRecord, domain.AuthSessionFilter]
|
||||
runSessions *memoryRepository[domain.RunControlSession, struct{}]
|
||||
aiProviders *memoryRepository[domain.AIProvider, domain.AIProviderFilter]
|
||||
gamePlugins *memoryRepository[domain.GamePlugin, domain.GamePluginFilter]
|
||||
serverInstances *memoryRepository[domain.ServerInstance, domain.ServerInstanceFilter]
|
||||
runEndpoints *memoryRepository[domain.RunEndpoint, domain.RunEndpointFilter]
|
||||
jobs *memoryJobRepository
|
||||
artifacts *memoryRepository[domain.Artifact, domain.ArtifactFilter]
|
||||
runtimeBindings *memoryRepository[domain.RuntimeBinding, domain.RuntimeBindingFilter]
|
||||
componentKeys *memoryRepository[domain.EncryptedComponentKey, domain.EncryptedComponentKeyFilter]
|
||||
runDists *memoryRepository[domain.RunDistribution, domain.RunDistributionFilter]
|
||||
clientDists *memoryRepository[domain.ClientManagerDistribution, domain.ClientManagerDistributionFilter]
|
||||
clientInstalls *memoryRepository[domain.ClientManagerInstallation, domain.ClientManagerInstallationFilter]
|
||||
clientSessions *memoryRepository[domain.ClientManagerSession, domain.ClientManagerSessionFilter]
|
||||
clientNonces *memoryRepository[domain.ClientManagerRegistrationNonce, domain.ClientManagerNonceFilter]
|
||||
dependencies *memoryRepository[domain.DependencyStatus, domain.DependencyStatusFilter]
|
||||
buildJobs *memoryRepository[domain.ClientManagerBuildJob, domain.ClientManagerBuildJobFilter]
|
||||
updateJobs *memoryRepository[domain.RunUpdateJob, domain.RunUpdateJobFilter]
|
||||
logStreams *memoryRepository[domain.LogStream, domain.LogStreamFilter]
|
||||
auditEvents *memoryRepository[domain.AuditEvent, domain.AuditEventFilter]
|
||||
metricSamples *memoryRepository[domain.MetricSample, domain.MetricSampleFilter]
|
||||
backups *memoryRepository[domain.BackupRecord, domain.BackupFilter]
|
||||
alerts *memoryRepository[domain.AlertRecord, domain.AlertFilter]
|
||||
pluginLifecycle *memoryRepository[domain.PluginLifecycleInstallation, domain.PluginLifecycleFilter]
|
||||
aiConfigDiffs *memoryRepository[domain.AIConfigDiffPreview, domain.AIConfigDiffFilter]
|
||||
bridgeCommands *memoryGameClientBridgeCommandRepository
|
||||
bridgeSnapshots *memoryGameClientBridgeSnapshotRepository
|
||||
bridgeStreams *memoryRepository[domain.GameClientBridgeSnapshotStream, domain.GameClientBridgeSnapshotStreamFilter]
|
||||
users *memoryRepository[domain.User, domain.UserFilter]
|
||||
authSessions *memoryRepository[domain.AuthSessionRecord, domain.AuthSessionFilter]
|
||||
runSessions *memoryRepository[domain.RunControlSession, struct{}]
|
||||
aiProviders *memoryRepository[domain.AIProvider, domain.AIProviderFilter]
|
||||
gamePlugins *memoryRepository[domain.GamePlugin, domain.GamePluginFilter]
|
||||
serverInstances *memoryRepository[domain.ServerInstance, domain.ServerInstanceFilter]
|
||||
runEndpoints *memoryRepository[domain.RunEndpoint, domain.RunEndpointFilter]
|
||||
jobs *memoryJobRepository
|
||||
artifacts *memoryRepository[domain.Artifact, domain.ArtifactFilter]
|
||||
runtimeBindings *memoryRepository[domain.RuntimeBinding, domain.RuntimeBindingFilter]
|
||||
componentKeys *memoryRepository[domain.EncryptedComponentKey, domain.EncryptedComponentKeyFilter]
|
||||
runDists *memoryRepository[domain.RunDistribution, domain.RunDistributionFilter]
|
||||
clientDists *memoryRepository[domain.ClientManagerDistribution, domain.ClientManagerDistributionFilter]
|
||||
clientInstalls *memoryRepository[domain.ClientManagerInstallation, domain.ClientManagerInstallationFilter]
|
||||
clientSessions *memoryRepository[domain.ClientManagerSession, domain.ClientManagerSessionFilter]
|
||||
clientNonces *memoryRepository[domain.ClientManagerRegistrationNonce, domain.ClientManagerNonceFilter]
|
||||
dependencies *memoryRepository[domain.DependencyStatus, domain.DependencyStatusFilter]
|
||||
buildJobs *memoryRepository[domain.ClientManagerBuildJob, domain.ClientManagerBuildJobFilter]
|
||||
updateJobs *memoryRepository[domain.RunUpdateJob, domain.RunUpdateJobFilter]
|
||||
logStreams *memoryRepository[domain.LogStream, domain.LogStreamFilter]
|
||||
auditEvents *memoryRepository[domain.AuditEvent, domain.AuditEventFilter]
|
||||
metricSamples *memoryRepository[domain.MetricSample, domain.MetricSampleFilter]
|
||||
backups *memoryRepository[domain.BackupRecord, domain.BackupFilter]
|
||||
alerts *memoryRepository[domain.AlertRecord, domain.AlertFilter]
|
||||
pluginLifecycle *memoryRepository[domain.PluginLifecycleInstallation, domain.PluginLifecycleFilter]
|
||||
aiConfigDiffs *memoryRepository[domain.AIConfigDiffPreview, domain.AIConfigDiffFilter]
|
||||
bridgeCommands *memoryGameClientBridgeCommandRepository
|
||||
bridgeSnapshots *memoryGameClientBridgeSnapshotRepository
|
||||
bridgeStreams *memoryRepository[domain.GameClientBridgeSnapshotStream, domain.GameClientBridgeSnapshotStreamFilter]
|
||||
gamePlayers *memoryRepository[domain.GamePlayer, domain.GamePlayerFilter]
|
||||
gamePlayerAliases *memoryRepository[domain.GamePlayerAlias, domain.GamePlayerAliasFilter]
|
||||
gamePlayerSessions *memoryRepository[domain.GamePlayerSession, domain.GamePlayerSessionFilter]
|
||||
gameAccessAttempts *memoryRepository[domain.GameAccessAttempt, domain.GameAccessAttemptFilter]
|
||||
gameSecuritySignals *memoryRepository[domain.GameSecuritySignal, domain.GameSecuritySignalFilter]
|
||||
}
|
||||
|
||||
func NewMemoryStore() *MemoryStore {
|
||||
@@ -423,6 +469,11 @@ func NewMemoryStore() *MemoryStore {
|
||||
domain.CopyGameClientBridgeSnapshotStream,
|
||||
matchGameClientBridgeSnapshotStream,
|
||||
),
|
||||
gamePlayers: newMemoryRepository(func(v domain.GamePlayer) string { return v.ID }, domain.CopyGamePlayer, matchGamePlayer),
|
||||
gamePlayerAliases: newMemoryRepository(func(v domain.GamePlayerAlias) string { return v.ID }, domain.CopyGamePlayerAlias, matchGamePlayerAlias),
|
||||
gamePlayerSessions: newMemoryRepository(func(v domain.GamePlayerSession) string { return v.ID }, domain.CopyGamePlayerSession, matchGamePlayerSession),
|
||||
gameAccessAttempts: newMemoryRepository(func(v domain.GameAccessAttempt) string { return v.ID }, domain.CopyGameAccessAttempt, matchGameAccessAttempt),
|
||||
gameSecuritySignals: newMemoryRepository(func(v domain.GameSecuritySignal) string { return v.ID }, domain.CopyGameSecuritySignal, matchGameSecuritySignal),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,6 +526,19 @@ func (store *MemoryStore) GameClientBridgeSnapshots() GameClientBridgeSnapshotRe
|
||||
func (store *MemoryStore) GameClientBridgeSnapshotStreams() GameClientBridgeSnapshotStreamRepository {
|
||||
return store.bridgeStreams
|
||||
}
|
||||
func (store *MemoryStore) GamePlayers() GamePlayerRepository { return store.gamePlayers }
|
||||
func (store *MemoryStore) GamePlayerAliases() GamePlayerAliasRepository {
|
||||
return store.gamePlayerAliases
|
||||
}
|
||||
func (store *MemoryStore) GamePlayerSessions() GamePlayerSessionRepository {
|
||||
return store.gamePlayerSessions
|
||||
}
|
||||
func (store *MemoryStore) GameAccessAttempts() GameAccessAttemptRepository {
|
||||
return store.gameAccessAttempts
|
||||
}
|
||||
func (store *MemoryStore) GameSecuritySignals() GameSecuritySignalRepository {
|
||||
return store.gameSecuritySignals
|
||||
}
|
||||
|
||||
type memoryRepository[T any, F any] struct {
|
||||
mu sync.RWMutex
|
||||
@@ -775,3 +839,19 @@ func matchGameClientBridgeSnapshotStream(stream domain.GameClientBridgeSnapshotS
|
||||
(filter.Type == "" || stream.Type == filter.Type) &&
|
||||
(filter.StreamKey == "" || stream.StreamKey == filter.StreamKey)
|
||||
}
|
||||
|
||||
func matchGamePlayer(v domain.GamePlayer, f domain.GamePlayerFilter) bool {
|
||||
return (f.ServerInstanceID == "" || v.ServerInstanceID == f.ServerInstanceID) && (f.Search == "" || strings.Contains(strings.ToLower(v.DisplayName), strings.ToLower(f.Search)) || strings.Contains(strings.ToLower(v.GamePlayerID), strings.ToLower(f.Search)))
|
||||
}
|
||||
func matchGamePlayerAlias(v domain.GamePlayerAlias, f domain.GamePlayerAliasFilter) bool {
|
||||
return (f.GamePlayerRecordID == "" || v.GamePlayerRecordID == f.GamePlayerRecordID) && (f.ServerInstanceID == "" || v.ServerInstanceID == f.ServerInstanceID)
|
||||
}
|
||||
func matchGamePlayerSession(v domain.GamePlayerSession, f domain.GamePlayerSessionFilter) bool {
|
||||
return (f.GamePlayerRecordID == "" || v.GamePlayerRecordID == f.GamePlayerRecordID) && (f.ServerInstanceID == "" || v.ServerInstanceID == f.ServerInstanceID) && (!f.OpenOnly || v.EndedAt.IsZero())
|
||||
}
|
||||
func matchGameAccessAttempt(v domain.GameAccessAttempt, f domain.GameAccessAttemptFilter) bool {
|
||||
return (f.GamePlayerRecordID == "" || v.GamePlayerRecordID == f.GamePlayerRecordID) && (f.ServerInstanceID == "" || v.ServerInstanceID == f.ServerInstanceID)
|
||||
}
|
||||
func matchGameSecuritySignal(v domain.GameSecuritySignal, f domain.GameSecuritySignalFilter) bool {
|
||||
return (f.GamePlayerRecordID == "" || v.GamePlayerRecordID == f.GamePlayerRecordID) && (f.ServerInstanceID == "" || v.ServerInstanceID == f.ServerInstanceID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user