Files
quake-kube/cmd/q3/app/server/server.go
Chris Marshall 2a599bcff5 Build standalone ioq3ded, fix asset timeout (#16)
When specifying `BUILD_STANDALONE=1` for ioq3ded, the default `com_homepath`, `com_basegame`, and `com_gamename` change to foo/foobar, so this sets those explicitly to their previously default values. This can be exposed via option later to allow for custom games. This also fixes the short read timeout used by CopyAssets.
2020-09-16 17:53:51 -04:00

93 lines
2.7 KiB
Go

package server
import (
"context"
"fmt"
"net/url"
"time"
"github.com/pkg/errors"
"github.com/spf13/cobra"
quakeclient "github.com/criticalstack/quake-kube/internal/quake/client"
"github.com/criticalstack/quake-kube/internal/quake/content"
quakeserver "github.com/criticalstack/quake-kube/internal/quake/server"
httputil "github.com/criticalstack/quake-kube/internal/util/net/http"
"github.com/criticalstack/quake-kube/public"
)
var opts struct {
ClientAddr string
ServerAddr string
ContentServer string
AcceptEula bool
AssetsDir string
ConfigFile string
WatchInterval time.Duration
}
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "server",
Short: "q3 server",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
csurl, err := url.Parse(opts.ContentServer)
if err != nil {
return err
}
if !opts.AcceptEula {
fmt.Println(quakeserver.Q3DemoEULA)
return errors.New("You must agree to the EULA to continue")
}
if err := httputil.GetUntil(opts.ContentServer, ctx.Done()); err != nil {
return err
}
// TODO(chrism): only download what is in map config
if err := content.CopyAssets(csurl, opts.AssetsDir); err != nil {
return err
}
go func() {
s := quakeserver.Server{
Dir: opts.AssetsDir,
WatchInterval: opts.WatchInterval,
ConfigFile: opts.ConfigFile,
Addr: opts.ServerAddr,
}
if err := s.Start(ctx); err != nil {
panic(err)
}
}()
e, err := quakeclient.NewRouter(&quakeclient.Config{
ContentServerURL: opts.ContentServer,
ServerAddr: opts.ServerAddr,
Files: public.Files,
})
if err != nil {
return err
}
s := &quakeclient.Server{
Addr: opts.ClientAddr,
Handler: e,
ServerAddr: opts.ServerAddr,
}
fmt.Printf("Starting server %s\n", opts.ClientAddr)
return s.ListenAndServe()
},
}
cmd.Flags().StringVarP(&opts.ConfigFile, "config", "c", "", "server configuration file")
cmd.Flags().StringVar(&opts.ContentServer, "content-server", "http://content.quakejs.com", "content server url")
cmd.Flags().BoolVar(&opts.AcceptEula, "agree-eula", false, "agree to the Quake 3 demo EULA")
cmd.Flags().StringVar(&opts.AssetsDir, "assets-dir", "assets", "location for game files")
cmd.Flags().StringVar(&opts.ClientAddr, "client-addr", "0.0.0.0:8080", "client address <host>:<port>")
cmd.Flags().StringVar(&opts.ServerAddr, "server-addr", "0.0.0.0:27960", "dedicated server <host>:<port>")
cmd.Flags().DurationVar(&opts.WatchInterval, "watch-interval", 15*time.Second, "dedicated server <host>:<port>")
return cmd
}