127 lines
3.5 KiB
Go
127 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jinzhu/gorm"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/echo/v4/middleware"
|
|
"github.com/labstack/gommon/log"
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/libretro/netplay-lobby-server-go/controller"
|
|
"github.com/libretro/netplay-lobby-server-go/domain"
|
|
"github.com/libretro/netplay-lobby-server-go/model"
|
|
"github.com/libretro/netplay-lobby-server-go/model/entity"
|
|
"github.com/libretro/netplay-lobby-server-go/model/repository"
|
|
)
|
|
|
|
func main() {
|
|
var verbose = flag.Bool("v", false, "详细日志记录")
|
|
flag.Parse()
|
|
|
|
server := echo.New()
|
|
server.HideBanner = true
|
|
server.Server.ReadTimeout = 5 * time.Second
|
|
server.Server.WriteTimeout = 5 * time.Second
|
|
|
|
config, err := readConfig()
|
|
if err != nil {
|
|
server.Logger.Fatalf("无法获取配置值: %v", err)
|
|
}
|
|
|
|
// 初始化领域逻辑和模型
|
|
db, err := initDatabase(config.Database.Type, config.Database.Connection)
|
|
if err != nil {
|
|
server.Logger.Fatalf("无法初始化数据库: %v", err)
|
|
}
|
|
db = db.AutoMigrate(&entity.Session{})
|
|
|
|
if *verbose {
|
|
server.Logger.SetLevel(log.INFO)
|
|
} else {
|
|
server.Logger.SetLevel(log.WARN)
|
|
}
|
|
|
|
sessionDomain, err := initDomain(db, config)
|
|
if err != nil {
|
|
server.Logger.Fatalf("无法初始化领域逻辑: %v", err)
|
|
}
|
|
|
|
sessionCotroller := controller.NewSessionController(sessionDomain)
|
|
|
|
// 启动清理作业以清除旧会话
|
|
go func() {
|
|
for true {
|
|
err := sessionDomain.PurgeOld()
|
|
if err != nil {
|
|
server.Logger.Fatalf("无法清除旧会话: %v", err)
|
|
}
|
|
time.Sleep(2 * time.Minute)
|
|
}
|
|
}()
|
|
|
|
// 服务器设置
|
|
server.Use(middleware.Logger())
|
|
server.Use(middleware.Recover())
|
|
server.Use(middleware.BodyLimit("64K"))
|
|
|
|
// 设置路由和预渲染模板
|
|
sessionCotroller.RegisterRoutes(server)
|
|
templatePath := fmt.Sprintf("%s/*.html", config.Server.TemplatePath)
|
|
if err = sessionCotroller.PrerenderTemplates(server, templatePath); err != nil {
|
|
server.Logger.Fatalf("无法预渲染模板: %v", err)
|
|
}
|
|
|
|
// 开始服务
|
|
server.Logger.Fatal(server.Start(config.Server.Address))
|
|
}
|
|
|
|
func readConfig() (*Config, error) {
|
|
viper := viper.New()
|
|
viper.SetConfigName("lobby")
|
|
viper.SetConfigType("yaml")
|
|
viper.AddConfigPath("/etc/lobby")
|
|
viper.AddConfigPath("$HOME/.lobby")
|
|
viper.AddConfigPath("./config")
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
return nil, fmt.Errorf("无法读取配置文件: %w", err)
|
|
}
|
|
var conf Config
|
|
if err := viper.Unmarshal(&conf); err != nil {
|
|
return nil, fmt.Errorf("无法解组配置文件: %w", err)
|
|
}
|
|
return &conf, nil
|
|
}
|
|
|
|
func initDatabase(databaseType string, connectionString string) (*gorm.DB, error) {
|
|
switch databaseType {
|
|
case "mysql":
|
|
return model.GetMysqlDB(connectionString)
|
|
case "postgres":
|
|
return model.GetPostgreDB(connectionString)
|
|
case "sqlite":
|
|
return model.GetSqliteDB(connectionString)
|
|
}
|
|
|
|
return nil, fmt.Errorf("配置中未知的数据库类型: %s", databaseType)
|
|
}
|
|
|
|
func initDomain(db *gorm.DB, config *Config) (*domain.SessionDomain, error) {
|
|
repo := repository.NewSessionRepository(db)
|
|
geo2Domain, err := domain.NewGeoIP2Domain(config.Server.GeoLite2Path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("无法初始化 GeoLite2 数据库: %w", err)
|
|
}
|
|
validationDomain, err := domain.NewValidationDomain(config.Blacklist.Strings, config.Blacklist.IPs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("无法初始化验证域: %w", err)
|
|
}
|
|
mitmDomain := domain.NewMitmDomain(config.Relay)
|
|
sessionDomain := domain.NewSessionDomain(repo, geo2Domain, validationDomain, mitmDomain)
|
|
|
|
return sessionDomain, nil
|
|
}
|