Skip to content

Commit

Permalink
Add Chinese support (#45)
Browse files Browse the repository at this point in the history
* feat(/web/front): Add Chinese support

Add Chinese support

* feat(/web/front): Add Chinese support

Add Chinese support

* feat(/web/front): Optimize user interface

Optimize user interface and interaction logic

* fix(/web/front): fix bugs

fix bugs about Add Chinese support

* fix(front): fix bugs

fix bugs about adding Chinese support and data struct

* fix(front): fix bugs

fix bugs about adding Chinese support

* perf(front): perf user interface

perf user interface

* perf(front): perf user interface

perf user interface

* fix(front): fix bugs

fix bugs

* fix(front): fix bugs

fix bugs about adding Chinese support

* perf(/web/front): perf user interface

perf user interface

* perf: Simplified Configuration

Simplified Configuration

* fix: fix bugs

fix bugs about web
  • Loading branch information
AdachiAndShimamura authored Jan 30, 2024
1 parent 0280c62 commit 47f7186
Show file tree
Hide file tree
Showing 62 changed files with 3,810 additions and 12,263 deletions.
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

0 comments on commit 47f7186

Please sign in to comment.