mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-01-23 02:34:42 +00:00
Update config manager
This commit is contained in:
parent
c13099c56a
commit
8893e1e5bf
38 changed files with 319 additions and 243 deletions
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
config "github.com/giongto35/cloud-game/v3/pkg/config/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/os"
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
var Version = "?"
|
||||
|
||||
func main() {
|
||||
conf := config.NewConfig()
|
||||
conf := config.NewCoordinatorConfig()
|
||||
conf.ParseFlags()
|
||||
|
||||
log := logger.NewConsole(conf.Coordinator.Debug, "c", false)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"time"
|
||||
|
||||
config "github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/os"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker"
|
||||
|
|
@ -13,7 +13,7 @@ import (
|
|||
var Version = "?"
|
||||
|
||||
func run() {
|
||||
conf := config.NewConfig()
|
||||
conf := config.NewWorkerConfig()
|
||||
conf.ParseFlags()
|
||||
|
||||
log := logger.NewConsole(conf.Worker.Debug, "w", false)
|
||||
|
|
|
|||
8
go.mod
8
go.mod
|
|
@ -9,7 +9,8 @@ require (
|
|||
github.com/goccy/go-json v0.10.2
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/kkyr/fig v0.3.1
|
||||
github.com/knadh/koanf/maps v0.1.1
|
||||
github.com/knadh/koanf/v2 v2.0.1
|
||||
github.com/pion/interceptor v0.1.12
|
||||
github.com/pion/logging v0.2.2
|
||||
github.com/pion/webrtc/v3 v3.1.60
|
||||
|
|
@ -18,14 +19,16 @@ require (
|
|||
github.com/veandco/go-sdl2 v0.4.34
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/image v0.7.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/pion/datachannel v1.5.5 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.6 // indirect
|
||||
github.com/pion/ice/v2 v2.3.2 // indirect
|
||||
|
|
@ -45,5 +48,4 @@ require (
|
|||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -34,8 +34,10 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/kkyr/fig v0.3.1 h1:GqsamO9dwY05t2xh6ubzjPPYw2It4hoWbKZEWmDxM0o=
|
||||
github.com/kkyr/fig v0.3.1/go.mod h1:ItUILF8IIzgZOMhx5xpJ1W/bviQsWRKOwKXfE/tqUoA=
|
||||
github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs=
|
||||
github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
|
||||
github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g=
|
||||
github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
|
@ -48,8 +50,12 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
|
|||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
|
@ -59,8 +65,6 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
|
|||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
|
||||
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
|
||||
github.com/pion/dtls/v2 v2.2.6 h1:yXMxKr0Skd+Ub6A8UqXTRLSywskx93ooMRHsQUtd+Z4=
|
||||
|
|
|
|||
66
pkg/config/coordinator.go
Normal file
66
pkg/config/coordinator.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package config
|
||||
|
||||
import "flag"
|
||||
|
||||
type CoordinatorConfig struct {
|
||||
Coordinator Coordinator
|
||||
Emulator Emulator
|
||||
Recording Recording
|
||||
Version Version
|
||||
Webrtc Webrtc
|
||||
}
|
||||
|
||||
type Coordinator struct {
|
||||
Analytics Analytics
|
||||
Debug bool
|
||||
Library Library
|
||||
Monitoring Monitoring
|
||||
Origin struct {
|
||||
UserWs string
|
||||
WorkerWs string
|
||||
}
|
||||
Selector string
|
||||
Server Server
|
||||
}
|
||||
|
||||
type Library struct {
|
||||
// some directory which is going to be
|
||||
// the root folder for the library
|
||||
BasePath string
|
||||
// a list of supported file extensions
|
||||
Supported []string
|
||||
// a list of ignored words in the files
|
||||
Ignored []string
|
||||
// print some additional info
|
||||
Verbose bool
|
||||
// enable directory changes watch
|
||||
WatchMode bool
|
||||
}
|
||||
|
||||
func (l Library) GetSupportedExtensions() []string { return l.Supported }
|
||||
|
||||
// Analytics is optional Google Analytics
|
||||
type Analytics struct {
|
||||
Inject bool
|
||||
Gtag string
|
||||
}
|
||||
|
||||
const SelectByPing = "ping"
|
||||
|
||||
// allows custom config path
|
||||
var coordinatorConfigPath string
|
||||
|
||||
func NewCoordinatorConfig() (conf CoordinatorConfig) {
|
||||
err := LoadConfig(&conf, coordinatorConfigPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *CoordinatorConfig) ParseFlags() {
|
||||
c.Coordinator.Server.WithFlags()
|
||||
flag.IntVar(&c.Coordinator.Monitoring.Port, "monitoring.port", c.Coordinator.Monitoring.Port, "Monitoring server port")
|
||||
flag.StringVar(&coordinatorConfigPath, "c-conf", coordinatorConfigPath, "Set custom configuration file path")
|
||||
flag.Parse()
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package coordinator
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/monitoring"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/shared"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/webrtc"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Coordinator Coordinator
|
||||
Emulator emulator.Emulator
|
||||
Recording shared.Recording
|
||||
Version shared.Version
|
||||
Webrtc webrtc.Webrtc
|
||||
}
|
||||
|
||||
type Coordinator struct {
|
||||
Analytics Analytics
|
||||
Debug bool
|
||||
Library games.Config
|
||||
Monitoring monitoring.Config
|
||||
Origin struct {
|
||||
UserWs string
|
||||
WorkerWs string
|
||||
}
|
||||
Selector string
|
||||
Server shared.Server
|
||||
}
|
||||
|
||||
// Analytics is optional Google Analytics
|
||||
type Analytics struct {
|
||||
Inject bool
|
||||
Gtag string
|
||||
}
|
||||
|
||||
const SelectByPing = "ping"
|
||||
|
||||
// allows custom config path
|
||||
var configPath string
|
||||
|
||||
func NewConfig() (conf Config) {
|
||||
err := config.LoadConfig(&conf, configPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Config) ParseFlags() {
|
||||
c.Coordinator.Server.WithFlags()
|
||||
flag.IntVar(&c.Coordinator.Monitoring.Port, "monitoring.port", c.Coordinator.Monitoring.Port, "Monitoring server port")
|
||||
flag.StringVar(&configPath, "c-conf", configPath, "Set custom configuration file path")
|
||||
flag.Parse()
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package emulator
|
||||
package config
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package emulator
|
||||
package config
|
||||
|
||||
import "testing"
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package encoder
|
||||
|
||||
type Encoder struct {
|
||||
Audio Audio
|
||||
Video Video
|
||||
}
|
||||
|
||||
type Audio struct {
|
||||
Frame int
|
||||
}
|
||||
|
||||
type Video struct {
|
||||
Codec string
|
||||
Concurrency int
|
||||
H264 struct {
|
||||
Crf uint8
|
||||
Preset string
|
||||
Profile string
|
||||
Tune string
|
||||
LogLevel int
|
||||
}
|
||||
Vpx struct {
|
||||
Bitrate uint
|
||||
KeyframeInterval uint
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,69 @@ package config
|
|||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kkyr/fig"
|
||||
"github.com/knadh/koanf/maps"
|
||||
"github.com/knadh/koanf/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const EnvPrefix = "CLOUD_GAME"
|
||||
const EnvPrefix = "CLOUD_GAME_"
|
||||
|
||||
type File string
|
||||
|
||||
func (f *File) ReadBytes() ([]byte, error) { return os.ReadFile(string(*f)) }
|
||||
func (f *File) Read() (map[string]interface{}, error) { return nil, nil }
|
||||
|
||||
type YAML struct{}
|
||||
|
||||
func (p *YAML) Marshal(map[string]interface{}) ([]byte, error) { return nil, nil }
|
||||
func (p *YAML) Unmarshal(b []byte) (map[string]interface{}, error) {
|
||||
var out map[string]interface{}
|
||||
if err := yaml.Unmarshal(b, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type Env string
|
||||
|
||||
func (e *Env) ReadBytes() ([]byte, error) { return nil, nil }
|
||||
func (e *Env) Read() (map[string]interface{}, error) {
|
||||
var keys []string
|
||||
for _, k := range os.Environ() {
|
||||
if strings.HasPrefix(k, string(*e)) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
mp := make(map[string]interface{})
|
||||
for _, k := range keys {
|
||||
parts := strings.SplitN(k, "=", 2)
|
||||
n := strings.ToLower(strings.TrimPrefix(parts[0], string(*e)))
|
||||
if n == "" {
|
||||
continue
|
||||
}
|
||||
// convert VAR_VAR to VAR.VAR or if we need to preserve _
|
||||
// i.e. VAR_VAR__KEY_HAS_SLASHES to VAR.VAR.KEY_HAS_SLASHES
|
||||
// with the result: VAR: { VAR: { KEY_HAS_SLASHES: '' } } }
|
||||
x := strings.Index(n, "__")
|
||||
var key string
|
||||
if x == -1 {
|
||||
key = strings.Replace(n, "_", ".", -1)
|
||||
} else {
|
||||
key = strings.Replace(n[:x+1], "_", ".", -1) + n[x+2:]
|
||||
}
|
||||
mp[key] = parts[1]
|
||||
}
|
||||
return maps.Unflatten(mp, "."), nil
|
||||
}
|
||||
|
||||
var k = koanf.New("_")
|
||||
|
||||
// LoadConfig loads a configuration file into the given struct.
|
||||
// The path param specifies a custom path to the configuration file.
|
||||
// Reads and puts environment variables with the prefix CLOUD_GAME_.
|
||||
// Params from the config should be in uppercase separated with _.
|
||||
func LoadConfig(config any, path string) error {
|
||||
dirs := []string{path}
|
||||
if path == "" {
|
||||
|
|
@ -24,18 +77,23 @@ func LoadConfig(config any, path string) error {
|
|||
dirs = append(dirs, homeDir)
|
||||
}
|
||||
|
||||
if err := fig.Load(config, fig.Dirs(dirs...), fig.UseEnv(EnvPrefix)); err != nil {
|
||||
for _, dir := range dirs {
|
||||
f := File(filepath.Join(filepath.Clean(dir), "config.yaml"))
|
||||
if _, err := os.Stat(string(f)); !os.IsNotExist(err) {
|
||||
if err := k.Load(&f, &YAML{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env := Env(EnvPrefix)
|
||||
if err := k.Load(&env, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// override from /home
|
||||
if homeDir != "" {
|
||||
_ = fig.Load(config, fig.Dirs(homeDir))
|
||||
if err := k.Unmarshal("", config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadConfigEnv(config any) error {
|
||||
return fig.Load(config, fig.IgnoreFile(), fig.UseEnv(EnvPrefix))
|
||||
}
|
||||
|
|
|
|||
32
pkg/config/loader_test.go
Normal file
32
pkg/config/loader_test.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigEnv(t *testing.T) {
|
||||
var out WorkerConfig
|
||||
|
||||
_ = os.Setenv("CLOUD_GAME_ENCODER_AUDIO_FRAME", "33")
|
||||
defer func() { _ = os.Unsetenv("CLOUD_GAME_ENCODER_AUDIO_FRAME") }()
|
||||
|
||||
_ = os.Setenv("CLOUD_GAME_EMULATOR_LIBRETRO_CORES_LIST_PCSX_OPTIONS__PCSX_REARMED_DRC", "x")
|
||||
defer func() {
|
||||
_ = os.Unsetenv("CLOUD_GAME_EMULATOR_LIBRETRO_CORES_LIST_PCSX_OPTIONS__PCSX_REARMED_DRC")
|
||||
}()
|
||||
|
||||
err := LoadConfig(&out, "../../configs")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if out.Encoder.Audio.Frame != 33 {
|
||||
t.Errorf("%v is not 33", out.Encoder.Audio.Frame)
|
||||
}
|
||||
|
||||
v := out.Emulator.Libretro.Cores.List["pcsx"].Options["pcsx_rearmed_drc"]
|
||||
if v != "x" {
|
||||
t.Errorf("%v is not x", v)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package monitoring
|
||||
|
||||
type Config struct {
|
||||
Port int
|
||||
URLPrefix string
|
||||
MetricEnabled bool `json:"metric_enabled"`
|
||||
ProfilingEnabled bool `json:"profiling_enabled"`
|
||||
}
|
||||
|
||||
func (c *Config) IsEnabled() bool { return c.MetricEnabled || c.ProfilingEnabled }
|
||||
|
|
@ -1,9 +1,18 @@
|
|||
package shared
|
||||
package config
|
||||
|
||||
import "flag"
|
||||
|
||||
type Version int
|
||||
|
||||
type Monitoring struct {
|
||||
Port int
|
||||
URLPrefix string
|
||||
MetricEnabled bool `json:"metric_enabled"`
|
||||
ProfilingEnabled bool `json:"profiling_enabled"`
|
||||
}
|
||||
|
||||
func (c *Monitoring) IsEnabled() bool { return c.MetricEnabled || c.ProfilingEnabled }
|
||||
|
||||
type Server struct {
|
||||
Address string
|
||||
Https bool
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package storage
|
||||
|
||||
type Storage struct {
|
||||
Provider string
|
||||
Key string
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package webrtc
|
||||
package config
|
||||
|
||||
type Webrtc struct {
|
||||
DisableDefaultInterceptors bool
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package worker
|
||||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
|
@ -8,29 +8,27 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/encoder"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/monitoring"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/shared"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/storage"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/webrtc"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Encoder encoder.Encoder
|
||||
Emulator emulator.Emulator
|
||||
Recording shared.Recording
|
||||
Storage storage.Storage
|
||||
type WorkerConfig struct {
|
||||
Encoder Encoder
|
||||
Emulator Emulator
|
||||
Recording Recording
|
||||
Storage Storage
|
||||
Worker Worker
|
||||
Webrtc webrtc.Webrtc
|
||||
Version shared.Version
|
||||
Webrtc Webrtc
|
||||
Version Version
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
Provider string
|
||||
Key string
|
||||
}
|
||||
|
||||
type Worker struct {
|
||||
Debug bool
|
||||
Monitoring monitoring.Config
|
||||
Monitoring Monitoring
|
||||
Network struct {
|
||||
CoordinatorAddress string
|
||||
Endpoint string
|
||||
|
|
@ -39,15 +37,40 @@ type Worker struct {
|
|||
Secure bool
|
||||
Zone string
|
||||
}
|
||||
Server shared.Server
|
||||
Server Server
|
||||
Tag string
|
||||
}
|
||||
|
||||
// allows custom config path
|
||||
var configPath string
|
||||
type Encoder struct {
|
||||
Audio Audio
|
||||
Video Video
|
||||
}
|
||||
|
||||
func NewConfig() (conf Config) {
|
||||
err := config.LoadConfig(&conf, configPath)
|
||||
type Audio struct {
|
||||
Frame int
|
||||
}
|
||||
|
||||
type Video struct {
|
||||
Codec string
|
||||
Concurrency int
|
||||
H264 struct {
|
||||
Crf uint8
|
||||
Preset string
|
||||
Profile string
|
||||
Tune string
|
||||
LogLevel int
|
||||
}
|
||||
Vpx struct {
|
||||
Bitrate uint
|
||||
KeyframeInterval uint
|
||||
}
|
||||
}
|
||||
|
||||
// allows custom config path
|
||||
var workerConfigPath string
|
||||
|
||||
func NewWorkerConfig() (conf WorkerConfig) {
|
||||
err := LoadConfig(&conf, workerConfigPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -59,17 +82,17 @@ func NewConfig() (conf Config) {
|
|||
// ParseFlags updates config values from passed runtime flags.
|
||||
// Define own flags with default value set to the current config param.
|
||||
// Don't forget to call flag.Parse().
|
||||
func (c *Config) ParseFlags() {
|
||||
func (c *WorkerConfig) ParseFlags() {
|
||||
c.Worker.Server.WithFlags()
|
||||
flag.IntVar(&c.Worker.Monitoring.Port, "monitoring.port", c.Worker.Monitoring.Port, "Monitoring server port")
|
||||
flag.StringVar(&c.Worker.Network.CoordinatorAddress, "coordinatorhost", c.Worker.Network.CoordinatorAddress, "Worker URL to connect")
|
||||
flag.StringVar(&c.Worker.Network.Zone, "zone", c.Worker.Network.Zone, "Worker network zone (us, eu, etc.)")
|
||||
flag.StringVar(&configPath, "w-conf", configPath, "Set custom configuration file path")
|
||||
flag.StringVar(&workerConfigPath, "w-conf", workerConfigPath, "Set custom configuration file path")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
// expandSpecialTags replaces all the special tags in the config.
|
||||
func (c *Config) expandSpecialTags() {
|
||||
func (c *WorkerConfig) expandSpecialTags() {
|
||||
tag := "{user}"
|
||||
for _, dir := range []*string{&c.Emulator.Storage, &c.Emulator.Libretro.Cores.Repo.ExtLock} {
|
||||
if *dir == "" || !strings.Contains(*dir, tag) {
|
||||
|
|
@ -85,10 +108,10 @@ func (c *Config) expandSpecialTags() {
|
|||
}
|
||||
|
||||
// fixValues tries to fix some values otherwise hard to set externally.
|
||||
func (c *Config) fixValues() {
|
||||
func (c *WorkerConfig) fixValues() {
|
||||
// with ICE lite we clear ICE servers
|
||||
if c.Webrtc.IceLite {
|
||||
c.Webrtc.IceServers = []webrtc.IceServer{}
|
||||
c.Webrtc.IceServers = []IceServer{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,8 +4,7 @@ import (
|
|||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/shared"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/monitoring"
|
||||
|
|
@ -13,7 +12,7 @@ import (
|
|||
"github.com/giongto35/cloud-game/v3/pkg/service"
|
||||
)
|
||||
|
||||
func New(conf coordinator.Config, log *logger.Logger) (services service.Group) {
|
||||
func New(conf config.CoordinatorConfig, log *logger.Logger) (services service.Group) {
|
||||
lib := games.NewLibWhitelisted(conf.Coordinator.Library, conf.Emulator, log)
|
||||
lib.Scan()
|
||||
hub := NewHub(conf, lib, log)
|
||||
|
|
@ -33,7 +32,7 @@ func New(conf coordinator.Config, log *logger.Logger) (services service.Group) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewHTTPServer(conf coordinator.Config, log *logger.Logger, fnMux func(*httpx.Mux) *httpx.Mux) (*httpx.Server, error) {
|
||||
func NewHTTPServer(conf config.CoordinatorConfig, log *logger.Logger, fnMux func(*httpx.Mux) *httpx.Mux) (*httpx.Server, error) {
|
||||
return httpx.NewServer(
|
||||
conf.Coordinator.Server.GetAddr(),
|
||||
func(s *httpx.Server) httpx.Handler {
|
||||
|
|
@ -46,7 +45,7 @@ func NewHTTPServer(conf coordinator.Config, log *logger.Logger, fnMux func(*http
|
|||
)
|
||||
}
|
||||
|
||||
func index(conf coordinator.Config, log *logger.Logger) httpx.Handler {
|
||||
func index(conf config.CoordinatorConfig, log *logger.Logger) httpx.Handler {
|
||||
const indexHTML = "./web/index.html"
|
||||
|
||||
handler := func(tpl *template.Template, w httpx.ResponseWriter, r *httpx.Request) {
|
||||
|
|
@ -56,8 +55,8 @@ func index(conf coordinator.Config, log *logger.Logger) httpx.Handler {
|
|||
}
|
||||
// render index page with some tpl values
|
||||
tplData := struct {
|
||||
Analytics coordinator.Analytics
|
||||
Recording shared.Recording
|
||||
Analytics config.Analytics
|
||||
Recording config.Recording
|
||||
}{conf.Coordinator.Analytics, conf.Recording}
|
||||
if err := tpl.Execute(w, tplData); err != nil {
|
||||
log.Fatal().Err(err).Msg("error with the analytics template file")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
)
|
||||
|
|
@ -24,14 +24,14 @@ type Connection interface {
|
|||
}
|
||||
|
||||
type Hub struct {
|
||||
conf coordinator.Config
|
||||
conf config.CoordinatorConfig
|
||||
launcher games.Launcher
|
||||
log *logger.Logger
|
||||
users com.NetMap[*User]
|
||||
workers com.NetMap[*Worker]
|
||||
}
|
||||
|
||||
func NewHub(conf coordinator.Config, lib games.GameLibrary, log *logger.Logger) *Hub {
|
||||
func NewHub(conf config.CoordinatorConfig, lib games.GameLibrary, log *logger.Logger) *Hub {
|
||||
return &Hub{
|
||||
conf: conf,
|
||||
users: com.NewNetMap[*User](),
|
||||
|
|
@ -168,7 +168,7 @@ func (h *Hub) findWorkerFor(usr *User, q url.Values, log *logger.Logger) *Worker
|
|||
log.Debug().Msgf("Worker with id: %v has been found", wid)
|
||||
} else {
|
||||
switch h.conf.Coordinator.Selector {
|
||||
case coordinator.SelectByPing:
|
||||
case config.SelectByPing:
|
||||
log.Debug().Msgf("Searching fastest free worker...")
|
||||
if worker = h.findFastestWorker(zone,
|
||||
func(servers []string) (map[string]int64, error) { return usr.CheckLatency(servers) }); worker != nil {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package coordinator
|
|||
import (
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
)
|
||||
|
|
@ -42,7 +42,7 @@ func (u *User) Disconnect() {
|
|||
}
|
||||
}
|
||||
|
||||
func (u *User) HandleRequests(info HasServerInfo, launcher games.Launcher, conf coordinator.Config) chan struct{} {
|
||||
func (u *User) HandleRequests(info HasServerInfo, launcher games.Launcher, conf config.CoordinatorConfig) chan struct{} {
|
||||
return u.ProcessPackets(func(x api.In[com.Uid]) error {
|
||||
payload := x.GetPayload()
|
||||
switch x.GetType() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"unsafe"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/webrtc"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
)
|
||||
|
||||
// CheckLatency sends a list of server addresses to the user
|
||||
|
|
@ -22,7 +22,7 @@ func (u *User) CheckLatency(req api.CheckLatencyUserResponse) (api.CheckLatencyU
|
|||
}
|
||||
|
||||
// InitSession signals the user that the app is ready to go.
|
||||
func (u *User) InitSession(wid string, ice []webrtc.IceServer, games []string) {
|
||||
func (u *User) InitSession(wid string, ice []config.IceServer, games []string) {
|
||||
u.Notify(api.InitSession, api.InitSessionUserResponse{
|
||||
// don't do this at home
|
||||
Ice: *(*[]api.IceServer)(unsafe.Pointer(&ice)),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/coordinator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
)
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ func (u *User) HandleWebrtcIceCandidate(rq api.WebrtcUserIceCandidate) {
|
|||
u.w.WebrtcIceCandidate(u.Id(), string(rq))
|
||||
}
|
||||
|
||||
func (u *User) HandleStartGame(rq api.GameStartUserRequest, launcher games.Launcher, conf coordinator.Config) {
|
||||
func (u *User) HandleStartGame(rq api.GameStartUserRequest, launcher games.Launcher, conf config.CoordinatorConfig) {
|
||||
// +injects game data into the original game request
|
||||
// the name of the game either in the `room id` field or
|
||||
// it's in the initial request
|
||||
|
|
|
|||
|
|
@ -11,24 +11,10 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
)
|
||||
|
||||
// Config is an external configuration
|
||||
type Config struct {
|
||||
// some directory which is going to be
|
||||
// the root folder for the library
|
||||
BasePath string
|
||||
// a list of supported file extensions
|
||||
Supported []string
|
||||
// a list of ignored words in the files
|
||||
Ignored []string
|
||||
// print some additional info
|
||||
Verbose bool
|
||||
// enable directory changes watch
|
||||
WatchMode bool
|
||||
}
|
||||
|
||||
// libConf is an optimized internal library configuration
|
||||
type libConf struct {
|
||||
path string
|
||||
|
|
@ -82,11 +68,11 @@ type GameMetadata struct {
|
|||
|
||||
func (g GameMetadata) FullPath() string { return filepath.Join(g.Base, g.Path) }
|
||||
|
||||
func (c Config) GetSupportedExtensions() []string { return c.Supported }
|
||||
func NewLib(conf config.Library, log *logger.Logger) GameLibrary {
|
||||
return NewLibWhitelisted(conf, conf, log)
|
||||
}
|
||||
|
||||
func NewLib(conf Config, log *logger.Logger) GameLibrary { return NewLibWhitelisted(conf, conf, log) }
|
||||
|
||||
func NewLibWhitelisted(conf Config, filter FileExtensionWhitelist, log *logger.Logger) GameLibrary {
|
||||
func NewLibWhitelisted(conf config.Library, filter FileExtensionWhitelist, log *logger.Logger) GameLibrary {
|
||||
hasSource := true
|
||||
dir, err := filepath.Abs(conf.BasePath)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package games
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
)
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ func TestLibraryScan(t *testing.T) {
|
|||
|
||||
l := logger.NewConsole(false, "w", false)
|
||||
for _, test := range tests {
|
||||
library := NewLib(Config{
|
||||
library := NewLib(config.Library{
|
||||
BasePath: test.directory,
|
||||
Supported: []string{"gba", "zip", "nes"},
|
||||
Ignored: []string{"neogeo", "pgm"},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/VictoriaMetrics/metrics"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/monitoring"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/network/httpx"
|
||||
)
|
||||
|
|
@ -16,14 +16,14 @@ const debugEndpoint = "/debug/pprof"
|
|||
const metricsEndpoint = "/metrics"
|
||||
|
||||
type Monitoring struct {
|
||||
conf monitoring.Config
|
||||
conf config.Monitoring
|
||||
server *httpx.Server
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
// New creates new monitoring service.
|
||||
// The tag param specifies owner label for logs.
|
||||
func New(conf monitoring.Config, baseAddr string, log *logger.Logger) *Monitoring {
|
||||
func New(conf config.Monitoring, baseAddr string, log *logger.Logger) *Monitoring {
|
||||
serv, err := httpx.NewServer(
|
||||
net.JoinHostPort(baseAddr, strconv.Itoa(conf.Port)),
|
||||
func(s *httpx.Server) httpx.Handler {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package httpx
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/shared"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
)
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ func HttpsRedirect(redirect bool) Option {
|
|||
|
||||
func WithPortRoll(roll bool) Option { return func(opts *Options) { opts.PortRoll = roll } }
|
||||
func WithZone(zone string) Option { return func(opts *Options) { opts.Zone = zone } }
|
||||
func WithServerConfig(conf shared.Server) Option {
|
||||
func WithServerConfig(conf config.Server) Option {
|
||||
return func(opts *Options) {
|
||||
opts.Https = conf.Https
|
||||
opts.HttpsCert = conf.Tls.HttpsCert
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
|
||||
conf "github.com/giongto35/cloud-game/v3/pkg/config/webrtc"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/network/socket"
|
||||
"github.com/pion/interceptor"
|
||||
|
|
@ -19,7 +19,7 @@ type ApiFactory struct {
|
|||
|
||||
type ModApiFun func(m *webrtc.MediaEngine, i *interceptor.Registry, s *webrtc.SettingEngine)
|
||||
|
||||
func NewApiFactory(conf conf.Webrtc, log *logger.Logger, mod ModApiFun) (api *ApiFactory, err error) {
|
||||
func NewApiFactory(conf config.Webrtc, log *logger.Logger, mod ModApiFun) (api *ApiFactory, err error) {
|
||||
m := &webrtc.MediaEngine{}
|
||||
if err = m.RegisterDefaultCodecs(); err != nil {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/network/webrtc"
|
||||
)
|
||||
|
|
@ -27,7 +27,7 @@ type coordinator struct {
|
|||
|
||||
var connector com.Client
|
||||
|
||||
func newCoordinatorConnection(host string, conf worker.Worker, addr string, log *logger.Logger) (*coordinator, error) {
|
||||
func newCoordinatorConnection(host string, conf config.Worker, addr string, log *logger.Logger) (*coordinator, error) {
|
||||
scheme := "ws"
|
||||
if conf.Network.Secure {
|
||||
scheme = "wss"
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ import (
|
|||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/api"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/network/webrtc"
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
// buildConnQuery builds initial connection data query to a coordinator.
|
||||
func buildConnQuery(id com.Uid, conf worker.Worker, address string) (string, error) {
|
||||
func buildConnQuery(id com.Uid, conf config.Worker, address string) (string, error) {
|
||||
addr := conf.GetPingAddr(address)
|
||||
return toBase64Json(api.ConnectionRequest[com.Uid]{
|
||||
Addr: addr.Hostname(),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
conf "github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/os"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator"
|
||||
|
|
@ -21,7 +21,7 @@ type Frontend struct {
|
|||
|
||||
input InputState
|
||||
|
||||
conf conf.Emulator
|
||||
conf config.Emulator
|
||||
storage Storage
|
||||
|
||||
// out frame size
|
||||
|
|
@ -64,7 +64,7 @@ var (
|
|||
)
|
||||
|
||||
// NewFrontend implements Emulator interface for a Libretro frontend.
|
||||
func NewFrontend(conf conf.Emulator, log *logger.Logger) (*Frontend, error) {
|
||||
func NewFrontend(conf config.Emulator, log *logger.Logger) (*Frontend, error) {
|
||||
log = log.Extend(log.With().Str("m", "Libretro"))
|
||||
ll := log.Extend(log.Level(logger.Level(conf.Libretro.LogLevel)).With())
|
||||
SetLibretroLogger(ll)
|
||||
|
|
@ -105,15 +105,15 @@ func NewFrontend(conf conf.Emulator, log *logger.Logger) (*Frontend, error) {
|
|||
}
|
||||
|
||||
func (f *Frontend) LoadMetadata(emu string) {
|
||||
config := f.conf.GetLibretroCoreConfig(emu)
|
||||
conf := f.conf.GetLibretroCoreConfig(emu)
|
||||
meta := emulator.Metadata{
|
||||
AutoGlContext: config.AutoGlContext,
|
||||
HasMultitap: config.HasMultitap,
|
||||
HasVFR: config.VFR,
|
||||
IsGlAllowed: config.IsGlAllowed,
|
||||
LibPath: config.Lib,
|
||||
Options: config.Options,
|
||||
UsesLibCo: config.UsesLibCo,
|
||||
AutoGlContext: conf.AutoGlContext,
|
||||
HasMultitap: conf.HasMultitap,
|
||||
HasVFR: conf.VFR,
|
||||
IsGlAllowed: conf.IsGlAllowed,
|
||||
LibPath: conf.Lib,
|
||||
Options: conf.Options,
|
||||
UsesLibCo: conf.UsesLibCo,
|
||||
}
|
||||
f.mu.Lock()
|
||||
coreLoad(meta)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package manager
|
||||
|
||||
import (
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
|
|
@ -14,10 +14,10 @@ type Manager interface {
|
|||
}
|
||||
|
||||
type BasicManager struct {
|
||||
Conf emulator.LibretroConfig
|
||||
Conf config.LibretroConfig
|
||||
}
|
||||
|
||||
func (m BasicManager) GetInstalled() (installed []emulator.CoreInfo, err error) {
|
||||
func (m BasicManager) GetInstalled() (installed []config.CoreInfo, err error) {
|
||||
dir := m.Conf.GetCoresStorePath()
|
||||
arch, err := libretro.GetCoreExt()
|
||||
if err != nil {
|
||||
|
|
@ -32,7 +32,7 @@ func (m BasicManager) GetInstalled() (installed []emulator.CoreInfo, err error)
|
|||
for _, file := range files {
|
||||
name := file.Name()
|
||||
if filepath.Ext(name) == arch.LibExt {
|
||||
installed = append(installed, emulator.CoreInfo{Name: strings.TrimSuffix(name, arch.LibExt)})
|
||||
installed = append(installed, config.CoreInfo{Name: strings.TrimSuffix(name, arch.LibExt)})
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package remotehttp
|
||||
|
||||
import (
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro"
|
||||
"os"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro/manager"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator/libretro/repo"
|
||||
"github.com/gofrs/flock"
|
||||
|
|
@ -22,7 +22,7 @@ type Manager struct {
|
|||
log *logger.Logger
|
||||
}
|
||||
|
||||
func NewRemoteHttpManager(conf emulator.LibretroConfig, log *logger.Logger) Manager {
|
||||
func NewRemoteHttpManager(conf config.LibretroConfig, log *logger.Logger) Manager {
|
||||
repoConf := conf.Cores.Repo.Main
|
||||
altRepoConf := conf.Cores.Repo.Secondary
|
||||
// used for synchronization of multiple process
|
||||
|
|
@ -55,7 +55,7 @@ func NewRemoteHttpManager(conf emulator.LibretroConfig, log *logger.Logger) Mana
|
|||
return m
|
||||
}
|
||||
|
||||
func CheckCores(conf emulator.Emulator, log *logger.Logger) error {
|
||||
func CheckCores(conf config.Emulator, log *logger.Logger) error {
|
||||
if !conf.Libretro.Cores.Repo.Sync {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ func (m *Manager) getCoreUrls(names []string, repo repo.Repository) (urls []Down
|
|||
return
|
||||
}
|
||||
|
||||
func (m *Manager) download(cores []emulator.CoreInfo) (failed []string) {
|
||||
func (m *Manager) download(cores []config.CoreInfo) (failed []string) {
|
||||
if len(cores) == 0 || m.repo == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ func (m *Manager) down(cores []string, repo repo.Repository) (failed []string) {
|
|||
}
|
||||
|
||||
// diff returns a list of not installed cores.
|
||||
func diff(declared, installed []emulator.CoreInfo) (diff []emulator.CoreInfo) {
|
||||
func diff(declared, installed []config.CoreInfo) (diff []config.CoreInfo) {
|
||||
if len(declared) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
)
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
|
|
@ -39,9 +39,9 @@ func TestDiff(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
toCoreInfo := func(names []string) (r []emulator.CoreInfo) {
|
||||
toCoreInfo := func(names []string) (r []config.CoreInfo) {
|
||||
for _, n := range names {
|
||||
r = append(r, emulator.CoreInfo{Name: n})
|
||||
r = append(r, config.CoreInfo{Name: n})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"unsafe"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator"
|
||||
)
|
||||
|
|
@ -50,7 +49,7 @@ func GetEmulatorMock(room string, system string) *EmulatorMock {
|
|||
rootPath := getRootPath()
|
||||
configPath := rootPath + "configs/"
|
||||
|
||||
var conf worker.Config
|
||||
var conf config.WorkerConfig
|
||||
if err := config.LoadConfig(&conf, configPath); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
conf "github.com/giongto35/cloud-game/v3/pkg/config/encoder"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/encoder"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/encoder/h264"
|
||||
|
|
@ -68,7 +68,7 @@ func (b *Buffer) Write(s Samples, onFull OnFull) (r int) {
|
|||
// GetFrameSizeFor calculates audio frame size, i.e. 48k*frame/1000*2
|
||||
func GetFrameSizeFor(hz int, frame int) int { return hz * frame / 1000 * audioChannels }
|
||||
|
||||
func (r *Room) initAudio(frequency int, conf conf.Audio) {
|
||||
func (r *Room) initAudio(frequency int, conf config.Audio) {
|
||||
buf := NewBuffer(GetFrameSizeFor(frequency, conf.Frame))
|
||||
resample, frameLen := frequency != audioFrequency, 0
|
||||
if resample {
|
||||
|
|
@ -107,7 +107,7 @@ func (r *Room) initAudio(frequency int, conf conf.Audio) {
|
|||
}
|
||||
|
||||
// initVideo processes videoFrames images with an encoder (codec) then pushes the result to WebRTC.
|
||||
func (r *Room) initVideo(width, height int, conf conf.Video) {
|
||||
func (r *Room) initVideo(width, height int, conf config.Video) {
|
||||
var enc encoder.Encoder
|
||||
var err error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/recorder"
|
||||
)
|
||||
|
|
@ -11,7 +11,7 @@ type RecordingRoom struct {
|
|||
rec *recorder.Recording
|
||||
}
|
||||
|
||||
func WithRecording(room GamingRoom, rec bool, recUser string, game string, conf worker.Config) *RecordingRoom {
|
||||
func WithRecording(room GamingRoom, rec bool, recUser string, game string, conf config.WorkerConfig) *RecordingRoom {
|
||||
rr := &RecordingRoom{GamingRoom: room, rec: recorder.NewRecording(
|
||||
recorder.Meta{UserName: recUser},
|
||||
room.GetLog(),
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/com"
|
||||
conf "github.com/giongto35/cloud-game/v3/pkg/config/emulator"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/os"
|
||||
|
|
@ -42,7 +41,7 @@ type Room struct {
|
|||
log *logger.Logger
|
||||
}
|
||||
|
||||
func NewRoom(id string, game games.GameMetadata, onClose func(*Room), conf worker.Config, log *logger.Logger) *Room {
|
||||
func NewRoom(id string, game games.GameMetadata, onClose func(*Room), conf config.WorkerConfig, log *logger.Logger) *Room {
|
||||
if id == "" {
|
||||
id = games.GenerateRoomID(game.Name)
|
||||
}
|
||||
|
|
@ -110,7 +109,7 @@ func (r *Room) EnableAutosave(periodSec int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Room) whatsFrame(conf conf.Emulator) (ww int, hh int) {
|
||||
func (r *Room) whatsFrame(conf config.Emulator) (ww int, hh int) {
|
||||
w, h := r.emulator.GetFrameSize()
|
||||
// nwidth, nheight are the WebRTC output size
|
||||
var nwidth, nheight int
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/games"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/worker/emulator"
|
||||
|
|
@ -206,7 +205,7 @@ func dumpCanvas(frame *image2.Frame, name string, caption string, path string) {
|
|||
func getRoomMock(cfg roomMockConfig) roomMock {
|
||||
cfg.game.Path = cfg.gamesPath + cfg.game.Path
|
||||
|
||||
var conf worker.Config
|
||||
var conf config.WorkerConfig
|
||||
if err := config.LoadConfig(&conf, whereIsConfigs); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -249,7 +248,7 @@ func getRoomMock(cfg roomMockConfig) roomMock {
|
|||
|
||||
// fixEmulators makes absolute game paths in global GameList and passes GL context config.
|
||||
// hack: emulator paths should be absolute and visible to the tests.
|
||||
func fixEmulators(config *worker.Config, autoGlContext bool) {
|
||||
func fixEmulators(config *config.WorkerConfig, autoGlContext bool) {
|
||||
rootPath := getRootPath()
|
||||
|
||||
config.Emulator.Libretro.Cores.Paths.Libs =
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package worker
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config/worker"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/config"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/logger"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/monitoring"
|
||||
"github.com/giongto35/cloud-game/v3/pkg/network/httpx"
|
||||
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
type Worker struct {
|
||||
address string
|
||||
conf worker.Config
|
||||
conf config.WorkerConfig
|
||||
cord *coordinator
|
||||
log *logger.Logger
|
||||
router Router
|
||||
|
|
@ -23,7 +23,7 @@ type Worker struct {
|
|||
|
||||
const retry = 10 * time.Second
|
||||
|
||||
func New(conf worker.Config, log *logger.Logger, done chan struct{}) (services service.Group) {
|
||||
func New(conf config.WorkerConfig, log *logger.Logger, done chan struct{}) (services service.Group) {
|
||||
if err := remotehttp.CheckCores(conf.Emulator, log); err != nil {
|
||||
log.Error().Err(err).Msg("cores sync error")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue