mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
342 lines
10 KiB
Go
342 lines
10 KiB
Go
// Package config 包含go-cqhttp操作配置文件的相关函数
|
||
package config
|
||
|
||
import (
|
||
"bufio"
|
||
_ "embed" // embed the default config file
|
||
"fmt"
|
||
"os"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||
|
||
log "github.com/sirupsen/logrus"
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// defaultConfig 默认配置文件
|
||
//go:embed default_config.yml
|
||
var defaultConfig string
|
||
|
||
// Reconnect 重连配置
|
||
type Reconnect struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Delay uint `yaml:"delay"`
|
||
MaxTimes uint `yaml:"max-times"`
|
||
Interval int `yaml:"interval"`
|
||
}
|
||
|
||
// Account 账号配置
|
||
type Account struct {
|
||
Uin int64 `yaml:"uin"`
|
||
Password string `yaml:"password"`
|
||
Encrypt bool `yaml:"encrypt"`
|
||
Status int `yaml:"status"`
|
||
ReLogin *Reconnect `yaml:"relogin"`
|
||
UseSSOAddress bool `yaml:"use-sso-address"`
|
||
}
|
||
|
||
// Config 总配置文件
|
||
type Config struct {
|
||
Account *Account `yaml:"account"`
|
||
Heartbeat struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Interval int `yaml:"interval"`
|
||
} `yaml:"heartbeat"`
|
||
|
||
Message struct {
|
||
PostFormat string `yaml:"post-format"`
|
||
ProxyRewrite string `yaml:"proxy-rewrite"`
|
||
IgnoreInvalidCQCode bool `yaml:"ignore-invalid-cqcode"`
|
||
ForceFragment bool `yaml:"force-fragment"`
|
||
FixURL bool `yaml:"fix-url"`
|
||
ReportSelfMessage bool `yaml:"report-self-message"`
|
||
RemoveReplyAt bool `yaml:"remove-reply-at"`
|
||
ExtraReplyData bool `yaml:"extra-reply-data"`
|
||
SkipMimeScan bool `yaml:"skip-mime-scan"`
|
||
} `yaml:"message"`
|
||
|
||
Output struct {
|
||
LogLevel string `yaml:"log-level"`
|
||
LogAging int `yaml:"log-aging"`
|
||
LogForceNew bool `yaml:"log-force-new"`
|
||
Debug bool `yaml:"debug"`
|
||
} `yaml:"output"`
|
||
|
||
Servers []map[string]yaml.Node `yaml:"servers"`
|
||
Database map[string]yaml.Node `yaml:"database"`
|
||
}
|
||
|
||
// MiddleWares 通信中间件
|
||
type MiddleWares struct {
|
||
AccessToken string `yaml:"access-token"`
|
||
Filter string `yaml:"filter"`
|
||
RateLimit struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
Frequency float64 `yaml:"frequency"`
|
||
Bucket int `yaml:"bucket"`
|
||
} `yaml:"rate-limit"`
|
||
}
|
||
|
||
// HTTPServer HTTP通信相关配置
|
||
type HTTPServer struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Host string `yaml:"host"`
|
||
Port int `yaml:"port"`
|
||
Timeout int32 `yaml:"timeout"`
|
||
LongPolling struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
MaxQueueSize int `yaml:"max-queue-size"`
|
||
} `yaml:"long-polling"`
|
||
Post []struct {
|
||
URL string `yaml:"url"`
|
||
Secret string `yaml:"secret"`
|
||
}
|
||
|
||
MiddleWares `yaml:"middlewares"`
|
||
}
|
||
|
||
// PprofServer pprof性能分析服务器相关配置
|
||
type PprofServer struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Host string `yaml:"host"`
|
||
Port int `yaml:"port"`
|
||
}
|
||
|
||
// WebsocketServer 正向WS相关配置
|
||
type WebsocketServer struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Host string `yaml:"host"`
|
||
Port int `yaml:"port"`
|
||
|
||
MiddleWares `yaml:"middlewares"`
|
||
}
|
||
|
||
// WebsocketReverse 反向WS相关配置
|
||
type WebsocketReverse struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Universal string `yaml:"universal"`
|
||
API string `yaml:"api"`
|
||
Event string `yaml:"event"`
|
||
ReconnectInterval int `yaml:"reconnect-interval"`
|
||
|
||
MiddleWares `yaml:"middlewares"`
|
||
}
|
||
|
||
// LambdaServer 云函数配置
|
||
type LambdaServer struct {
|
||
Disabled bool `yaml:"disabled"`
|
||
Type string `yaml:"type"`
|
||
|
||
MiddleWares `yaml:"middlewares"`
|
||
}
|
||
|
||
// LevelDBConfig leveldb 相关配置
|
||
type LevelDBConfig struct {
|
||
Enable bool `yaml:"enable"`
|
||
}
|
||
|
||
type MongoDBConfig struct {
|
||
Enable bool `yaml:"enable"`
|
||
Uri string `yaml:"uri"`
|
||
Database string `yaml:"database"`
|
||
}
|
||
|
||
// Parse 从默认配置文件路径中获取
|
||
func Parse(path string) *Config {
|
||
fromEnv := os.Getenv("GCQ_UIN") != ""
|
||
|
||
file, err := os.Open(path)
|
||
config := &Config{}
|
||
if err == nil {
|
||
defer func() { _ = file.Close() }()
|
||
if err = yaml.NewDecoder(file).Decode(config); err != nil && !fromEnv {
|
||
log.Fatal("配置文件不合法!", err)
|
||
}
|
||
} else if !fromEnv {
|
||
generateConfig()
|
||
os.Exit(0)
|
||
}
|
||
if fromEnv {
|
||
// type convert tools
|
||
toInt64 := func(str string) int64 {
|
||
i, _ := strconv.ParseInt(str, 10, 64)
|
||
return i
|
||
}
|
||
|
||
// load config from environment variable
|
||
param.SetAtDefault(&config.Account.Uin, toInt64(os.Getenv("GCQ_UIN")), int64(0))
|
||
param.SetAtDefault(&config.Account.Password, os.Getenv("GCQ_PWD"), "")
|
||
param.SetAtDefault(&config.Account.Status, int32(toInt64(os.Getenv("GCQ_STATUS"))), int32(0))
|
||
param.SetAtDefault(&config.Account.ReLogin.Disabled, !param.EnsureBool(os.Getenv("GCQ_RELOGIN_DISABLED"), true), false)
|
||
param.SetAtDefault(&config.Account.ReLogin.Delay, uint(toInt64(os.Getenv("GCQ_RELOGIN_DELAY"))), uint(0))
|
||
param.SetAtDefault(&config.Account.ReLogin.MaxTimes, uint(toInt64(os.Getenv("GCQ_RELOGIN_MAX_TIMES"))), uint(0))
|
||
dbConf := &LevelDBConfig{Enable: param.EnsureBool(os.Getenv("GCQ_LEVELDB"), true)}
|
||
if config.Database == nil {
|
||
config.Database = make(map[string]yaml.Node)
|
||
}
|
||
config.Database["leveldb"] = func() yaml.Node {
|
||
n := &yaml.Node{}
|
||
_ = n.Encode(dbConf)
|
||
return *n
|
||
}()
|
||
accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN")
|
||
if os.Getenv("GCQ_HTTP_PORT") != "" {
|
||
node := &yaml.Node{}
|
||
httpConf := &HTTPServer{
|
||
Host: "0.0.0.0",
|
||
Port: 5700,
|
||
MiddleWares: MiddleWares{
|
||
AccessToken: accessTokenEnv,
|
||
},
|
||
}
|
||
param.SetExcludeDefault(&httpConf.Disabled, param.EnsureBool(os.Getenv("GCQ_HTTP_DISABLE"), false), false)
|
||
param.SetExcludeDefault(&httpConf.Host, os.Getenv("GCQ_HTTP_HOST"), "")
|
||
param.SetExcludeDefault(&httpConf.Port, int(toInt64(os.Getenv("GCQ_HTTP_PORT"))), 0)
|
||
if os.Getenv("GCQ_HTTP_POST_URL") != "" {
|
||
httpConf.Post = append(httpConf.Post, struct {
|
||
URL string `yaml:"url"`
|
||
Secret string `yaml:"secret"`
|
||
}{os.Getenv("GCQ_HTTP_POST_URL"), os.Getenv("GCQ_HTTP_POST_SECRET")})
|
||
}
|
||
_ = node.Encode(httpConf)
|
||
config.Servers = append(config.Servers, map[string]yaml.Node{"http": *node})
|
||
}
|
||
if os.Getenv("GCQ_WS_PORT") != "" {
|
||
node := &yaml.Node{}
|
||
wsServerConf := &WebsocketServer{
|
||
Host: "0.0.0.0",
|
||
Port: 6700,
|
||
MiddleWares: MiddleWares{
|
||
AccessToken: accessTokenEnv,
|
||
},
|
||
}
|
||
param.SetExcludeDefault(&wsServerConf.Disabled, param.EnsureBool(os.Getenv("GCQ_WS_DISABLE"), false), false)
|
||
param.SetExcludeDefault(&wsServerConf.Host, os.Getenv("GCQ_WS_HOST"), "")
|
||
param.SetExcludeDefault(&wsServerConf.Port, int(toInt64(os.Getenv("GCQ_WS_PORT"))), 0)
|
||
_ = node.Encode(wsServerConf)
|
||
config.Servers = append(config.Servers, map[string]yaml.Node{"ws": *node})
|
||
}
|
||
if os.Getenv("GCQ_RWS_API") != "" || os.Getenv("GCQ_RWS_EVENT") != "" || os.Getenv("GCQ_RWS_UNIVERSAL") != "" {
|
||
node := &yaml.Node{}
|
||
rwsConf := &WebsocketReverse{
|
||
MiddleWares: MiddleWares{
|
||
AccessToken: accessTokenEnv,
|
||
},
|
||
}
|
||
param.SetExcludeDefault(&rwsConf.Disabled, param.EnsureBool(os.Getenv("GCQ_RWS_DISABLE"), false), false)
|
||
param.SetExcludeDefault(&rwsConf.API, os.Getenv("GCQ_RWS_API"), "")
|
||
param.SetExcludeDefault(&rwsConf.Event, os.Getenv("GCQ_RWS_EVENT"), "")
|
||
param.SetExcludeDefault(&rwsConf.Universal, os.Getenv("GCQ_RWS_UNIVERSAL"), "")
|
||
_ = node.Encode(rwsConf)
|
||
config.Servers = append(config.Servers, map[string]yaml.Node{"ws-reverse": *node})
|
||
}
|
||
}
|
||
return config
|
||
}
|
||
|
||
// generateConfig 生成配置文件
|
||
func generateConfig() {
|
||
fmt.Println("未找到配置文件,正在为您生成配置文件中!")
|
||
sb := strings.Builder{}
|
||
sb.WriteString(defaultConfig)
|
||
fmt.Print(`请选择你需要的通信方式:
|
||
> 1: HTTP通信
|
||
> 2: 正向 Websocket 通信
|
||
> 3: 反向 Websocket 通信
|
||
> 4: pprof 性能分析服务器
|
||
> 5: 云函数服务
|
||
请输入你需要的编号,可输入多个,同一编号也可输入多个(如: 233)
|
||
您的选择是:`)
|
||
input := bufio.NewReader(os.Stdin)
|
||
readString, err := input.ReadString('\n')
|
||
if err != nil {
|
||
log.Fatal("输入不合法: ", err)
|
||
}
|
||
for _, r := range readString {
|
||
switch r {
|
||
case '1':
|
||
sb.WriteString(httpDefault)
|
||
case '2':
|
||
sb.WriteString(wsDefault)
|
||
case '3':
|
||
sb.WriteString(wsReverseDefault)
|
||
case '4':
|
||
sb.WriteString(pprofDefault)
|
||
case '5':
|
||
sb.WriteString(lambdaDefault)
|
||
}
|
||
}
|
||
_ = os.WriteFile("config.yml", []byte(sb.String()), 0o644)
|
||
fmt.Println("默认配置文件已生成,请修改 config.yml 后重新启动!")
|
||
_, _ = input.ReadString('\n')
|
||
}
|
||
|
||
const httpDefault = ` # HTTP 通信设置
|
||
- http:
|
||
# 服务端监听地址
|
||
host: 127.0.0.1
|
||
# 服务端监听端口
|
||
port: 5700
|
||
# 反向HTTP超时时间, 单位秒
|
||
# 最小值为5,小于5将会忽略本项设置
|
||
timeout: 5
|
||
# 长轮询拓展
|
||
long-polling:
|
||
# 是否开启
|
||
enabled: false
|
||
# 消息队列大小,0 表示不限制队列大小,谨慎使用
|
||
max-queue-size: 2000
|
||
middlewares:
|
||
<<: *default # 引用默认中间件
|
||
# 反向HTTP POST地址列表
|
||
post:
|
||
#- url: '' # 地址
|
||
# secret: '' # 密钥
|
||
#- url: 127.0.0.1:5701 # 地址
|
||
# secret: '' # 密钥
|
||
`
|
||
|
||
const lambdaDefault = ` # LambdaServer 配置
|
||
- lambda:
|
||
type: scf # scf: 腾讯云函数 aws: aws Lambda
|
||
middlewares:
|
||
<<: *default # 引用默认中间件
|
||
`
|
||
|
||
const wsDefault = ` # 正向WS设置
|
||
- ws:
|
||
# 正向WS服务器监听地址
|
||
host: 127.0.0.1
|
||
# 正向WS服务器监听端口
|
||
port: 6700
|
||
middlewares:
|
||
<<: *default # 引用默认中间件
|
||
`
|
||
|
||
const wsReverseDefault = ` # 反向WS设置
|
||
- ws-reverse:
|
||
# 反向WS Universal 地址
|
||
# 注意 设置了此项地址后下面两项将会被忽略
|
||
universal: ws://your_websocket_universal.server
|
||
# 反向WS API 地址
|
||
api: ws://your_websocket_api.server
|
||
# 反向WS Event 地址
|
||
event: ws://your_websocket_event.server
|
||
# 重连间隔 单位毫秒
|
||
reconnect-interval: 3000
|
||
middlewares:
|
||
<<: *default # 引用默认中间件
|
||
`
|
||
|
||
const pprofDefault = ` # pprof 性能分析服务器, 一般情况下不需要启用.
|
||
# 如果遇到性能问题请上传报告给开发者处理
|
||
# 注意: pprof服务不支持中间件、不支持鉴权. 请不要开放到公网
|
||
- pprof:
|
||
# pprof服务器监听地址
|
||
host: 127.0.0.1
|
||
# pprof服务器监听端口
|
||
port: 7700
|
||
`
|