feat: 重构配置层,添加 json 支持
This commit is contained in:
69
internal/config/config.go
Normal file
69
internal/config/config.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/config/flags"
|
||||
"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
|
||||
"github.com/Mmx233/tool"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ConfFromFile struct {
|
||||
Form srun.LoginForm `json:"form" yaml:"form"`
|
||||
Meta srun.LoginMeta `json:"meta" yaml:"meta"`
|
||||
Settings SettingsConf `json:"settings" yaml:"settings"`
|
||||
}
|
||||
|
||||
var (
|
||||
Form *srun.LoginForm
|
||||
Meta *srun.LoginMeta
|
||||
Settings *SettingsConf
|
||||
|
||||
Timeout time.Duration
|
||||
)
|
||||
|
||||
func init() {
|
||||
reader := newReaderFromPath(flags.Path)
|
||||
|
||||
// 生成配置文件
|
||||
exist, err := tool.File.Exists(flags.Path)
|
||||
if err != nil {
|
||||
log.Fatalln("[init] 读取配置文件失败:", err)
|
||||
} else if !exist {
|
||||
var data []byte
|
||||
data, err = reader.Marshal(&defaultConfig)
|
||||
if err != nil {
|
||||
log.Fatalln("[init] 生成配置文件失败:", err)
|
||||
}
|
||||
if err = os.WriteFile(flags.Path, data, 0600); err != nil {
|
||||
log.Fatalln("[init] 写入配置文件失败:", err)
|
||||
}
|
||||
log.Infoln("[init] 已生成配置文件,请编辑 '" + flags.Path + "' 然后重试")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
data, err := os.ReadFile(flags.Path)
|
||||
if err != nil {
|
||||
log.Fatalln("[init] 读取配置失败:", err)
|
||||
}
|
||||
var fileConf ConfFromFile
|
||||
if err = reader.Unmarshal(data, &fileConf); err != nil {
|
||||
log.Fatalln("[init] 解析配置失败:", err)
|
||||
}
|
||||
Form = &fileConf.Form
|
||||
Meta = &fileConf.Meta
|
||||
Settings = &fileConf.Settings
|
||||
Timeout = time.Duration(Settings.Basic.Timeout) * time.Second
|
||||
|
||||
// flag 配置覆写
|
||||
if flags.Debug {
|
||||
Settings.Log.DebugLevel = true
|
||||
}
|
||||
if flags.Acid != "" {
|
||||
Meta.Acid = flags.Acid
|
||||
}
|
||||
|
||||
initLog()
|
||||
}
|
||||
39
internal/config/default.go
Normal file
39
internal/config/default.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
|
||||
)
|
||||
|
||||
var defaultConfig = ConfFromFile{
|
||||
Form: srun.LoginForm{
|
||||
Domain: "www.msftconnecttest.com",
|
||||
UserType: "cmcc",
|
||||
},
|
||||
Meta: srun.LoginMeta{
|
||||
N: "200",
|
||||
Type: "1",
|
||||
Acid: "5",
|
||||
Enc: "srun_bx1",
|
||||
},
|
||||
Settings: SettingsConf{
|
||||
Basic: BasicConf{
|
||||
Timeout: 5,
|
||||
},
|
||||
Guardian: GuardianConf{
|
||||
Duration: 300,
|
||||
},
|
||||
Log: LogConf{
|
||||
FilePath: "./",
|
||||
},
|
||||
DDNS: DdnsConf{
|
||||
Enable: false,
|
||||
TTL: 600,
|
||||
Domain: "www.example.com",
|
||||
Provider: "cloudflare",
|
||||
Config: map[string]interface{}{
|
||||
"zone": "",
|
||||
"token": "",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
26
internal/config/flags/flags.go
Normal file
26
internal/config/flags/flags.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package flags
|
||||
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
var (
|
||||
// Path 配置文件路径
|
||||
Path string
|
||||
|
||||
Interface string
|
||||
Debug bool
|
||||
AutoAcid bool
|
||||
Acid string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&Path, "config", "Config.yaml", "config path")
|
||||
|
||||
flag.StringVar(&Interface, "interface", "", "specify the eth name")
|
||||
flag.BoolVar(&Debug, "debug", false, "enable debug mode")
|
||||
flag.BoolVar(&AutoAcid, "auto-acid", false, "auto detect acid")
|
||||
flag.StringVar(&Acid, "acid", "", "specify acid value")
|
||||
|
||||
flag.Parse()
|
||||
}
|
||||
48
internal/config/log.go
Normal file
48
internal/config/log.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
nested "github.com/antonfisher/nested-logrus-formatter"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func initLog() {
|
||||
if Settings.Log.DebugLevel {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
if Settings.Log.WriteFile {
|
||||
//日志路径初始化与处理
|
||||
if !strings.HasSuffix(Settings.Log.FilePath, "/") {
|
||||
Settings.Log.FilePath += "/"
|
||||
}
|
||||
e := os.MkdirAll(Settings.Log.FilePath, os.ModePerm)
|
||||
if e != nil {
|
||||
log.Fatalln(e)
|
||||
}
|
||||
|
||||
if Settings.Log.FileName == "" {
|
||||
Settings.Log.FileName = time.Now().Format("2006.01.02-15.04.05") + ".log"
|
||||
}
|
||||
|
||||
f, e := os.OpenFile(Settings.Log.FilePath+Settings.Log.FileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
|
||||
if e != nil {
|
||||
log.Fatalln(e)
|
||||
}
|
||||
|
||||
//设置双重输出
|
||||
mw := io.MultiWriter(os.Stdout, f)
|
||||
log.SetOutput(mw)
|
||||
|
||||
//设置输出格式
|
||||
log.SetFormatter(&nested.Formatter{
|
||||
HideKeys: true,
|
||||
NoColors: Settings.Log.WriteFile,
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
})
|
||||
}
|
||||
}
|
||||
37
internal/config/models.go
Normal file
37
internal/config/models.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package config
|
||||
|
||||
type (
|
||||
GuardianConf struct {
|
||||
Enable bool `json:"enable" yaml:"enable"`
|
||||
Duration uint `json:"duration" yaml:"duration"`
|
||||
}
|
||||
|
||||
BasicConf struct {
|
||||
Https bool `json:"https" yaml:"https"`
|
||||
SkipCertVerify bool `json:"skip_cert_verify" yaml:"skip_cert_verify"`
|
||||
Timeout uint `json:"timeout" yaml:"timeout"`
|
||||
Interfaces string `json:"interfaces" yaml:"interfaces"`
|
||||
}
|
||||
|
||||
LogConf struct {
|
||||
DebugLevel bool `json:"debug_level" yaml:"debug_level"`
|
||||
WriteFile bool `json:"write_file" yaml:"write_file"`
|
||||
FilePath string `json:"file_path" yaml:"log_path"`
|
||||
FileName string `json:"file_name" yaml:"log_name"`
|
||||
}
|
||||
|
||||
DdnsConf struct {
|
||||
Enable bool `json:"enable" yaml:"enable"`
|
||||
TTL uint `json:"ttl" yaml:"ttl"`
|
||||
Domain string `json:"domain" yaml:"domain"`
|
||||
Provider string `json:"provider" yaml:"provider"`
|
||||
Config map[string]interface{} `json:"config" json:"config" yaml:"config"`
|
||||
}
|
||||
)
|
||||
|
||||
type SettingsConf struct {
|
||||
Basic BasicConf `json:"basic" yaml:"basic"`
|
||||
Guardian GuardianConf `json:"guardian" yaml:"guardian"`
|
||||
Log LogConf `json:"log" yaml:"log"`
|
||||
DDNS DdnsConf `json:"ddns" yaml:"ddns"`
|
||||
}
|
||||
45
internal/config/reader.go
Normal file
45
internal/config/reader.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
"path"
|
||||
)
|
||||
|
||||
func newReaderFromPath(pathname string) Reader {
|
||||
switch path.Ext(pathname) {
|
||||
case ".json":
|
||||
return Json{}
|
||||
case ".yaml":
|
||||
return Yaml{}
|
||||
default:
|
||||
log.Warnf("未知配置类型,使用 yaml 进行解析")
|
||||
return Yaml{}
|
||||
}
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
Marshal(v any) ([]byte, error)
|
||||
Unmarshal(data []byte, v any) error
|
||||
}
|
||||
|
||||
type Json struct {
|
||||
}
|
||||
|
||||
func (Json) Marshal(v any) ([]byte, error) {
|
||||
return json.MarshalIndent(v, "", " ")
|
||||
}
|
||||
func (Json) Unmarshal(data []byte, v any) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
type Yaml struct {
|
||||
}
|
||||
|
||||
func (Yaml) Marshal(v any) ([]byte, error) {
|
||||
return yaml.Marshal(v)
|
||||
}
|
||||
func (Yaml) Unmarshal(data []byte, v any) error {
|
||||
return yaml.Unmarshal(data, v)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/global"
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/config"
|
||||
"time"
|
||||
|
||||
"github.com/Mmx233/BitSrunLoginGo/tools"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func Guardian() {
|
||||
log.Infoln("[以守护模式启动]")
|
||||
|
||||
GuardianDuration := time.Duration(global.Config.Settings.Guardian.Duration) * time.Second
|
||||
GuardianDuration := time.Duration(config.Settings.Guardian.Duration) * time.Second
|
||||
|
||||
var c = make(chan bool)
|
||||
for {
|
||||
@@ -20,13 +20,13 @@ func Guardian() {
|
||||
defer func() {
|
||||
_ = recover()
|
||||
}()
|
||||
if global.Config.Settings.Basic.Interfaces == "" { //单网卡
|
||||
if config.Settings.Basic.Interfaces == "" { //单网卡
|
||||
e := Login(nil, true)
|
||||
if e != nil {
|
||||
log.Errorln("登录出错: ", e)
|
||||
}
|
||||
} else { //多网卡
|
||||
interfaces, e := tools.GetInterfaceAddr(global.Config.Settings.Basic.Interfaces)
|
||||
interfaces, e := tools.GetInterfaceAddr(config.Settings.Basic.Interfaces)
|
||||
if e == nil {
|
||||
for _, eth := range interfaces {
|
||||
log.Debugf("使用 %s 网口登录 ", eth.Name)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/global"
|
||||
"errors"
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/config"
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/config/flags"
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/pkg/dns"
|
||||
"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
|
||||
"github.com/Mmx233/BitSrunLoginGo/tools"
|
||||
@@ -14,23 +16,23 @@ func Login(eth *tools.Eth, debugOutput bool) error {
|
||||
// 登录配置初始化
|
||||
httpClient := tools.HttpPackSelect(eth).Client
|
||||
srunClient := srun.New(&srun.Conf{
|
||||
Https: global.Config.Settings.Basic.Https,
|
||||
Https: config.Settings.Basic.Https,
|
||||
LoginInfo: srun.LoginInfo{
|
||||
Form: global.Config.Form,
|
||||
Meta: global.Config.Meta,
|
||||
Form: *config.Form,
|
||||
Meta: *config.Meta,
|
||||
},
|
||||
Client: httpClient,
|
||||
})
|
||||
|
||||
// 嗅探 acid
|
||||
if global.Flags.AutoAcid {
|
||||
if flags.AutoAcid {
|
||||
log.Debugln("开始嗅探 acid")
|
||||
acid, e := srunClient.DetectAcid()
|
||||
if e != nil {
|
||||
if e == srun.ErrAcidCannotFound {
|
||||
acid, err := srunClient.DetectAcid()
|
||||
if err != nil {
|
||||
if errors.Is(err, srun.ErrAcidCannotFound) {
|
||||
log.Errorln("找不到 acid,使用配置 acid")
|
||||
} else {
|
||||
log.Errorf("嗅探 acid 失败,使用配置 acid: %v", e)
|
||||
log.Errorf("嗅探 acid 失败,使用配置 acid: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Debugf("使用嗅探 acid: %s", acid)
|
||||
@@ -60,7 +62,7 @@ func Login(eth *tools.Eth, debugOutput bool) error {
|
||||
if online {
|
||||
output("已登录~")
|
||||
|
||||
if global.Config.Settings.DDNS.Enable && global.Config.Settings.Guardian.Enable && ipLast != ip {
|
||||
if config.Settings.DDNS.Enable && config.Settings.Guardian.Enable && ipLast != ip {
|
||||
if ddns(ip, httpClient) == nil {
|
||||
ipLast = ip
|
||||
}
|
||||
@@ -76,7 +78,7 @@ func Login(eth *tools.Eth, debugOutput bool) error {
|
||||
|
||||
log.Infoln("登录成功~")
|
||||
|
||||
if global.Config.Settings.DDNS.Enable {
|
||||
if config.Settings.DDNS.Enable {
|
||||
_ = ddns(ip, httpClient)
|
||||
}
|
||||
}
|
||||
@@ -88,11 +90,11 @@ var ipLast string
|
||||
|
||||
func ddns(ip string, httpClient *http.Client) error {
|
||||
return dns.Run(&dns.Config{
|
||||
Provider: global.Config.Settings.DDNS.Provider,
|
||||
Provider: config.Settings.DDNS.Provider,
|
||||
IP: ip,
|
||||
Domain: global.Config.Settings.DDNS.Domain,
|
||||
TTL: global.Config.Settings.DDNS.TTL,
|
||||
Conf: global.Config.Settings.DDNS.Config,
|
||||
Domain: config.Settings.DDNS.Domain,
|
||||
TTL: config.Settings.DDNS.TTL,
|
||||
Conf: config.Settings.DDNS.Config,
|
||||
Http: httpClient,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/internal/global/models"
|
||||
"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
|
||||
"github.com/Mmx233/tool"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Config models.Config
|
||||
|
||||
var Timeout time.Duration
|
||||
|
||||
func createDefaultConfig() error {
|
||||
configFile, err := os.OpenFile(Flags.Path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
return yaml.NewEncoder(configFile).Encode(&models.Config{
|
||||
Form: srun.LoginForm{
|
||||
Domain: "www.msftconnecttest.com",
|
||||
UserType: "cmcc",
|
||||
},
|
||||
Meta: srun.LoginMeta{
|
||||
N: "200",
|
||||
Type: "1",
|
||||
Acid: "5",
|
||||
Enc: "srun_bx1",
|
||||
},
|
||||
Settings: models.Settings{
|
||||
Basic: models.Basic{
|
||||
Timeout: 5,
|
||||
},
|
||||
Guardian: models.Guardian{
|
||||
Duration: 300,
|
||||
},
|
||||
Log: models.Log{
|
||||
FilePath: "./",
|
||||
},
|
||||
DDNS: models.DDNS{
|
||||
Enable: false,
|
||||
TTL: 600,
|
||||
Domain: "www.example.com",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
// 生成配置文件
|
||||
if exist, err := tool.File.Exists(Flags.Path); err != nil {
|
||||
log.Fatalln("[init] 读取配置文件失败:", err)
|
||||
} else if !exist {
|
||||
err = createDefaultConfig()
|
||||
if err != nil {
|
||||
log.Fatalln("[init] 生成配置文件失败:", err)
|
||||
}
|
||||
log.Infoln("[init] 已生成配置文件,请编辑 '" + Flags.Path + "' 然后重试")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
configBytes, err := os.ReadFile(Flags.Path)
|
||||
if err != nil {
|
||||
log.Fatalln("[init] 读取配置失败:", err)
|
||||
}
|
||||
if err = yaml.Unmarshal(configBytes, &Config); err != nil {
|
||||
log.Fatalln("[init] 解析配置失败:", err)
|
||||
}
|
||||
|
||||
// flag 配置覆写
|
||||
if Flags.Debug {
|
||||
Config.Settings.Log.DebugLevel = true
|
||||
}
|
||||
if Flags.Acid != "" {
|
||||
Config.Meta.Acid = Flags.Acid
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
var Flags struct {
|
||||
// 配置文件路径
|
||||
Path string
|
||||
|
||||
// settings overwrite
|
||||
Interface string
|
||||
Debug bool
|
||||
AutoAcid bool
|
||||
Acid string
|
||||
}
|
||||
|
||||
func initFlags() {
|
||||
flag.StringVar(&Flags.Path, "config", "Config.yaml", "config path")
|
||||
|
||||
flag.StringVar(&Flags.Interface, "interface", "", "specify the eth name")
|
||||
flag.BoolVar(&Flags.Debug, "debug", false, "enable debug mode")
|
||||
flag.BoolVar(&Flags.AutoAcid, "auto-acid", false, "auto detect acid")
|
||||
flag.StringVar(&Flags.Acid, "acid", "", "specify acid value")
|
||||
|
||||
flag.Parse()
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
initFlags()
|
||||
|
||||
//配置文件初始化
|
||||
initConfig()
|
||||
|
||||
//初始化常变量
|
||||
Timeout = time.Duration(Config.Settings.Basic.Timeout) * time.Second
|
||||
|
||||
//初始化日志配置
|
||||
initLog()
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
nested "github.com/antonfisher/nested-logrus-formatter"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func initLog() {
|
||||
if Config.Settings.Log.DebugLevel {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
if Config.Settings.Log.WriteFile {
|
||||
//日志路径初始化与处理
|
||||
if !strings.HasSuffix(Config.Settings.Log.FilePath, "/") {
|
||||
Config.Settings.Log.FilePath += "/"
|
||||
}
|
||||
e := os.MkdirAll(Config.Settings.Log.FilePath, os.ModePerm)
|
||||
if e != nil {
|
||||
log.Fatalln(e)
|
||||
}
|
||||
|
||||
if Config.Settings.Log.FileName == "" {
|
||||
Config.Settings.Log.FileName = time.Now().Format("2006.01.02-15.04.05") + ".log"
|
||||
}
|
||||
|
||||
f, e := os.OpenFile(Config.Settings.Log.FilePath+Config.Settings.Log.FileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
|
||||
if e != nil {
|
||||
log.Fatalln(e)
|
||||
}
|
||||
|
||||
//设置双重输出
|
||||
mw := io.MultiWriter(os.Stdout, f)
|
||||
log.SetOutput(mw)
|
||||
|
||||
//设置输出格式
|
||||
log.SetFormatter(&nested.Formatter{
|
||||
HideKeys: true,
|
||||
NoColors: Config.Settings.Log.WriteFile,
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
|
||||
)
|
||||
|
||||
type Guardian struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
Duration uint `yaml:"duration"`
|
||||
}
|
||||
|
||||
type Basic struct {
|
||||
Https bool `yaml:"https"`
|
||||
SkipCertVerify bool `yaml:"skip_cert_verify"`
|
||||
Timeout uint `yaml:"timeout"`
|
||||
Interfaces string `yaml:"interfaces"`
|
||||
}
|
||||
|
||||
type Log struct {
|
||||
DebugLevel bool `yaml:"debug_level"`
|
||||
WriteFile bool `yaml:"write_file"`
|
||||
FilePath string `yaml:"log_path"`
|
||||
FileName string `yaml:"log_name"`
|
||||
}
|
||||
|
||||
type DDNS struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
TTL uint `yaml:"ttl"`
|
||||
Domain string `yaml:"domain"`
|
||||
Provider string `yaml:"provider"`
|
||||
Config map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
Basic Basic `yaml:"basic"`
|
||||
Guardian Guardian `yaml:"guardian"`
|
||||
Log Log `yaml:"log"`
|
||||
DDNS DDNS `yaml:"ddns"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Form srun.LoginForm `yaml:"form"`
|
||||
Meta srun.LoginMeta `yaml:"meta"`
|
||||
Settings Settings `yaml:"settings"`
|
||||
}
|
||||
Reference in New Issue
Block a user