mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-04 19:17:37 +08:00
style: move flag variable into internal/base
This commit is contained in:
parent
f2ed46d6ce
commit
2cf136d031
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||
)
|
||||
|
||||
// CQGetLoginInfo 获取登录号信息
|
||||
@ -945,7 +946,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) global
|
||||
reply := operation.Get("reply")
|
||||
|
||||
if reply.Exists() {
|
||||
autoEscape := global.EnsureBool(operation.Get("auto_escape"), false)
|
||||
autoEscape := param.EnsureBool(operation.Get("auto_escape"), false)
|
||||
at := operation.Get("at_sender").Bool() && !isAnonymous && msgType == "group"
|
||||
if at && reply.IsArray() {
|
||||
// 在 reply 数组头部插入CQ码
|
||||
|
11
coolq/bot.go
11
coolq/bot.go
@ -27,6 +27,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/global/config"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
)
|
||||
|
||||
// CQBot CQBot结构体,存储Bot实例相关配置
|
||||
@ -69,12 +70,6 @@ func (e *Event) JSONString() string {
|
||||
return utils.B2S(e.buffer.Bytes())
|
||||
}
|
||||
|
||||
// ForceFragmented 是否启用强制分片
|
||||
var ForceFragmented = false
|
||||
|
||||
// SkipMimeScan 是否跳过Mime扫描
|
||||
var SkipMimeScan bool
|
||||
|
||||
// keep sync with /docs/file.md#MINE
|
||||
var lawfulImageTypes = [...]string{
|
||||
"image/bmp",
|
||||
@ -296,7 +291,7 @@ func (bot *CQBot) SendGroupMessage(groupID int64, m *message.SendingMessage) int
|
||||
}
|
||||
m.Elements = newElem
|
||||
bot.checkMedia(newElem)
|
||||
ret := bot.Client.SendGroupMessage(groupID, m, ForceFragmented)
|
||||
ret := bot.Client.SendGroupMessage(groupID, m, base.ForceFragmented)
|
||||
if ret == nil || ret.Id == -1 {
|
||||
log.Warnf("群消息发送失败: 账号可能被风控.")
|
||||
return -1
|
||||
@ -619,7 +614,7 @@ func (bot *CQBot) uploadMedia(raw message.IMessageElement, target int64, group b
|
||||
// 返回 是否合法, 实际Mime
|
||||
// 判断后会自动将 Stream Seek 至 0
|
||||
func IsLawfulImage(r io.ReadSeeker) (bool, string) {
|
||||
if SkipMimeScan {
|
||||
if base.SkipMimeScan {
|
||||
return true, ""
|
||||
}
|
||||
_, _ = r.Seek(0, io.SeekStart)
|
||||
|
@ -26,6 +26,8 @@ import (
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/global/codec"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -34,18 +36,6 @@ var typeReg = regexp.MustCompile(`\[CQ:(\w+)`)
|
||||
var paramReg = regexp.MustCompile(`,([\w\-.]+?)=([^,\]]+)`)
|
||||
*/
|
||||
|
||||
// RemoveReplyAt 是否删除reply后的at
|
||||
var RemoveReplyAt bool
|
||||
|
||||
// ExtraReplyData 是否上报额外reply信息
|
||||
var ExtraReplyData bool
|
||||
|
||||
// IgnoreInvalidCQCode 是否忽略无效CQ码
|
||||
var IgnoreInvalidCQCode = false
|
||||
|
||||
// SplitURL 是否分割URL
|
||||
var SplitURL = false
|
||||
|
||||
const (
|
||||
maxImageSize = 1024 * 1024 * 30 // 30MB
|
||||
maxVideoSize = 1024 * 1024 * 100 // 100MB
|
||||
@ -137,7 +127,7 @@ func ToArrayMessage(e []message.IMessageElement, groupID int64) (r []global.MSG)
|
||||
if rid == 0 {
|
||||
rid = replyElem.Sender
|
||||
}
|
||||
if ExtraReplyData {
|
||||
if base.ExtraReplyData {
|
||||
r = append(r, global.MSG{
|
||||
"type": "reply",
|
||||
"data": map[string]string{
|
||||
@ -159,7 +149,7 @@ func ToArrayMessage(e []message.IMessageElement, groupID int64) (r []global.MSG)
|
||||
var m global.MSG
|
||||
switch o := elem.(type) {
|
||||
case *message.ReplyElement:
|
||||
if RemoveReplyAt && i+1 < len(e) {
|
||||
if base.RemoveReplyAt && i+1 < len(e) {
|
||||
elem, ok := e[i+1].(*message.AtElement)
|
||||
if ok && elem.Target == o.Sender {
|
||||
e[i+1] = nil
|
||||
@ -279,7 +269,7 @@ func ToStringMessage(e []message.IMessageElement, groupID int64, isRaw ...bool)
|
||||
if rid == 0 {
|
||||
rid = replyElem.Sender
|
||||
}
|
||||
if ExtraReplyData {
|
||||
if base.ExtraReplyData {
|
||||
write("[CQ:reply,id=%d,seq=%d,qq=%d,time=%d,text=%s]",
|
||||
toGlobalID(rid, replyElem.ReplySeq),
|
||||
replyElem.ReplySeq, replyElem.Sender, replyElem.Time,
|
||||
@ -291,7 +281,7 @@ func ToStringMessage(e []message.IMessageElement, groupID int64, isRaw ...bool)
|
||||
for i, elem := range e {
|
||||
switch o := elem.(type) {
|
||||
case *message.ReplyElement:
|
||||
if RemoveReplyAt && len(e) > i+1 {
|
||||
if base.RemoveReplyAt && len(e) > i+1 {
|
||||
elem, ok := e[i+1].(*message.AtElement)
|
||||
if ok && elem.Target == o.Sender {
|
||||
e[i+1] = nil
|
||||
@ -454,7 +444,7 @@ func (bot *CQBot) ConvertStringMessage(raw string, isGroup bool) (r []message.IM
|
||||
org += "," + k + "=" + v
|
||||
}
|
||||
org += "]"
|
||||
if !IgnoreInvalidCQCode {
|
||||
if !base.IgnoreInvalidCQCode {
|
||||
log.Warnf("转换CQ码 %v 时出现错误: %v 将原样发送.", org, err)
|
||||
r = append(r, message.NewText(org))
|
||||
} else {
|
||||
@ -476,8 +466,8 @@ func (bot *CQBot) ConvertStringMessage(raw string, isGroup bool) (r []message.IM
|
||||
i++
|
||||
}
|
||||
if i > 0 {
|
||||
if SplitURL {
|
||||
for _, txt := range global.SplitURL(CQCodeUnescapeText(raw[:i])) {
|
||||
if base.SplitURL {
|
||||
for _, txt := range param.SplitURL(CQCodeUnescapeText(raw[:i])) {
|
||||
r = append(r, message.NewText(txt))
|
||||
}
|
||||
} else {
|
||||
@ -662,9 +652,9 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, isGroup bool) (r []messag
|
||||
func (bot *CQBot) ToElement(t string, d map[string]string, isGroup bool) (m interface{}, err error) {
|
||||
switch t {
|
||||
case "text":
|
||||
if SplitURL {
|
||||
if base.SplitURL {
|
||||
var ret []message.IMessageElement
|
||||
for _, text := range global.SplitURL(d["text"]) {
|
||||
for _, text := range param.SplitURL(d["text"]) {
|
||||
ret = append(ret, message.NewText(text))
|
||||
}
|
||||
return ret, nil
|
||||
@ -735,7 +725,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, isGroup bool) (m inte
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !SkipMimeScan && !global.IsAMRorSILK(data) {
|
||||
if !base.SkipMimeScan && !global.IsAMRorSILK(data) {
|
||||
mt := mimetype.Detect(data)
|
||||
lawful := false
|
||||
for _, lt := range lawfulAudioTypes {
|
||||
@ -1117,7 +1107,7 @@ func (bot *CQBot) makeImageOrVideoElem(d map[string]string, video, group bool) (
|
||||
return &LocalImageElement{File: fu.Path}, nil
|
||||
}
|
||||
if strings.HasPrefix(f, "base64") && !video {
|
||||
b, err := global.Base64DecodeString(strings.TrimPrefix(f, "base64://"))
|
||||
b, err := param.Base64DecodeString(strings.TrimPrefix(f, "base64://"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wdvxdr1123/go-silk"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
)
|
||||
|
||||
const silkCachePath = "data/cache"
|
||||
@ -30,7 +32,7 @@ func EncodeToSilk(record []byte, tempName string, useCache bool) (silkWav []byte
|
||||
// 2.转换pcm
|
||||
pcmPath := path.Join(silkCachePath, tempName+".pcm")
|
||||
cmd := exec.Command("ffmpeg", "-i", rawPath, "-f", "s16le", "-ar", "24000", "-ac", "1", pcmPath)
|
||||
if Debug {
|
||||
if base.Debug {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
package codec
|
||||
|
||||
// Debug mode controls the ffmpeg output.
|
||||
var Debug bool
|
@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
@ -168,13 +168,13 @@ func Get() *Config {
|
||||
}
|
||||
|
||||
// load config from environment variable
|
||||
global.SetAtDefault(&config.Account.Uin, toInt64(os.Getenv("GCQ_UIN")), int64(0))
|
||||
global.SetAtDefault(&config.Account.Password, os.Getenv("GCQ_PWD"), "")
|
||||
global.SetAtDefault(&config.Account.Status, int32(toInt64(os.Getenv("GCQ_STATUS"))), int32(0))
|
||||
global.SetAtDefault(&config.Account.ReLogin.Disabled, !global.EnsureBool(os.Getenv("GCQ_RELOGIN_DISABLED"), true), false)
|
||||
global.SetAtDefault(&config.Account.ReLogin.Delay, uint(toInt64(os.Getenv("GCQ_RELOGIN_DELAY"))), uint(0))
|
||||
global.SetAtDefault(&config.Account.ReLogin.MaxTimes, uint(toInt64(os.Getenv("GCQ_RELOGIN_MAX_TIMES"))), uint(0))
|
||||
dbConf := &LevelDBConfig{Enable: global.EnsureBool(os.Getenv("GCQ_LEVELDB"), true)}
|
||||
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)
|
||||
}
|
||||
@ -193,9 +193,9 @@ func Get() *Config {
|
||||
AccessToken: accessTokenEnv,
|
||||
},
|
||||
}
|
||||
global.SetExcludeDefault(&httpConf.Disabled, global.EnsureBool(os.Getenv("GCQ_HTTP_DISABLE"), false), false)
|
||||
global.SetExcludeDefault(&httpConf.Host, os.Getenv("GCQ_HTTP_HOST"), "")
|
||||
global.SetExcludeDefault(&httpConf.Port, int(toInt64(os.Getenv("GCQ_HTTP_PORT"))), 0)
|
||||
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"`
|
||||
@ -214,9 +214,9 @@ func Get() *Config {
|
||||
AccessToken: accessTokenEnv,
|
||||
},
|
||||
}
|
||||
global.SetExcludeDefault(&wsServerConf.Disabled, global.EnsureBool(os.Getenv("GCQ_WS_DISABLE"), false), false)
|
||||
global.SetExcludeDefault(&wsServerConf.Host, os.Getenv("GCQ_WS_HOST"), "")
|
||||
global.SetExcludeDefault(&wsServerConf.Port, int(toInt64(os.Getenv("GCQ_WS_PORT"))), 0)
|
||||
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})
|
||||
}
|
||||
@ -227,10 +227,10 @@ func Get() *Config {
|
||||
AccessToken: accessTokenEnv,
|
||||
},
|
||||
}
|
||||
global.SetExcludeDefault(&rwsConf.Disabled, global.EnsureBool(os.Getenv("GCQ_RWS_DISABLE"), false), false)
|
||||
global.SetExcludeDefault(&rwsConf.API, os.Getenv("GCQ_RWS_API"), "")
|
||||
global.SetExcludeDefault(&rwsConf.Event, os.Getenv("GCQ_RWS_EVENT"), "")
|
||||
global.SetExcludeDefault(&rwsConf.Universal, os.Getenv("GCQ_RWS_UNIVERSAL"), "")
|
||||
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})
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import (
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -97,7 +99,7 @@ func FindFile(file, cache, p string) (data []byte, err error) {
|
||||
return nil, err
|
||||
}
|
||||
case strings.HasPrefix(file, "base64"):
|
||||
data, err = Base64DecodeString(strings.TrimPrefix(file, "base64://"))
|
||||
data, err = param.Base64DecodeString(strings.TrimPrefix(file, "base64://"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -16,16 +16,18 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
)
|
||||
|
||||
var (
|
||||
client = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: func(request *http.Request) (u *url.URL, e error) {
|
||||
if Proxy == "" {
|
||||
if base.Proxy == "" {
|
||||
return http.ProxyFromEnvironment(request)
|
||||
}
|
||||
return url.Parse(Proxy)
|
||||
return url.Parse(base.Proxy)
|
||||
},
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxConnsPerHost: 0,
|
||||
@ -34,9 +36,6 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
// Proxy 存储Config.proxy_rewrite,用于设置代理
|
||||
Proxy string
|
||||
|
||||
// ErrOverSize 响应主体过大时返回此错误
|
||||
ErrOverSize = errors.New("oversize")
|
||||
|
||||
|
123
global/param.go
123
global/param.go
@ -1,64 +1,15 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
"github.com/segmentio/asm/base64"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// MSG 消息Map
|
||||
type MSG map[string]interface{}
|
||||
|
||||
// EnsureBool 判断给定的p是否可表示为合法Bool类型,否则返回defaultVal
|
||||
//
|
||||
// 支持的合法类型有
|
||||
//
|
||||
// type bool
|
||||
//
|
||||
// type gjson.True or gjson.False
|
||||
//
|
||||
// type string "true","yes","1" or "false","no","0" (case insensitive)
|
||||
func EnsureBool(p interface{}, defaultVal bool) bool {
|
||||
var str string
|
||||
if b, ok := p.(bool); ok {
|
||||
return b
|
||||
}
|
||||
if j, ok := p.(gjson.Result); ok {
|
||||
if !j.Exists() {
|
||||
return defaultVal
|
||||
}
|
||||
switch j.Type { // nolint
|
||||
case gjson.True:
|
||||
return true
|
||||
case gjson.False:
|
||||
return false
|
||||
case gjson.String:
|
||||
str = j.Str
|
||||
default:
|
||||
return defaultVal
|
||||
}
|
||||
} else if s, ok := p.(string); ok {
|
||||
str = s
|
||||
}
|
||||
str = strings.ToLower(str)
|
||||
switch str {
|
||||
case "true", "yes", "1":
|
||||
return true
|
||||
case "false", "no", "0":
|
||||
return false
|
||||
default:
|
||||
return defaultVal
|
||||
}
|
||||
}
|
||||
|
||||
// VersionNameCompare 检查版本名是否需要更新, 仅适用于 go-cqhttp 的版本命名规则
|
||||
//
|
||||
// 例: v0.9.29-fix2 == v0.9.29-fix2 -> false
|
||||
@ -93,77 +44,3 @@ func VersionNameCompare(current, remote string) bool {
|
||||
}
|
||||
return cur[4] < re[4]
|
||||
}
|
||||
|
||||
// SetAtDefault 在变量 variable 为默认值 defaultValue 的时候修改为 value
|
||||
func SetAtDefault(variable, value, defaultValue interface{}) {
|
||||
v := reflect.ValueOf(variable)
|
||||
v2 := reflect.ValueOf(value)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if v.Interface() != defaultValue {
|
||||
return
|
||||
}
|
||||
if v.Kind() != v2.Kind() {
|
||||
return
|
||||
}
|
||||
v.Set(v2)
|
||||
}
|
||||
|
||||
// SetExcludeDefault 在目标值 value 不为默认值 defaultValue 时修改 variable 为 value
|
||||
func SetExcludeDefault(variable, value, defaultValue interface{}) {
|
||||
v := reflect.ValueOf(variable)
|
||||
v2 := reflect.ValueOf(value)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if reflect.Indirect(v2).Interface() != defaultValue {
|
||||
return
|
||||
}
|
||||
if v.Kind() != v2.Kind() {
|
||||
return
|
||||
}
|
||||
v.Set(v2)
|
||||
}
|
||||
|
||||
var (
|
||||
// once lazy compile the reg
|
||||
once sync.Once
|
||||
// reg is splitURL regex pattern.
|
||||
reg *regexp.Regexp
|
||||
)
|
||||
|
||||
// SplitURL 将给定URL字符串分割为两部分,用于URL预处理防止风控
|
||||
func SplitURL(s string) []string {
|
||||
once.Do(func() { // lazy init.
|
||||
reg = regexp.MustCompile(`(?i)[a-z\d][-a-z\d]{0,62}(\.[a-z\d][-a-z\d]{0,62})+\.?`)
|
||||
})
|
||||
idx := reg.FindAllStringIndex(s, -1)
|
||||
if len(idx) == 0 {
|
||||
return []string{s}
|
||||
}
|
||||
var result []string
|
||||
last := 0
|
||||
for i := 0; i < len(idx); i++ {
|
||||
if len(idx[i]) != 2 {
|
||||
continue
|
||||
}
|
||||
m := int(math.Abs(float64(idx[i][0]-idx[i][1]))/1.5) + idx[i][0]
|
||||
result = append(result, s[last:m])
|
||||
last = m
|
||||
}
|
||||
result = append(result, s[last:])
|
||||
return result
|
||||
}
|
||||
|
||||
// Base64DecodeString decode base64 with avx2
|
||||
// see https://github.com/segmentio/asm/issues/50
|
||||
// avoid incorrect unsafe usage in origin library
|
||||
func Base64DecodeString(s string) ([]byte, error) {
|
||||
e := base64.StdEncoding
|
||||
dst := make([]byte, e.DecodedLen(len(s)))
|
||||
n, err := e.Decode(dst, utils.S2B(s))
|
||||
return dst[:n], err
|
||||
}
|
||||
|
34
internal/base/flag.go
Normal file
34
internal/base/flag.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Package base provides base config for go-cqhttp
|
||||
package base
|
||||
|
||||
import "github.com/Mrs4s/go-cqhttp/global/config"
|
||||
|
||||
var (
|
||||
Debug bool // 是否开启 debug 模式
|
||||
RemoveReplyAt bool // 是否删除reply后的at
|
||||
ExtraReplyData bool // 是否上报额外reply信息
|
||||
IgnoreInvalidCQCode bool // 是否忽略无效CQ码
|
||||
SplitURL bool // 是否分割URL
|
||||
ForceFragmented bool // 是否启用强制分片
|
||||
SkipMimeScan bool // 是否跳过Mime扫描
|
||||
|
||||
Proxy string // 存储 proxy_rewrite,用于设置代理
|
||||
PasswordHash [16]byte // 存储QQ密码哈希供登录使用
|
||||
AccountToken []byte // 存储AccountToken供登录使用
|
||||
)
|
||||
|
||||
func Parse() {
|
||||
conf := config.Get()
|
||||
{ // bool config
|
||||
Debug = conf.Output.Debug
|
||||
IgnoreInvalidCQCode = conf.Message.IgnoreInvalidCQCode
|
||||
SplitURL = conf.Message.FixURL
|
||||
RemoveReplyAt = conf.Message.RemoveReplyAt
|
||||
ExtraReplyData = conf.Message.ExtraReplyData
|
||||
ForceFragmented = conf.Message.ForceFragment
|
||||
SkipMimeScan = conf.Message.SkipMimeScan
|
||||
}
|
||||
{ // string
|
||||
Proxy = conf.Message.ProxyRewrite
|
||||
}
|
||||
}
|
130
internal/param/param.go
Normal file
130
internal/param/param.go
Normal file
@ -0,0 +1,130 @@
|
||||
// Package param provide some util for param parse
|
||||
package param
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
"github.com/segmentio/asm/base64"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// EnsureBool 判断给定的p是否可表示为合法Bool类型,否则返回defaultVal
|
||||
//
|
||||
// 支持的合法类型有
|
||||
//
|
||||
// type bool
|
||||
//
|
||||
// type gjson.True or gjson.False
|
||||
//
|
||||
// type string "true","yes","1" or "false","no","0" (case insensitive)
|
||||
func EnsureBool(p interface{}, defaultVal bool) bool {
|
||||
var str string
|
||||
if b, ok := p.(bool); ok {
|
||||
return b
|
||||
}
|
||||
if j, ok := p.(gjson.Result); ok {
|
||||
if !j.Exists() {
|
||||
return defaultVal
|
||||
}
|
||||
switch j.Type { // nolint
|
||||
case gjson.True:
|
||||
return true
|
||||
case gjson.False:
|
||||
return false
|
||||
case gjson.String:
|
||||
str = j.Str
|
||||
default:
|
||||
return defaultVal
|
||||
}
|
||||
} else if s, ok := p.(string); ok {
|
||||
str = s
|
||||
}
|
||||
str = strings.ToLower(str)
|
||||
switch str {
|
||||
case "true", "yes", "1":
|
||||
return true
|
||||
case "false", "no", "0":
|
||||
return false
|
||||
default:
|
||||
return defaultVal
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// once lazy compile the reg
|
||||
once sync.Once
|
||||
// reg is splitURL regex pattern.
|
||||
reg *regexp.Regexp
|
||||
)
|
||||
|
||||
// SplitURL 将给定URL字符串分割为两部分,用于URL预处理防止风控
|
||||
func SplitURL(s string) []string {
|
||||
once.Do(func() { // lazy init.
|
||||
reg = regexp.MustCompile(`(?i)[a-z\d][-a-z\d]{0,62}(\.[a-z\d][-a-z\d]{0,62})+\.?`)
|
||||
})
|
||||
idx := reg.FindAllStringIndex(s, -1)
|
||||
if len(idx) == 0 {
|
||||
return []string{s}
|
||||
}
|
||||
var result []string
|
||||
last := 0
|
||||
for i := 0; i < len(idx); i++ {
|
||||
if len(idx[i]) != 2 {
|
||||
continue
|
||||
}
|
||||
m := int(math.Abs(float64(idx[i][0]-idx[i][1]))/1.5) + idx[i][0]
|
||||
result = append(result, s[last:m])
|
||||
last = m
|
||||
}
|
||||
result = append(result, s[last:])
|
||||
return result
|
||||
}
|
||||
|
||||
// Base64DecodeString decode base64 with avx2
|
||||
// see https://github.com/segmentio/asm/issues/50
|
||||
// avoid incorrect unsafe usage in origin library
|
||||
func Base64DecodeString(s string) ([]byte, error) {
|
||||
e := base64.StdEncoding
|
||||
dst := make([]byte, e.DecodedLen(len(s)))
|
||||
n, err := e.Decode(dst, utils.S2B(s))
|
||||
return dst[:n], err
|
||||
}
|
||||
|
||||
// SetAtDefault 在变量 variable 为默认值 defaultValue 的时候修改为 value
|
||||
func SetAtDefault(variable, value, defaultValue interface{}) {
|
||||
v := reflect.ValueOf(variable)
|
||||
v2 := reflect.ValueOf(value)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if v.Interface() != defaultValue {
|
||||
return
|
||||
}
|
||||
if v.Kind() != v2.Kind() {
|
||||
return
|
||||
}
|
||||
v.Set(v2)
|
||||
}
|
||||
|
||||
// SetExcludeDefault 在目标值 value 不为默认值 defaultValue 时修改 variable 为 value
|
||||
func SetExcludeDefault(variable, value, defaultValue interface{}) {
|
||||
v := reflect.ValueOf(variable)
|
||||
v2 := reflect.ValueOf(value)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if reflect.Indirect(v2).Interface() != defaultValue {
|
||||
return
|
||||
}
|
||||
if v.Kind() != v2.Kind() {
|
||||
return
|
||||
}
|
||||
v.Set(v2)
|
||||
}
|
2
login.go
2
login.go
@ -18,7 +18,7 @@ import (
|
||||
|
||||
var console = bufio.NewReader(os.Stdin)
|
||||
|
||||
var readLine = func() (str string) {
|
||||
func readLine() (str string) {
|
||||
str, _ = console.ReadString('\n')
|
||||
str = strings.TrimSpace(str)
|
||||
return
|
||||
|
84
main.go
84
main.go
@ -29,21 +29,16 @@ import (
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/global/codec"
|
||||
"github.com/Mrs4s/go-cqhttp/global/config"
|
||||
"github.com/Mrs4s/go-cqhttp/global/terminal"
|
||||
"github.com/Mrs4s/go-cqhttp/global/update"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
"github.com/Mrs4s/go-cqhttp/server"
|
||||
)
|
||||
|
||||
var (
|
||||
conf *config.Config
|
||||
isFastStart = false
|
||||
// PasswordHash 存储QQ密码哈希供登录使用
|
||||
PasswordHash [16]byte
|
||||
|
||||
// AccountToken 存储AccountToken供登录使用
|
||||
AccountToken []byte
|
||||
|
||||
// 允许通过配置文件设置的状态列表
|
||||
allowStatus = [...]client.UserOnlineStatus{
|
||||
@ -62,6 +57,7 @@ func main() {
|
||||
wd := flag.String("w", "", "cover the working directory")
|
||||
debug := flag.Bool("D", false, "debug mode")
|
||||
flag.Parse()
|
||||
// todo: maybe move flag to internal/base?
|
||||
|
||||
switch {
|
||||
case *h:
|
||||
@ -78,9 +74,9 @@ func main() {
|
||||
if *debug {
|
||||
conf.Output.Debug = true
|
||||
}
|
||||
if conf.Output.Debug {
|
||||
base.Parse()
|
||||
if base.Debug {
|
||||
log.SetReportCaller(true)
|
||||
codec.Debug = true
|
||||
}
|
||||
|
||||
rotateOptions := []rotatelogs.Option{
|
||||
@ -155,8 +151,8 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("当前版本:", coolq.Version)
|
||||
if conf.Output.Debug {
|
||||
log.Info("当前版本:", base.Version)
|
||||
if base.Debug {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.Warnf("已开启Debug模式.")
|
||||
log.Debugf("开发交流群: 192548878")
|
||||
@ -183,8 +179,8 @@ func main() {
|
||||
}
|
||||
log.Infof("密码加密已启用, 请输入Key对密码进行加密: (Enter 提交)")
|
||||
byteKey, _ = term.ReadPassword(int(os.Stdin.Fd()))
|
||||
PasswordHash = md5.Sum([]byte(conf.Account.Password))
|
||||
_ = os.WriteFile("password.encrypt", []byte(PasswordHashEncrypt(PasswordHash[:], byteKey)), 0o644)
|
||||
base.PasswordHash = md5.Sum([]byte(conf.Account.Password))
|
||||
_ = os.WriteFile("password.encrypt", []byte(PasswordHashEncrypt(base.PasswordHash[:], byteKey)), 0o644)
|
||||
log.Info("密码已加密,为了您的账号安全,请删除配置文件中的密码后重新启动.")
|
||||
readLine()
|
||||
os.Exit(0)
|
||||
@ -221,10 +217,10 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalf("加密存储的密码损坏,请尝试重新配置密码")
|
||||
}
|
||||
copy(PasswordHash[:], ph)
|
||||
copy(base.PasswordHash[:], ph)
|
||||
}
|
||||
} else if len(conf.Account.Password) > 0 {
|
||||
PasswordHash = md5.Sum([]byte(conf.Account.Password))
|
||||
base.PasswordHash = md5.Sum([]byte(conf.Account.Password))
|
||||
}
|
||||
if !isFastStart {
|
||||
log.Info("Bot将在5秒后登录并开始信息处理, 按 Ctrl+C 取消.")
|
||||
@ -247,12 +243,11 @@ func main() {
|
||||
return "未知"
|
||||
}())
|
||||
cli = newClient()
|
||||
global.Proxy = conf.Message.ProxyRewrite
|
||||
isQRCodeLogin := (conf.Account.Uin == 0 || len(conf.Account.Password) == 0) && !conf.Account.Encrypt
|
||||
isTokenLogin := false
|
||||
saveToken := func() {
|
||||
AccountToken = cli.GenToken()
|
||||
_ = os.WriteFile("session.token", AccountToken, 0o644)
|
||||
base.AccountToken = cli.GenToken()
|
||||
_ = os.WriteFile("session.token", base.AccountToken, 0o644)
|
||||
}
|
||||
if global.PathExists("session.token") {
|
||||
token, err := os.ReadFile("session.token")
|
||||
@ -285,9 +280,9 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if conf.Account.Uin != 0 && PasswordHash != [16]byte{} {
|
||||
if conf.Account.Uin != 0 && base.PasswordHash != [16]byte{} {
|
||||
cli.Uin = conf.Account.Uin
|
||||
cli.PasswordMd5 = PasswordHash
|
||||
cli.PasswordMd5 = base.PasswordHash
|
||||
}
|
||||
if !isTokenLogin {
|
||||
if !isQRCodeLogin {
|
||||
@ -331,7 +326,7 @@ func main() {
|
||||
break
|
||||
}
|
||||
log.Warnf("尝试重连...")
|
||||
err := cli.TokenLogin(AccountToken)
|
||||
err := cli.TokenLogin(base.AccountToken)
|
||||
if err == nil {
|
||||
saveToken()
|
||||
return
|
||||
@ -371,12 +366,6 @@ func main() {
|
||||
} else {
|
||||
coolq.SetMessageFormat(conf.Message.PostFormat)
|
||||
}
|
||||
coolq.IgnoreInvalidCQCode = conf.Message.IgnoreInvalidCQCode
|
||||
coolq.SplitURL = conf.Message.FixURL
|
||||
coolq.ForceFragmented = conf.Message.ForceFragment
|
||||
coolq.RemoveReplyAt = conf.Message.RemoveReplyAt
|
||||
coolq.ExtraReplyData = conf.Message.ExtraReplyData
|
||||
coolq.SkipMimeScan = conf.Message.SkipMimeScan
|
||||
for _, m := range conf.Servers {
|
||||
if h, ok := m["http"]; ok {
|
||||
hc := new(config.HTTPServer)
|
||||
@ -460,7 +449,7 @@ func PasswordHashDecrypt(encryptedPasswordHash string, key []byte) ([]byte, erro
|
||||
|
||||
func checkUpdate() {
|
||||
log.Infof("正在检查更新.")
|
||||
if coolq.Version == "(devel)" {
|
||||
if base.Version == "(devel)" {
|
||||
log.Warnf("检查更新失败: 使用的 Actions 测试版或自编译版本.")
|
||||
return
|
||||
}
|
||||
@ -470,9 +459,9 @@ func checkUpdate() {
|
||||
return
|
||||
}
|
||||
info := gjson.Parse(utils.B2S(r))
|
||||
if global.VersionNameCompare(coolq.Version, info.Get("tag_name").Str) {
|
||||
if global.VersionNameCompare(base.Version, info.Get("tag_name").Str) {
|
||||
log.Infof("当前有更新的 go-cqhttp 可供更新, 请前往 https://github.com/Mrs4s/go-cqhttp/releases 下载.")
|
||||
log.Infof("当前版本: %v 最新版本: %v", coolq.Version, info.Get("tag_name").Str)
|
||||
log.Infof("当前版本: %v 最新版本: %v", base.Version, info.Get("tag_name").Str)
|
||||
return
|
||||
}
|
||||
log.Infof("检查更新完成. 当前已运行最新版本.")
|
||||
@ -488,7 +477,7 @@ func selfUpdate(imageURL string) {
|
||||
}
|
||||
info := gjson.Parse(utils.B2S(res))
|
||||
version := info.Get("tag_name").Str
|
||||
if coolq.Version == version {
|
||||
if base.Version == version {
|
||||
log.Info("当前版本已经是最新版本!")
|
||||
goto wait
|
||||
}
|
||||
@ -556,39 +545,6 @@ wait:
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
/*
|
||||
func restart(args []string) {
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
file, err := exec.LookPath(args[0])
|
||||
if err != nil {
|
||||
log.Errorf("重启失败:%s", err.Error())
|
||||
return
|
||||
}
|
||||
path, err := filepath.Abs(file)
|
||||
if err != nil {
|
||||
log.Errorf("重启失败:%s", err.Error())
|
||||
}
|
||||
args = append([]string{"/c", "start ", path, "faststart"}, args[1:]...)
|
||||
cmd = &exec.Cmd{
|
||||
Path: "cmd.exe",
|
||||
Args: args,
|
||||
Stderr: os.Stderr,
|
||||
Stdout: os.Stdout,
|
||||
}
|
||||
} else {
|
||||
args = append(args, "faststart")
|
||||
cmd = &exec.Cmd{
|
||||
Path: args[0],
|
||||
Args: args,
|
||||
Stderr: os.Stderr,
|
||||
Stdout: os.Stdout,
|
||||
}
|
||||
}
|
||||
_ = cmd.Start()
|
||||
}
|
||||
*/
|
||||
|
||||
// help cli命令行-h的帮助提示
|
||||
func help() {
|
||||
fmt.Printf(`go-cqhttp service
|
||||
@ -599,7 +555,7 @@ Usage:
|
||||
server [OPTIONS]
|
||||
|
||||
Options:
|
||||
`, coolq.Version)
|
||||
`, base.Version)
|
||||
|
||||
flag.PrintDefaults()
|
||||
os.Exit(0)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@ -63,7 +64,7 @@ func getGroupMemberInfo(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
}
|
||||
|
||||
func sendMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
autoEscape := global.EnsureBool(p.Get("auto_escape"), false)
|
||||
autoEscape := param.EnsureBool(p.Get("auto_escape"), false)
|
||||
if p.Get("message_type").Str == "private" {
|
||||
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("group_id").Int(), p.Get("message"), autoEscape)
|
||||
}
|
||||
@ -81,7 +82,7 @@ func sendMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
|
||||
func sendGroupMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"),
|
||||
global.EnsureBool(p.Get("auto_escape"), false))
|
||||
param.EnsureBool(p.Get("auto_escape"), false))
|
||||
}
|
||||
|
||||
func sendGroupForwardMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
@ -90,7 +91,7 @@ func sendGroupForwardMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
|
||||
func sendPrivateMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("group_id").Int(), p.Get("message"),
|
||||
global.EnsureBool(p.Get("auto_escape"), false))
|
||||
param.EnsureBool(p.Get("auto_escape"), false))
|
||||
}
|
||||
|
||||
func deleteMSG(bot *coolq.CQBot, p resultGetter) global.MSG {
|
||||
|
Loading…
x
Reference in New Issue
Block a user