mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-04 11:07:39 +08:00
Merge branch 'dev' into database-support
# Conflicts: # main.go
This commit is contained in:
commit
69a187ddd7
@ -14,6 +14,8 @@ RUN set -ex \
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk add --no-cache ffmpeg
|
||||
|
||||
COPY --from=builder /build/cqhttp /usr/bin/cqhttp
|
||||
RUN chmod +x /usr/bin/cqhttp
|
||||
|
||||
|
@ -29,3 +29,9 @@ var (
|
||||
func nocheck(_ io.ReadSeeker) (bool, string) {
|
||||
return true, ""
|
||||
}
|
||||
|
||||
// todo: enable in v1.1.0
|
||||
// onebot v12 feature
|
||||
const (
|
||||
AcceptOneBotV12HTTPEndPoint = false
|
||||
)
|
||||
|
@ -3,8 +3,12 @@ package base
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@ -17,7 +21,7 @@ import (
|
||||
var (
|
||||
LittleC string // config file
|
||||
LittleD bool // daemon
|
||||
LittleH bool // help
|
||||
LittleH bool // Help
|
||||
LittleWD string // working directory
|
||||
)
|
||||
|
||||
@ -55,7 +59,7 @@ func Parse() {
|
||||
dc := path.Join(wd, "config.yml")
|
||||
flag.StringVar(&LittleC, "c", dc, "configuration filename")
|
||||
flag.BoolVar(&LittleD, "d", false, "running as a daemon")
|
||||
flag.BoolVar(&LittleH, "h", false, "this help")
|
||||
flag.BoolVar(&LittleH, "h", false, "this Help")
|
||||
flag.StringVar(&LittleWD, "w", "", "cover the working directory")
|
||||
d := flag.Bool("D", false, "debug mode")
|
||||
flag.Parse()
|
||||
@ -105,3 +109,40 @@ func Init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Help cli命令行-h的帮助提示
|
||||
func Help() {
|
||||
fmt.Printf(`go-cqhttp service
|
||||
version: %s
|
||||
Usage:
|
||||
server [OPTIONS]
|
||||
Options:
|
||||
`, Version)
|
||||
|
||||
flag.PrintDefaults()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// ResetWorkingDir 重设工作路径
|
||||
func ResetWorkingDir() {
|
||||
wd := LittleWD
|
||||
args := make([]string, 0, len(os.Args))
|
||||
for i := 1; i < len(os.Args); i++ {
|
||||
if os.Args[i] == "-w" {
|
||||
i++ // skip value field
|
||||
} else if !strings.HasPrefix(os.Args[i], "-w") {
|
||||
args = append(args, os.Args[i])
|
||||
}
|
||||
}
|
||||
p, _ := filepath.Abs(os.Args[0])
|
||||
proc := exec.Command(p, args...)
|
||||
proc.Stdin = os.Stdin
|
||||
proc.Stdout = os.Stdout
|
||||
proc.Stderr = os.Stderr
|
||||
proc.Dir = wd
|
||||
err := proc.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
95
main.go
95
main.go
@ -5,13 +5,8 @@ import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -29,7 +24,7 @@ import (
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/cache"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/selfupdate"
|
||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||
"github.com/Mrs4s/go-cqhttp/modules/servers"
|
||||
"github.com/Mrs4s/go-cqhttp/server"
|
||||
|
||||
_ "github.com/Mrs4s/go-cqhttp/modules/mime" // mime检查模块
|
||||
@ -49,11 +44,11 @@ func main() {
|
||||
base.Parse()
|
||||
switch {
|
||||
case base.LittleH:
|
||||
help()
|
||||
base.Help()
|
||||
case base.LittleD:
|
||||
server.Daemon()
|
||||
case base.LittleWD != "":
|
||||
resetWorkDir()
|
||||
base.ResetWorkingDir()
|
||||
}
|
||||
base.Init()
|
||||
|
||||
@ -332,49 +327,8 @@ func main() {
|
||||
base.Account.Status = 0
|
||||
}
|
||||
cli.SetOnlineStatus(allowStatus[base.Account.Status])
|
||||
bot := coolq.NewQQBot(cli)
|
||||
for _, m := range base.Servers {
|
||||
if h, ok := m["http"]; ok {
|
||||
hc := new(config.HTTPServer)
|
||||
if err := h.Decode(hc); err != nil {
|
||||
log.Warn("读取http配置失败 :", err)
|
||||
} else if !hc.Disabled {
|
||||
go server.RunHTTPServerAndClients(bot, hc)
|
||||
}
|
||||
}
|
||||
if s, ok := m["ws"]; ok {
|
||||
sc := new(config.WebsocketServer)
|
||||
if err := s.Decode(sc); err != nil {
|
||||
log.Warn("读取正向Websocket配置失败 :", err)
|
||||
} else if !sc.Disabled {
|
||||
go server.RunWebSocketServer(bot, sc)
|
||||
}
|
||||
}
|
||||
if c, ok := m["ws-reverse"]; ok {
|
||||
rc := new(config.WebsocketReverse)
|
||||
if err := c.Decode(rc); err != nil {
|
||||
log.Warn("读取反向Websocket配置失败 :", err)
|
||||
} else if !rc.Disabled {
|
||||
go server.RunWebSocketClient(bot, rc)
|
||||
}
|
||||
}
|
||||
if p, ok := m["pprof"]; ok {
|
||||
pc := new(config.PprofServer)
|
||||
if err := p.Decode(pc); err != nil {
|
||||
log.Warn("读取pprof配置失败 :", err)
|
||||
} else if !pc.Disabled {
|
||||
go server.RunPprofServer(pc)
|
||||
}
|
||||
}
|
||||
if p, ok := m["lambda"]; ok {
|
||||
lc := new(config.LambdaServer)
|
||||
if err := p.Decode(lc); err != nil {
|
||||
log.Warn("读取pprof配置失败 :", err)
|
||||
} else if !lc.Disabled {
|
||||
go server.RunLambdaClient(bot, lc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
servers.Run(coolq.NewQQBot(cli))
|
||||
log.Info("资源初始化完成, 开始处理信息.")
|
||||
log.Info("アトリは、高性能ですから!")
|
||||
|
||||
@ -414,45 +368,6 @@ func PasswordHashDecrypt(encryptedPasswordHash string, key []byte) ([]byte, erro
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// help cli命令行-h的帮助提示
|
||||
func help() {
|
||||
fmt.Printf(`go-cqhttp service
|
||||
version: %s
|
||||
|
||||
Usage:
|
||||
|
||||
server [OPTIONS]
|
||||
|
||||
Options:
|
||||
`, base.Version)
|
||||
|
||||
flag.PrintDefaults()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func resetWorkDir() {
|
||||
wd := base.LittleWD
|
||||
args := make([]string, 0, len(os.Args))
|
||||
for i := 1; i < len(os.Args); i++ {
|
||||
if os.Args[i] == "-w" {
|
||||
i++ // skip value field
|
||||
} else if !strings.HasPrefix(os.Args[i], "-w") {
|
||||
args = append(args, os.Args[i])
|
||||
}
|
||||
}
|
||||
p, _ := filepath.Abs(os.Args[0])
|
||||
proc := exec.Command(p, args...)
|
||||
proc.Stdin = os.Stdin
|
||||
proc.Stdout = os.Stdout
|
||||
proc.Stderr = os.Stderr
|
||||
proc.Dir = wd
|
||||
err := proc.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func newClient() *client.QQClient {
|
||||
c := client.NewClientEmpty()
|
||||
c.OnServerUpdated(func(bot *client.QQClient, e *client.ServerUpdatedEvent) bool {
|
||||
|
31
modules/servers/servers.go
Normal file
31
modules/servers/servers.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Package servers provide servers register
|
||||
package servers
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
)
|
||||
|
||||
var svr = make(map[string]func(*coolq.CQBot, yaml.Node))
|
||||
|
||||
// Register 注册 Server
|
||||
func Register(name string, proc func(*coolq.CQBot, yaml.Node)) {
|
||||
_, ok := svr[name]
|
||||
if ok {
|
||||
panic(name + " server has existed")
|
||||
}
|
||||
svr[name] = proc
|
||||
}
|
||||
|
||||
// Run 运行所有svr
|
||||
func Run(bot *coolq.CQBot) {
|
||||
for _, l := range base.Servers {
|
||||
for name, conf := range l {
|
||||
if fn, ok := svr[name]; ok {
|
||||
go fn(bot, conf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +1,13 @@
|
||||
// Package server 包含HTTP,WebSocket,反向WebSocket请求处理的相关函数与结构体
|
||||
package server
|
||||
|
||||
import "github.com/Mrs4s/go-cqhttp/modules/servers"
|
||||
|
||||
// 注册
|
||||
func init() {
|
||||
servers.Register("http", runHTTP)
|
||||
servers.Register("ws", runWSServer)
|
||||
servers.Register("ws-reverse", runWSClient)
|
||||
servers.Register("pprof", runPprof)
|
||||
servers.Register("lambda", runLambda)
|
||||
}
|
||||
|
@ -19,8 +19,11 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||
)
|
||||
|
||||
@ -114,14 +117,21 @@ func (s *httpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
action := strings.TrimPrefix(request.URL.Path, "/")
|
||||
action = strings.TrimSuffix(action, "_async")
|
||||
log.Debugf("HTTPServer接收到API调用: %v", action)
|
||||
ret := s.api.callAPI(action, &ctx)
|
||||
var response global.MSG
|
||||
if base.AcceptOneBotV12HTTPEndPoint && request.URL.Path == "/" {
|
||||
action := strings.TrimSuffix(ctx.Get("action").Str, "_async")
|
||||
log.Debugf("HTTPServer接收到API调用: %v", action)
|
||||
response = s.api.callAPI(action, ctx.Get("params"))
|
||||
} else {
|
||||
action := strings.TrimPrefix(request.URL.Path, "/")
|
||||
action = strings.TrimSuffix(action, "_async")
|
||||
log.Debugf("HTTPServer接收到API调用: %v", action)
|
||||
response = s.api.callAPI(action, &ctx)
|
||||
}
|
||||
|
||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
_ = json.NewEncoder(writer).Encode(ret)
|
||||
_ = json.NewEncoder(writer).Encode(response)
|
||||
}
|
||||
|
||||
func checkAuth(req *http.Request, token string) int {
|
||||
@ -149,13 +159,19 @@ func checkAuth(req *http.Request, token string) int {
|
||||
}
|
||||
}
|
||||
|
||||
// RunHTTPServerAndClients 启动HTTP服务器与HTTP上报客户端
|
||||
func RunHTTPServerAndClients(bot *coolq.CQBot, conf *config.HTTPServer) {
|
||||
var (
|
||||
s = new(httpServer)
|
||||
addr string
|
||||
)
|
||||
s.accessToken = conf.AccessToken
|
||||
// runHTTP 启动HTTP服务器与HTTP上报客户端
|
||||
func runHTTP(bot *coolq.CQBot, node yaml.Node) {
|
||||
var conf config.HTTPServer
|
||||
switch err := node.Decode(&conf); {
|
||||
case err != nil:
|
||||
log.Warn("读取http配置失败 :", err)
|
||||
fallthrough
|
||||
case conf.Disabled:
|
||||
return
|
||||
}
|
||||
|
||||
var addr string
|
||||
s := &httpServer{accessToken: conf.AccessToken}
|
||||
if conf.Host == "" || conf.Port == 0 {
|
||||
goto client
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
@ -76,7 +75,7 @@ func longPolling(bot *coolq.CQBot, maxSize int) handler {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
ok int32
|
||||
once sync.Once
|
||||
ch = make(chan []interface{}, 1)
|
||||
timeout = time.Duration(p.Get("timeout").Int()) * time.Second
|
||||
)
|
||||
@ -87,7 +86,7 @@ func longPolling(bot *coolq.CQBot, maxSize int) handler {
|
||||
if queue.Len() == 0 {
|
||||
cond.Wait()
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&ok, 0, 1) {
|
||||
once.Do(func() {
|
||||
limit := int(p.Get("limit").Int())
|
||||
if limit <= 0 || queue.Len() < limit {
|
||||
limit = queue.Len()
|
||||
@ -97,12 +96,12 @@ func longPolling(bot *coolq.CQBot, maxSize int) handler {
|
||||
ret[i] = queue.Remove(queue.Front())
|
||||
}
|
||||
ch <- ret
|
||||
}
|
||||
})
|
||||
}()
|
||||
if timeout != 0 {
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
once.Do(func() {})
|
||||
return coolq.OK([]interface{}{})
|
||||
case ret := <-ch:
|
||||
return coolq.OK(ret)
|
||||
|
@ -8,12 +8,23 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||
)
|
||||
|
||||
// RunPprofServer 启动 pprof 性能分析服务器
|
||||
func RunPprofServer(conf *config.PprofServer) {
|
||||
// runPprof 启动 pprof 性能分析服务器
|
||||
func runPprof(_ *coolq.CQBot, node yaml.Node) {
|
||||
var conf config.PprofServer
|
||||
switch err := node.Decode(&conf); {
|
||||
case err != nil:
|
||||
log.Warn("读取pprof配置失败 :", err)
|
||||
fallthrough
|
||||
case conf.Disabled:
|
||||
return
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
@ -77,8 +78,17 @@ func (l *lambdaResponseWriter) WriteHeader(statusCode int) {
|
||||
|
||||
var cli *lambdaClient
|
||||
|
||||
// RunLambdaClient type: [scf,aws]
|
||||
func RunLambdaClient(bot *coolq.CQBot, conf *config.LambdaServer) {
|
||||
// runLambda type: [scf,aws]
|
||||
func runLambda(bot *coolq.CQBot, node yaml.Node) {
|
||||
var conf config.LambdaServer
|
||||
switch err := node.Decode(&conf); {
|
||||
case err != nil:
|
||||
log.Warn("读取lambda配置失败 :", err)
|
||||
fallthrough
|
||||
case conf.Disabled:
|
||||
return
|
||||
}
|
||||
|
||||
cli = &lambdaClient{
|
||||
lambdaType: conf.Type,
|
||||
client: http.Client{Timeout: 0},
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||
@ -54,11 +56,20 @@ var upgrader = websocket.Upgrader{
|
||||
},
|
||||
}
|
||||
|
||||
// RunWebSocketServer 运行一个正向WS server
|
||||
func RunWebSocketServer(b *coolq.CQBot, conf *config.WebsocketServer) {
|
||||
// runWSServer 运行一个正向WS server
|
||||
func runWSServer(b *coolq.CQBot, node yaml.Node) {
|
||||
var conf config.WebsocketServer
|
||||
switch err := node.Decode(&conf); {
|
||||
case err != nil:
|
||||
log.Warn("读取正向Websocket配置失败 :", err)
|
||||
fallthrough
|
||||
case conf.Disabled:
|
||||
return
|
||||
}
|
||||
|
||||
s := &webSocketServer{
|
||||
bot: b,
|
||||
conf: conf,
|
||||
conf: &conf,
|
||||
token: conf.AccessToken,
|
||||
filter: conf.Filter,
|
||||
}
|
||||
@ -77,11 +88,20 @@ func RunWebSocketServer(b *coolq.CQBot, conf *config.WebsocketServer) {
|
||||
}()
|
||||
}
|
||||
|
||||
// RunWebSocketClient 运行一个正向WS client
|
||||
func RunWebSocketClient(b *coolq.CQBot, conf *config.WebsocketReverse) {
|
||||
// runWSClient 运行一个反向向WS client
|
||||
func runWSClient(b *coolq.CQBot, node yaml.Node) {
|
||||
var conf config.WebsocketReverse
|
||||
switch err := node.Decode(&conf); {
|
||||
case err != nil:
|
||||
log.Warn("读取反向Websocket配置失败 :", err)
|
||||
fallthrough
|
||||
case conf.Disabled:
|
||||
return
|
||||
}
|
||||
|
||||
c := &websocketClient{
|
||||
bot: b,
|
||||
conf: conf,
|
||||
conf: &conf,
|
||||
token: conf.AccessToken,
|
||||
filter: conf.Filter,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user