Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Chinese support #45

Merged
merged 15 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"net/netip"
"net/url"
"os"
"reflect"
"runtime/debug"
"strconv"
"strings"
Expand All @@ -54,6 +55,11 @@ import (
func New(args []string, out io.Writer) (c *Client, err error) {
conf := getDefaultConfig(args)
err = config.ParseFlags(args, &conf, &conf.Options)
conf.ConfigType = "client"
err = MergeConfig(&conf)
if err != nil {
return
}
if err != nil {
return
}
Expand Down Expand Up @@ -98,11 +104,25 @@ func New(args []string, out io.Writer) (c *Client, err error) {
c.webrtcThreadPool = webrtc.NewThreadPool(3)
return
}
func MergeConfig(cfg *Config) (err error) {
defaultConfig := DefaultConfig()
reflectedSavedConfig := reflect.ValueOf(&cfg.Options).Elem()
reflectedDefaultConfig := reflect.ValueOf(&defaultConfig.Options).Elem()

for i := 0; i < reflectedSavedConfig.NumField(); i++ {
field := reflectedSavedConfig.Field(i)
if field.IsZero() && field.Kind() != reflect.Slice && reflectedDefaultConfig.Field(i).IsZero() != true {
field.Set(reflectedDefaultConfig.Field(i))
}
}
return
}

func getDefaultConfig(args []string) (conf Config) {
if predef.IsNoArgs() {
conf = defaultConfigWithNoArgs()
} else {
conf = defaultConfig()
conf = DefaultConfig()
if util.Contains(args, "-webAddr") {
conf.Config = predef.GetDefaultClientConfigPath()
}
Expand Down
14 changes: 8 additions & 6 deletions client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ import (

// Config is a client config.
type Config struct {
Version string `yaml:"-" json:"-"` // 目前未使用
Services services
Version string `yaml:"-" json:"-"` // 目前未使用
ConfigType string `yaml:"type,omitempty"`
Services services
Options
}

Expand Down Expand Up @@ -66,7 +67,7 @@ type Options struct {
SentryDebug bool `yaml:"sentryDebug,omitempty" json:",omitempty" usage:"Sentry debug mode, the debug information is printed to help you understand what sentry is doing"`

WebRTCConnectionIdleTimeout config.Duration `yaml:"webrtcConnectionIdleTimeout,omitempty" usage:"The timeout of WebRTC connection. Supports values like '30s', '5m'"`
WebRTCRemoteConnections uint `yaml:"webrtcConnections" usage:"The max number of webrtc connections. Valid value is 1 to 50"`
WebRTCRemoteConnections uint `yaml:"webrtcConnections,omitempty" usage:"The max number of webrtc connections. Valid value is 1 to 50"`
WebRTCLogLevel string `yaml:"webrtcLogLevel,omitempty" json:",omitempty" usage:"WebRTC log level: verbose, info, warning, error"`
WebRTCMinPort uint16 `yaml:"webrtcMinPort,omitempty" json:",omitempty" usage:"The min port of WebRTC peer connection"`
WebRTCMaxPort uint16 `yaml:"webrtcMaxPort,omitempty" json:",omitempty" usage:"The max port of WebRTC peer connection"`
Expand All @@ -92,13 +93,14 @@ type Options struct {

Signal string `arg:"s" yaml:"-" json:"-" usage:"Send signal to client processes. Supports values: reload, restart, stop, kill"`

OpenBBR bool `yaml:"bbr" usage:"Use bbr as congestion control algorithm (through msquic) when GT use QUIC connection. Default algorithm is Cubic (through quic-go)."`
OpenBBR bool `yaml:"bbr,omitempty" usage:"Use bbr as congestion control algorithm (through msquic) when GT use QUIC connection. Default algorithm is Cubic (through quic-go)."`
}

// if you enable web service, it will set 'Config' if not specified

func defaultConfig() Config {
func DefaultConfig() Config {
return Config{
ConfigType: "Client",
Options: Options{
ReconnectDelay: config.Duration{Duration: 5 * time.Second},
RemoteTimeout: config.Duration{Duration: 45 * time.Second},
Expand All @@ -124,7 +126,7 @@ func defaultConfig() Config {
}

func defaultConfigWithNoArgs() Config {
conf := defaultConfig()
conf := DefaultConfig()
conf.Config = predef.GetDefaultClientConfigPath()
conf.WebAddr = "127.0.0.1:7000"
return conf
Expand Down
8 changes: 5 additions & 3 deletions client/web/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func ChangeUserInfo(c *client.Client) gin.HandlerFunc {
func GetUserInfo(c *client.Client) gin.HandlerFunc {
return func(ctx *gin.Context) {
var userInfo request.UserInfo
cfg, err := service.GetConfigFromFile(c)
cfg, err := service.GetMergedConfig(c)
if err != nil {
userInfo = request.UserInfo{
Username: cfg.Admin,
Expand All @@ -100,7 +100,8 @@ func GetUserInfo(c *client.Client) gin.HandlerFunc {
// GetMenu returns the permission menu based on the role of the user
func GetMenu(c *client.Client) gin.HandlerFunc {
return func(ctx *gin.Context) {
menu := service.GetMenu(c)
lang := ctx.Query("lang")
menu := service.GetMenu(c, lang)
response.SuccessWithData(menu, ctx)
}
}
Expand Down Expand Up @@ -141,7 +142,7 @@ func GetRunningConfig(c *client.Client) gin.HandlerFunc {
// if failed, try to fetch running config
func GetConfigFromFile(c *client.Client) gin.HandlerFunc {
return func(ctx *gin.Context) {
cfg, err := service.GetConfigFromFile(c)
cfg, err := service.GetMergedConfig(c)
c.Logger.Info().Msg("get config from file")
if err != nil {
c.Logger.Info().Msg("get config from file failed, try to fetch running config")
Expand Down Expand Up @@ -171,6 +172,7 @@ func SaveConfigToFile(c *client.Client) gin.HandlerFunc {
response.FailWithMessage(err.Error(), ctx)
return
}
service.SeparateConfig(&cfg)
fullPath, err := service.SaveConfigToFile(&cfg)
if err != nil {
response.FailWithMessage(err.Error(), ctx)
Expand Down
180 changes: 136 additions & 44 deletions client/web/service/service.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package service

import (
"bytes"
"errors"
"fmt"
"github.com/davecgh/go-spew/spew"
Expand All @@ -12,6 +13,7 @@ import (
"github.com/isrc-cas/gt/web/server/util"
"github.com/jinzhu/copier"
"github.com/shirou/gopsutil/v3/net"
"reflect"

"gopkg.in/yaml.v3"
"os"
Expand All @@ -38,6 +40,7 @@ func ChangeUserInfo(user request.UserInfo, c *client.Client) error {
conf4log := cfg
conf4log.Password = "******"
conf4log.SigningKey = "******"
SeparateConfig(&cfg)
_, err = SaveConfigToFile(&cfg)
if err != nil {
return err
Expand All @@ -46,50 +49,97 @@ func ChangeUserInfo(user request.UserInfo, c *client.Client) error {
return nil
}

func GetMenu(c *client.Client) (menu []request.Menu) {
menu = []request.Menu{
//Home
{
Path: "/home/index",
Name: "home",
Component: "/home/index",
Meta: request.MetaProps{
Icon: "HomeFilled",
Title: "Home",
IsHide: false,
IsFull: false,
IsAffix: true,
IsKeepAlive: false,
func GetMenu(c *client.Client, lang string) (menu []request.Menu) {
if lang == "zh" {
menu = []request.Menu{
//Home
{
Path: "/home/index",
Name: "home",
Component: "/home/index",
Meta: request.MetaProps{
Icon: "HomeFilled",
Title: "主页",
IsHide: false,
IsFull: false,
IsAffix: true,
IsKeepAlive: false,
},
},
},
//Connection
{
Path: "/connection",
Name: "connection",
Component: "/connection/index",
Meta: request.MetaProps{
Icon: "Connection",
Title: "Connection Status",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: false,
//Connection
{
Path: "/connection",
Name: "connection",
Component: "/connection/index",
Meta: request.MetaProps{
Icon: "Connection",
Title: "连接状态",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: false,
},
},
},
//Client Config
{
Path: "/config/client",
Name: "client",
Component: "/config/ClientConfig/index",
Meta: request.MetaProps{
Icon: "Setting",
Title: "Client",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: true,
//Client Config
{
Path: "/config/client",
Name: "client",
Component: "/config/ClientConfig/index",
Meta: request.MetaProps{
Icon: "Setting",
Title: "客户端",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: true,
},
},
},
}
} else {
menu = []request.Menu{
//Home
{
Path: "/home/index",
Name: "home",
Component: "/home/index",
Meta: request.MetaProps{
Icon: "HomeFilled",
Title: "Home",
IsHide: false,
IsFull: false,
IsAffix: true,
IsKeepAlive: false,
},
},
//Connection
{
Path: "/connection",
Name: "connection",
Component: "/connection/index",
Meta: request.MetaProps{
Icon: "Connection",
Title: "Connection Status",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: false,
},
},
//Client Config
{
Path: "/config/client",
Name: "client",
Component: "/config/ClientConfig/index",
Meta: request.MetaProps{
Icon: "Setting",
Title: "Client",
IsHide: false,
IsFull: false,
IsAffix: false,
IsKeepAlive: true,
},
},
}
}
//pprof
if c.Config().EnablePprof {
Expand Down Expand Up @@ -160,7 +210,10 @@ func GetConfigFromFile(c *client.Client) (cfg client.Config, err error) {
func SaveConfigToFile(cfg *client.Config) (fullPath string, err error) {

// switch config type to yaml
yamlData, err := yaml.Marshal(cfg)
buff := bytes.Buffer{}
yamlEncoder := yaml.NewEncoder(&buff)
yamlEncoder.SetIndent(2)
err = yamlEncoder.Encode(cfg)
if err != nil {
return
}
Expand All @@ -170,7 +223,7 @@ func SaveConfigToFile(cfg *client.Config) (fullPath string, err error) {
fullPath = predef.GetDefaultClientConfigPath()
cfg.Options.Config = fullPath
}
err = util2.WriteYamlToFile(fullPath, yamlData)
err = util2.WriteYamlToFile(fullPath, buff.Bytes())
if err != nil {
return
}
Expand All @@ -191,11 +244,12 @@ func InheritImmutableConfigFields(original *client.Config, new *client.Config) (
new.SigningKey = original.SigningKey
new.Admin = original.Admin
new.Password = original.Password
new.ConfigType = original.ConfigType
return
}
func InheritConfig(c *client.Client) (cfg client.Config, err error) {
// Get From File
cfg, err = GetConfigFromFile(c)
cfg, err = GetMergedConfig(c)
if err != nil {
// Get From Running
err = copier.Copy(&cfg, c.Config()) // SigningKey is also copied
Expand All @@ -205,3 +259,41 @@ func InheritConfig(c *client.Client) (cfg client.Config, err error) {
}
return
}
func GetMergedConfig(c *client.Client) (cfg client.Config, err error) {
cfg, err = GetConfigFromFile(c)
if err != nil {
return
}
defaultConfig := client.DefaultConfig()
reflectedSavedConfig := reflect.ValueOf(&cfg.Options).Elem()
reflectedDefaultConfig := reflect.ValueOf(&defaultConfig.Options).Elem()

for i := 0; i < reflectedSavedConfig.NumField(); i++ {
field := reflectedSavedConfig.Field(i)
if field.IsZero() && field.Kind() != reflect.Slice && reflectedDefaultConfig.Field(i).IsZero() != true {
reflectedSavedConfig.Field(i).Set(reflectedDefaultConfig.Field(i))
}
}
return
}

func SeparateConfig(newConfig *client.Config) {
defaultConfig := client.DefaultConfig()
reflectedNewConfig := reflect.ValueOf(&newConfig.Options).Elem()
reflectedOldConfig := reflect.ValueOf(&defaultConfig.Options).Elem()

for i := 0; i < reflectedNewConfig.NumField(); i++ {
field := reflectedNewConfig.Field(i)
if field.Kind() == reflect.Slice {
continue
}
if reflect.DeepEqual(reflectedNewConfig.Field(i).Interface(), reflectedOldConfig.Field(i).Interface()) {
field.SetZero()
}
}
for index := range newConfig.Services {
if newConfig.Services[index].RemoteTCPRandom != nil && *newConfig.Services[index].RemoteTCPRandom == false {
newConfig.Services[index].RemoteTCPRandom = nil
}
}
}
Loading
Loading