Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
go-cqhttp
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
go-cqhttp
Commits
229098d2
Commit
229098d2
authored
Aug 26, 2020
by
nanahira
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:Mrs4s/go-cqhttp
parents
df1592ff
174ebfae
Pipeline
#629
passed with stages
in 4 minutes and 49 seconds
Changes
15
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
535 additions
and
83 deletions
+535
-83
.dockerignore
.dockerignore
+1
-0
.gitignore
.gitignore
+1
-0
coolq/api.go
coolq/api.go
+11
-3
coolq/bot.go
coolq/bot.go
+10
-1
coolq/cqcode.go
coolq/cqcode.go
+89
-9
docs/config.md
docs/config.md
+20
-13
docs/cqhttp.md
docs/cqhttp.md
+45
-0
global/config.go
global/config.go
+16
-13
global/filter.go
global/filter.go
+267
-0
global/net.go
global/net.go
+37
-0
go.mod
go.mod
+1
-1
go.sum
go.sum
+2
-22
main.go
main.go
+12
-0
server/http.go
server/http.go
+2
-1
server/websocket.go
server/websocket.go
+21
-20
No files found.
.dockerignore
View file @
229098d2
...
@@ -10,3 +10,4 @@ device.json
...
@@ -10,3 +10,4 @@ device.json
data/
data/
vendor/
vendor/
/go-cqhttp
/go-cqhttp
.idea
.gitignore
View file @
229098d2
...
@@ -5,3 +5,4 @@ device.json
...
@@ -5,3 +5,4 @@ device.json
data/
data/
vendor/
vendor/
/go-cqhttp
/go-cqhttp
.idea
coolq/api.go
View file @
229098d2
...
@@ -489,7 +489,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG {
...
@@ -489,7 +489,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG {
bot
.
CQProcessFriendRequest
(
context
.
Get
(
"flag"
)
.
Str
,
operation
.
Get
(
"approve"
)
.
Bool
())
bot
.
CQProcessFriendRequest
(
context
.
Get
(
"flag"
)
.
Str
,
operation
.
Get
(
"approve"
)
.
Bool
())
}
}
if
reqType
==
"group"
{
if
reqType
==
"group"
{
bot
.
CQProcessGroupRequest
(
context
.
Get
(
"flag"
)
.
Str
,
context
.
Get
(
"sub_type"
)
.
Str
,
context
.
Get
(
"reason"
)
.
Str
,
operation
.
Get
(
"approve"
)
.
Bool
())
bot
.
CQProcessGroupRequest
(
context
.
Get
(
"flag"
)
.
Str
,
context
.
Get
(
"sub_type"
)
.
Str
,
operation
.
Get
(
"reason"
)
.
Str
,
operation
.
Get
(
"approve"
)
.
Bool
())
}
}
}
}
}
}
...
@@ -503,11 +503,19 @@ func (bot *CQBot) CQGetImage(file string) MSG {
...
@@ -503,11 +503,19 @@ func (bot *CQBot) CQGetImage(file string) MSG {
if
b
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
global
.
IMAGE_PATH
,
file
));
err
==
nil
{
if
b
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
global
.
IMAGE_PATH
,
file
));
err
==
nil
{
r
:=
binary
.
NewReader
(
b
)
r
:=
binary
.
NewReader
(
b
)
r
.
ReadBytes
(
16
)
r
.
ReadBytes
(
16
)
return
OK
(
MSG
{
msg
:=
MSG
{
"size"
:
r
.
ReadInt32
(),
"size"
:
r
.
ReadInt32
(),
"filename"
:
r
.
ReadString
(),
"filename"
:
r
.
ReadString
(),
"url"
:
r
.
ReadString
(),
"url"
:
r
.
ReadString
(),
})
}
local
:=
path
.
Join
(
global
.
CACHE_PATH
,
file
+
"."
+
path
.
Ext
(
msg
[
"filename"
]
.
(
string
)))
if
!
global
.
PathExists
(
local
)
{
if
data
,
err
:=
global
.
GetBytes
(
msg
[
"url"
]
.
(
string
));
err
==
nil
{
_
=
ioutil
.
WriteFile
(
local
,
data
,
0644
)
}
}
msg
[
"file"
]
=
local
return
OK
(
msg
)
}
}
return
Failed
(
100
)
return
Failed
(
100
)
}
}
...
...
coolq/bot.go
View file @
229098d2
...
@@ -10,6 +10,7 @@ import (
...
@@ -10,6 +10,7 @@ import (
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/go-cqhttp/global"
"github.com/Mrs4s/go-cqhttp/global"
log
"github.com/sirupsen/logrus"
log
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/xujiajun/nutsdb"
"github.com/xujiajun/nutsdb"
"hash/crc32"
"hash/crc32"
"path"
"path"
...
@@ -30,6 +31,8 @@ type CQBot struct {
...
@@ -30,6 +31,8 @@ type CQBot struct {
type
MSG
map
[
string
]
interface
{}
type
MSG
map
[
string
]
interface
{}
var
ForceFragmented
=
false
func
NewQQBot
(
cli
*
client
.
QQClient
,
conf
*
global
.
JsonConfig
)
*
CQBot
{
func
NewQQBot
(
cli
*
client
.
QQClient
,
conf
*
global
.
JsonConfig
)
*
CQBot
{
bot
:=
&
CQBot
{
bot
:=
&
CQBot
{
Client
:
cli
,
Client
:
cli
,
...
@@ -127,7 +130,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int
...
@@ -127,7 +130,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int
newElem
=
append
(
newElem
,
elem
)
newElem
=
append
(
newElem
,
elem
)
}
}
m
.
Elements
=
newElem
m
.
Elements
=
newElem
ret
:=
bot
.
Client
.
SendGroupMessage
(
groupId
,
m
)
ret
:=
bot
.
Client
.
SendGroupMessage
(
groupId
,
m
,
ForceFragmented
)
if
ret
==
nil
||
ret
.
Id
==
-
1
{
if
ret
==
nil
||
ret
.
Id
==
-
1
{
log
.
Warnf
(
"群消息发送失败: 账号可能被风控."
)
log
.
Warnf
(
"群消息发送失败: 账号可能被风控."
)
return
-
1
return
-
1
...
@@ -208,6 +211,12 @@ func (bot *CQBot) Release() {
...
@@ -208,6 +211,12 @@ func (bot *CQBot) Release() {
}
}
func
(
bot
*
CQBot
)
dispatchEventMessage
(
m
MSG
)
{
func
(
bot
*
CQBot
)
dispatchEventMessage
(
m
MSG
)
{
payload
:=
gjson
.
Parse
(
m
.
ToJson
())
filter
:=
global
.
GetFilter
()
if
filter
!=
nil
&&
(
*
filter
)
.
Eval
(
payload
)
==
false
{
log
.
Debug
(
"Event filtered!"
)
return
}
for
_
,
f
:=
range
bot
.
events
{
for
_
,
f
:=
range
bot
.
events
{
fn
:=
f
fn
:=
f
go
func
()
{
go
func
()
{
...
...
coolq/cqcode.go
View file @
229098d2
...
@@ -6,11 +6,6 @@ import (
...
@@ -6,11 +6,6 @@ import (
"encoding/hex"
"encoding/hex"
"errors"
"errors"
"fmt"
"fmt"
"github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/go-cqhttp/global"
log
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"io/ioutil"
"io/ioutil"
"net/url"
"net/url"
"path"
"path"
...
@@ -18,12 +13,20 @@ import (
...
@@ -18,12 +13,20 @@ import (
"runtime"
"runtime"
"strconv"
"strconv"
"strings"
"strings"
"github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/go-cqhttp/global"
log
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
)
)
var
matchReg
=
regexp
.
MustCompile
(
`\[CQ:\w+?.*?]`
)
var
matchReg
=
regexp
.
MustCompile
(
`\[CQ:\w+?.*?]`
)
var
typeReg
=
regexp
.
MustCompile
(
`\[CQ:(\w+)`
)
var
typeReg
=
regexp
.
MustCompile
(
`\[CQ:(\w+)`
)
var
paramReg
=
regexp
.
MustCompile
(
`,([\w\-.]+?)=([^,\]]+)`
)
var
paramReg
=
regexp
.
MustCompile
(
`,([\w\-.]+?)=([^,\]]+)`
)
var
IgnoreInvalidCQCode
=
false
func
ToArrayMessage
(
e
[]
message
.
IMessageElement
,
code
int64
,
raw
...
bool
)
(
r
[]
MSG
)
{
func
ToArrayMessage
(
e
[]
message
.
IMessageElement
,
code
int64
,
raw
...
bool
)
(
r
[]
MSG
)
{
ur
:=
false
ur
:=
false
if
len
(
raw
)
!=
0
{
if
len
(
raw
)
!=
0
{
...
@@ -111,6 +114,15 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
...
@@ -111,6 +114,15 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
if
len
(
raw
)
!=
0
{
if
len
(
raw
)
!=
0
{
ur
=
raw
[
0
]
ur
=
raw
[
0
]
}
}
// 方便
m
:=
&
message
.
SendingMessage
{
Elements
:
e
}
reply
:=
m
.
FirstOrNil
(
func
(
e
message
.
IMessageElement
)
bool
{
_
,
ok
:=
e
.
(
*
message
.
ReplyElement
)
return
ok
})
if
reply
!=
nil
{
r
+=
fmt
.
Sprintf
(
"[CQ:reply,id=%d]"
,
ToGlobalId
(
code
,
reply
.
(
*
message
.
ReplyElement
)
.
ReplySeq
))
}
for
_
,
elem
:=
range
e
{
for
_
,
elem
:=
range
e
{
switch
o
:=
elem
.
(
type
)
{
switch
o
:=
elem
.
(
type
)
{
case
*
message
.
TextElement
:
case
*
message
.
TextElement
:
...
@@ -121,8 +133,6 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
...
@@ -121,8 +133,6 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
continue
continue
}
}
r
+=
fmt
.
Sprintf
(
"[CQ:at,qq=%d]"
,
o
.
Target
)
r
+=
fmt
.
Sprintf
(
"[CQ:at,qq=%d]"
,
o
.
Target
)
case
*
message
.
ReplyElement
:
r
+=
fmt
.
Sprintf
(
"[CQ:reply,id=%d]"
,
ToGlobalId
(
code
,
o
.
ReplySeq
))
case
*
message
.
ForwardElement
:
case
*
message
.
ForwardElement
:
r
+=
fmt
.
Sprintf
(
"[CQ:forward,id=%s]"
,
o
.
ResId
)
r
+=
fmt
.
Sprintf
(
"[CQ:forward,id=%s]"
,
o
.
ResId
)
case
*
message
.
FaceElement
:
case
*
message
.
FaceElement
:
...
@@ -191,8 +201,12 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa
...
@@ -191,8 +201,12 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa
}
}
elem
,
err
:=
bot
.
ToElement
(
t
,
d
,
group
)
elem
,
err
:=
bot
.
ToElement
(
t
,
d
,
group
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Warnf
(
"转换CQ码到MiraiGo Element时出现错误: %v 将原样发送."
,
err
)
if
!
IgnoreInvalidCQCode
{
r
=
append
(
r
,
message
.
NewText
(
code
))
log
.
Warnf
(
"转换CQ码 %v 到MiraiGo Element时出现错误: %v 将原样发送."
,
code
,
err
)
r
=
append
(
r
,
message
.
NewText
(
code
))
}
else
{
log
.
Warnf
(
"转换CQ码 %v 到MiraiGo Element时出现错误: %v 将忽略."
,
code
,
err
)
}
continue
continue
}
}
r
=
append
(
r
,
elem
)
r
=
append
(
r
,
elem
)
...
@@ -322,6 +336,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
...
@@ -322,6 +336,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
}
}
var
size
int32
var
size
int32
var
hash
[]
byte
var
hash
[]
byte
var
url
string
if
path
.
Ext
(
rawPath
)
==
".cqimg"
{
if
path
.
Ext
(
rawPath
)
==
".cqimg"
{
for
_
,
line
:=
range
strings
.
Split
(
global
.
ReadAllText
(
rawPath
),
"
\n
"
)
{
for
_
,
line
:=
range
strings
.
Split
(
global
.
ReadAllText
(
rawPath
),
"
\n
"
)
{
kv
:=
strings
.
SplitN
(
line
,
"="
,
2
)
kv
:=
strings
.
SplitN
(
line
,
"="
,
2
)
...
@@ -337,8 +352,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
...
@@ -337,8 +352,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
r
:=
binary
.
NewReader
(
b
)
r
:=
binary
.
NewReader
(
b
)
hash
=
r
.
ReadBytes
(
16
)
hash
=
r
.
ReadBytes
(
16
)
size
=
r
.
ReadInt32
()
size
=
r
.
ReadInt32
()
r
.
ReadString
()
url
=
r
.
ReadString
()
}
}
if
size
==
0
{
if
size
==
0
{
if
url
!=
""
{
return
bot
.
ToElement
(
t
,
map
[
string
]
string
{
"file"
:
url
},
group
)
}
return
nil
,
errors
.
New
(
"img size is 0"
)
return
nil
,
errors
.
New
(
"img size is 0"
)
}
}
if
len
(
hash
)
!=
16
{
if
len
(
hash
)
!=
16
{
...
@@ -418,6 +438,66 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
...
@@ -418,6 +438,66 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
return
message
.
NewAt
(
t
),
nil
return
message
.
NewAt
(
t
),
nil
case
"share"
:
case
"share"
:
return
message
.
NewUrlShare
(
d
[
"url"
],
d
[
"title"
],
d
[
"content"
],
d
[
"image"
]),
nil
return
message
.
NewUrlShare
(
d
[
"url"
],
d
[
"title"
],
d
[
"content"
],
d
[
"image"
]),
nil
case
"music"
:
if
d
[
"type"
]
==
"qq"
{
info
,
err
:=
global
.
QQMusicSongInfo
(
d
[
"id"
])
if
err
!=
nil
{
return
nil
,
err
}
if
!
info
.
Get
(
"track_info"
)
.
Exists
()
{
return
nil
,
errors
.
New
(
"song not found"
)
}
aid
:=
strconv
.
FormatInt
(
info
.
Get
(
"track_info.album.id"
)
.
Int
(),
10
)
name
:=
info
.
Get
(
"track_info.name"
)
.
Str
if
len
(
aid
)
<
2
{
return
nil
,
errors
.
New
(
"song error"
)
}
xml
:=
fmt
.
Sprintf
(
`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="https://i.y.qq.com/v8/playsong.html?_wv=1&songid=%s&souce=qqshare&source=qqshare&ADTAG=qqshare" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="http://imgcache.qq.com/music/photo/album_500/%s/500_albumpic_%s_0.jpg" src="%s" /><title>%s</title><summary>%s</summary></item><source name="QQ音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`
,
name
,
d
[
"id"
],
aid
[
:
len
(
aid
)
-
2
],
aid
,
name
,
""
,
info
.
Get
(
"track_info.singer.name"
)
.
Str
)
return
&
message
.
ServiceElement
{
Id
:
60
,
Content
:
xml
,
SubType
:
"music"
,
},
nil
}
if
d
[
"type"
]
==
"163"
{
info
,
err
:=
global
.
NeteaseMusicSongInfo
(
d
[
"id"
])
if
err
!=
nil
{
return
nil
,
err
}
if
!
info
.
Exists
()
{
return
nil
,
errors
.
New
(
"song not found"
)
}
name
:=
info
.
Get
(
"name"
)
.
Str
artistName
:=
""
if
info
.
Get
(
"artists.0"
)
.
Exists
()
{
artistName
=
info
.
Get
(
"artists.0.name"
)
.
Str
}
xml
:=
fmt
.
Sprintf
(
`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="http://music.163.com/m/song/%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s?param=90y90" src="https://music.163.com/song/media/outer/url?id=%s.mp3" /><title>%s</title><summary>%s</summary></item><source name="网易云音乐" icon="https://pic.rmb.bdstatic.com/911423bee2bef937975b29b265d737b3.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.netease.cloudmusic" i_actionData="tencent100495085://" appid="100495085" /></msg>`
,
name
,
d
[
"id"
],
info
.
Get
(
"album.picUrl"
)
.
Str
,
d
[
"id"
],
name
,
artistName
)
return
&
message
.
ServiceElement
{
Id
:
60
,
Content
:
xml
,
SubType
:
"music"
,
},
nil
}
if
d
[
"type"
]
==
"custom"
{
xml
:=
fmt
.
Sprintf
(
`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`
,
d
[
"title"
],
d
[
"url"
],
d
[
"image"
],
d
[
"audio"
],
d
[
"title"
],
d
[
"content"
])
return
&
message
.
ServiceElement
{
Id
:
60
,
Content
:
xml
,
SubType
:
"music"
,
},
nil
}
return
nil
,
errors
.
New
(
"unsupported music type: "
+
d
[
"type"
])
case
"xml"
:
resId
:=
d
[
"resid"
]
template
:=
CQCodeEscapeValue
(
d
[
"data"
])
//println(template)
i
,
_
:=
strconv
.
ParseInt
(
resId
,
10
,
64
)
msg
:=
global
.
NewXmlMsg
(
template
,
i
)
return
msg
,
nil
default
:
default
:
return
nil
,
errors
.
New
(
"unsupported cq code: "
+
t
)
return
nil
,
errors
.
New
(
"unsupported cq code: "
+
t
)
}
}
...
...
docs/config.md
View file @
229098d2
...
@@ -25,12 +25,14 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
...
@@ -25,12 +25,14 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
"relogin"
:
false
,
"relogin"
:
false
,
"relogin_delay"
:
0
,
"relogin_delay"
:
0
,
"post_message_format"
:
"string"
,
"post_message_format"
:
"string"
,
"ignore_invalid_cqcode"
:
false
,
"force_fragmented"
:
true
,
"http_config"
:
{
"http_config"
:
{
"enabled"
:
true
,
"enabled"
:
true
,
"host"
:
"0.0.0.0"
,
"host"
:
"0.0.0.0"
,
"port"
:
5700
,
"port"
:
5700
,
"timeout"
:
5
,
"timeout"
:
5
,
"post_urls"
:
{
"url:port"
:
"secret"
}
,
"post_urls"
:
{
"url:port"
:
"secret"
}
},
},
"ws_config"
:
{
"ws_config"
:
{
"enabled"
:
true
,
"enabled"
:
true
,
...
@@ -51,18 +53,23 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
...
@@ -51,18 +53,23 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
| 字段 | 类型 | 说明 |
| 字段 | 类型 | 说明 |
| ------------------ | -------- | ------------------------------------------------------------------- |
| ------------------ | -------- | ------------------------------------------------------------------- |
| uin | int64 | 登录用QQ号 |
| uin | int64 | 登录用QQ号 |
| password | string | 登录用密码 |
| password | string | 登录用密码 |
| encrypt_password | bool | 是否对密码进行加密. |
| encrypt_password | bool | 是否对密码进行加密. |
| password_encrypted | string | 加密后的密码(请勿修改) |
| password_encrypted | string | 加密后的密码(请勿修改) |
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用
**回复/撤回**
等上下文相关接口 |
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用
**回复/撤回**
等上下文相关接口 |
| access_token | string | 同CQHTTP的
`access_token`
用于身份验证 |
| access_token | string | 同CQHTTP的
`access_token`
用于身份验证 |
| relogin | bool | 是否自动重新登录 |
| relogin | bool | 是否自动重新登录 |
| relogin_delay | int | 重登录延时(秒) |
| relogin_delay | int | 重登录延时(秒) |
| http_config | object | HTTP API配置 |
| post_message_format | string | 上报信息类型 |
| ws_config | object | Websocket API 配置 |
| ignore_invalid_cqcode| bool | 是否忽略错误的CQ码 |
| ws_reverse_servers | object[] | 反向 Websocket API 配置 |
| force_fragmented | bool | 是否强制分片发送群长消息 |
| http_config | object | HTTP API配置 |
| ws_config | object | Websocket API 配置 |
| ws_reverse_servers | object[] | 反向 Websocket API 配置 |
> 注: 开启密码加密后程序将在每次启动时要求输入解密密钥, 密钥错误会导致登录时提示密码错误.
> 注: 开启密码加密后程序将在每次启动时要求输入解密密钥, 密钥错误会导致登录时提示密码错误.
> 解密后密码将储存在内存中,用于自动重连等功能. 所以此加密并不能防止内存读取.
> 解密后密码将储存在内存中,用于自动重连等功能. 所以此加密并不能防止内存读取.
> 解密密钥在使用完成后并不会留存在内存中, 所以可用相对简单的字符串作为密钥
> 解密密钥在使用完成后并不会留存在内存中, 所以可用相对简单的字符串作为密钥
> 注2: 分片发送为原酷Q发送长消息的老方案, 发送速度更优/兼容性更好。关闭后将优先使用新方案, 能发送更长的消息, 但发送速度更慢,在部分老客户端将无法解析.
\ No newline at end of file
docs/cqhttp.md
View file @
229098d2
...
@@ -119,6 +119,51 @@ Type: `node`
...
@@ -119,6 +119,51 @@ Type: `node`
]
]
````
````
### xml支持
Type:
`xml`
范围:
**发送**
参数:
| 参数名 | 类型 | 说明 |
| ------ | ------ | ------------------------------------------------------------ |
| data | string | xml内容,xml中的value部分,记得实体化处理|
| resid | int32 | 可以不填|
示例:
`[CQ:xml,data=xxxx]`
####一些xml样例
####ps:重要:xml中的value部分,记得html实体化处理后,再打加入到cq码中
#### qq音乐
```
xml
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<msg
serviceID=
"2"
templateID=
"1"
action=
"web"
brief=
"[分享] 十年"
sourceMsgId=
"0"
url=
"https://i.y.qq.com/v8/playsong.html?_wv=1&songid=4830342&souce=qqshare&source=qqshare&ADTAG=qqshare"
flag=
"0"
adverSign=
"0"
multiMsgFlag=
"0"
><item
layout=
"2"
><audio
cover=
"http://imgcache.qq.com/music/photo/album_500/26/500_albumpic_89526_0.jpg"
src=
"http://ws.stream.qqmusic.qq.com/C400003mAan70zUy5O.m4a?guid=1535153710&vkey=D5315B8C0603653592AD4879A8A3742177F59D582A7A86546E24DD7F282C3ACF81526C76E293E57EA1E42CF19881C561275D919233333ADE&uin=&fromtag=3"
/><title>
十年
</title><summary>
陈奕迅
</summary></item><source
name=
"QQ音乐"
icon=
"https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png"
url=
"http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856"
action=
"app"
a_actionData=
"com.tencent.qqmusic"
i_actionData=
"tencent1101079856://"
appid=
"1101079856"
/></msg>
```
#### 网易音乐
```
xml
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<msg
serviceID=
"2"
templateID=
"1"
action=
"web"
brief=
"[分享] 十年"
sourceMsgId=
"0"
url=
"http://music.163.com/m/song/409650368"
flag=
"0"
adverSign=
"0"
multiMsgFlag=
"0"
><item
layout=
"2"
><audio
cover=
"http://p2.music.126.net/g-Qgb9ibk9Wp_0HWra0xQQ==/16636710440565853.jpg?param=90y90"
src=
"https://music.163.com/song/media/outer/url?id=409650368.mp3"
/><title>
十年
</title><summary>
黄梦之
</summary></item><source
name=
"网易云音乐"
icon=
"https://pic.rmb.bdstatic.com/911423bee2bef937975b29b265d737b3.png"
url=
"http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856"
action=
"app"
a_actionData=
"com.netease.cloudmusic"
i_actionData=
"tencent100495085://"
appid=
"100495085"
/></msg>
```
#### 卡片消息1
```
xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<msg
serviceID=
"1"
>
<item><title>
生死8秒!女司机高速急刹,他一个操作救下一车性命
</title></item>
<source
name=
"官方认证消息"
icon=
"https://qzs.qq.com/ac/qzone_v5/client/auth_icon.png"
action=
""
appid=
"-1"
/>
</msg>
```
#### 卡片消息2
```
xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<msg
serviceID=
"1"
>
<item
layout=
"4"
>
<title>
test title
</title>
<picture
cover=
"http://url.cn/5CEwIUy"
/>
</item>
</msg>
```
## API
## API
...
...
global/config.go
View file @
229098d2
...
@@ -6,19 +6,21 @@ import (
...
@@ -6,19 +6,21 @@ import (
)
)
type
JsonConfig
struct
{
type
JsonConfig
struct
{
Uin
int64
`json:"uin"`
Uin
int64
`json:"uin"`
Password
string
`json:"password"`
Password
string
`json:"password"`
EncryptPassword
bool
`json:"encrypt_password"`
EncryptPassword
bool
`json:"encrypt_password"`
PasswordEncrypted
string
`json:"password_encrypted"`
PasswordEncrypted
string
`json:"password_encrypted"`
EnableDB
bool
`json:"enable_db"`
EnableDB
bool
`json:"enable_db"`
AccessToken
string
`json:"access_token"`
AccessToken
string
`json:"access_token"`
ReLogin
bool
`json:"relogin"`
ReLogin
bool
`json:"relogin"`
ReLoginDelay
int
`json:"relogin_delay"`
ReLoginDelay
int
`json:"relogin_delay"`
HttpConfig
*
GoCQHttpConfig
`json:"http_config"`
IgnoreInvalidCQCode
bool
`json:"ignore_invalid_cqcode"`
WSConfig
*
GoCQWebsocketConfig
`json:"ws_config"`
ForceFragmented
bool
`json:"force_fragmented"`
ReverseServers
[]
*
GoCQReverseWebsocketConfig
`json:"ws_reverse_servers"`
HttpConfig
*
GoCQHttpConfig
`json:"http_config"`
PostMessageFormat
string
`json:"post_message_format"`
WSConfig
*
GoCQWebsocketConfig
`json:"ws_config"`
Debug
bool
`json:"debug"`
ReverseServers
[]
*
GoCQReverseWebsocketConfig
`json:"ws_reverse_servers"`
PostMessageFormat
string
`json:"post_message_format"`
Debug
bool
`json:"debug"`
}
}
type
CQHttpApiConfig
struct
{
type
CQHttpApiConfig
struct
{
...
@@ -68,6 +70,7 @@ func DefaultConfig() *JsonConfig {
...
@@ -68,6 +70,7 @@ func DefaultConfig() *JsonConfig {
ReLogin
:
true
,
ReLogin
:
true
,
ReLoginDelay
:
3
,
ReLoginDelay
:
3
,
PostMessageFormat
:
"string"
,
PostMessageFormat
:
"string"
,
ForceFragmented
:
true
,
HttpConfig
:
&
GoCQHttpConfig
{
HttpConfig
:
&
GoCQHttpConfig
{
Enabled
:
true
,
Enabled
:
true
,
Host
:
"0.0.0.0"
,
Host
:
"0.0.0.0"
,
...
...
global/filter.go
0 → 100644
View file @
229098d2
package
global
import
(
log
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"io/ioutil"
"regexp"
"strings"
"sync"
)
type
Filter
interface
{
Eval
(
payload
gjson
.
Result
)
bool
}
type
OperationNode
struct
{
key
string
filter
Filter
}
type
NotOperator
struct
{
operand_
Filter
}
func
notOperatorConstruct
(
argument
gjson
.
Result
)
*
NotOperator
{
if
!
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'not' operator must be an object"
)
}
op
:=
new
(
NotOperator
)
op
.
operand_
=
GetOperatorFactory
()
.
Generate
(
"and"
,
argument
)
return
op
}
func
(
notOperator
NotOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"not "
+
payload
.
Str
)
return
!
(
notOperator
.
operand_
)
.
Eval
(
payload
)
}
type
AndOperator
struct
{
operands
[]
OperationNode
}
func
andOperatorConstruct
(
argument
gjson
.
Result
)
*
AndOperator
{
if
!
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'and' operator must be an object"
)
}
op
:=
new
(
AndOperator
)
argument
.
ForEach
(
func
(
key
,
value
gjson
.
Result
)
bool
{
if
key
.
Str
[
0
]
==
'.'
{
// is an operator
// ".foo": {
// "bar": "baz"
// }
opKey
:=
key
.
Str
[
1
:
]
op
.
operands
=
append
(
op
.
operands
,
OperationNode
{
""
,
GetOperatorFactory
()
.
Generate
(
opKey
,
value
)})
}
else
if
value
.
IsObject
()
{
// is an normal key with an object as the value
// "foo": {
// ".bar": "baz"
// }
opKey
:=
key
.
Str
op
.
operands
=
append
(
op
.
operands
,
OperationNode
{
opKey
,
GetOperatorFactory
()
.
Generate
(
"and"
,
value
)})
}
else
{
// is an normal key with a non-object as the value
// "foo": "bar"
opKey
:=
key
.
Str
op
.
operands
=
append
(
op
.
operands
,
OperationNode
{
opKey
,
GetOperatorFactory
()
.
Generate
(
"eq"
,
value
)})
}
return
true
})
return
op
}
func
(
andOperator
*
AndOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"and "
+
payload
.
Str
)
res
:=
true
for
_
,
operand
:=
range
andOperator
.
operands
{
if
len
(
operand
.
key
)
==
0
{
// is an operator
res
=
res
&&
operand
.
filter
.
Eval
(
payload
)
}
else
{
// is an normal key
val
:=
payload
.
Get
(
operand
.
key
)
res
=
res
&&
operand
.
filter
.
Eval
(
val
)
}
if
res
==
false
{
break
}
}
return
res
}
type
OrOperator
struct
{
operands
[]
Filter
}
func
orOperatorConstruct
(
argument
gjson
.
Result
)
*
OrOperator
{
if
!
argument
.
IsArray
()
{
log
.
Error
(
"the argument of 'or' operator must be an array"
)
}
op
:=
new
(
OrOperator
)
argument
.
ForEach
(
func
(
_
,
value
gjson
.
Result
)
bool
{
op
.
operands
=
append
(
op
.
operands
,
GetOperatorFactory
()
.
Generate
(
"and"
,
value
))
return
true
})
return
op
}
func
(
orOperator
OrOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"or "
+
payload
.
Str
)
res
:=
false
for
_
,
operand
:=
range
orOperator
.
operands
{
res
=
res
||
operand
.
Eval
(
payload
)
if
res
==
true
{
break
}
}
return
res
}
type
EqualOperator
struct
{
value
gjson
.
Result
}
func
equalOperatorConstruct
(
argument
gjson
.
Result
)
*
EqualOperator
{
op
:=
new
(
EqualOperator
)
op
.
value
=
argument
return
op
}
func
(
equalOperator
EqualOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"eq "
+
payload
.
Str
+
"=="
+
equalOperator
.
value
.
Str
)
return
payload
.
Str
==
equalOperator
.
value
.
Str
}
type
NotEqualOperator
struct
{
value
gjson
.
Result
}
func
notEqualOperatorConstruct
(
argument
gjson
.
Result
)
*
NotEqualOperator
{
op
:=
new
(
NotEqualOperator
)
op
.
value
=
argument
return
op
}
func
(
notEqualOperator
NotEqualOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"neq "
+
payload
.
Str
)
return
!
(
payload
.
Str
==
notEqualOperator
.
value
.
Str
)
}
type
InOperator
struct
{
operand
gjson
.
Result
}
func
inOperatorConstruct
(
argument
gjson
.
Result
)
*
InOperator
{
if
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'in' operator must be an array or a string"
)
}
op
:=
new
(
InOperator
)
op
.
operand
=
argument
return
op
}
func
(
inOperator
InOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"in "
+
payload
.
Str
)
if
inOperator
.
operand
.
IsArray
()
{
res
:=
false
inOperator
.
operand
.
ForEach
(
func
(
key
,
value
gjson
.
Result
)
bool
{
res
=
res
||
value
.
Str
==
payload
.
Str
return
true
})
return
res
}
return
strings
.
Contains
(
inOperator
.
operand
.
Str
,
payload
.
Str
)
}
type
ContainsOperator
struct
{
operand
string
}
func
containsOperatorConstruct
(
argument
gjson
.
Result
)
*
ContainsOperator
{
if
argument
.
IsArray
()
||
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'contains' operator must be a string"
)
}
op
:=
new
(
ContainsOperator
)
op
.
operand
=
argument
.
Str
return
op
}
func
(
containsOperator
ContainsOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"contains "
+
payload
.
Str
)
if
payload
.
IsObject
()
||
payload
.
IsArray
()
{
return
false
}
return
strings
.
Contains
(
payload
.
String
(),
containsOperator
.
operand
)
}
type
RegexOperator
struct
{
regex
string
}
func
regexOperatorConstruct
(
argument
gjson
.
Result
)
*
RegexOperator
{
if
argument
.
IsArray
()
||
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'regex' operator must be a string"
)
}
op
:=
new
(
RegexOperator
)
op
.
regex
=
argument
.
Str
return
op
}
func
(
containsOperator
RegexOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"regex "
+
payload
.
Str
)
matched
,
_
:=
regexp
.
MatchString
(
containsOperator
.
regex
,
payload
.
Str
)
return
matched
}
// 单例工厂
type
operatorFactory
struct
{
}
var
instance
*
operatorFactory
=
&
operatorFactory
{}
func
GetOperatorFactory
()
*
operatorFactory
{
return
instance
}
func
(
o
operatorFactory
)
Generate
(
opName
string
,
argument
gjson
.
Result
)
Filter
{
switch
opName
{
case
"not"
:
return
notOperatorConstruct
(
argument
)
case
"and"
:
return
andOperatorConstruct
(
argument
)
case
"or"
:
return
orOperatorConstruct
(
argument
)
case
"neq"
:
return
notEqualOperatorConstruct
(
argument
)
case
"eq"
:
return
equalOperatorConstruct
(
argument
)
case
"in"
:
return
inOperatorConstruct
(
argument
)
case
"contains"
:
return
containsOperatorConstruct
(
argument
)
case
"regex"
:
return
regexOperatorConstruct
(
argument
)
default
:
log
.
Warnf
(
"the operator '%s' is not supported"
,
opName
)
return
nil
}
}
var
filter
=
new
(
Filter
)
var
once
sync
.
Once
// 过滤器单例模式
func
GetFilter
()
*
Filter
{
once
.
Do
(
func
()
{
f
,
err
:=
ioutil
.
ReadFile
(
"filter.json"
)
if
err
!=
nil
{
filter
=
nil
}
else
{
*
filter
=
GetOperatorFactory
()
.
Generate
(
"and"
,
gjson
.
ParseBytes
(
f
))
}
})
return
filter
}
\ No newline at end of file
global/net.go
View file @
229098d2
...
@@ -3,9 +3,14 @@ package global
...
@@ -3,9 +3,14 @@ package global
import
(
import
(
"bytes"
"bytes"
"compress/gzip"
"compress/gzip"
"fmt"
"io/ioutil"
"io/ioutil"
"net/http"
"net/http"
"strconv"
"strings"
"strings"
"github.com/Mrs4s/MiraiGo/message"
"github.com/tidwall/gjson"
)
)
func
GetBytes
(
url
string
)
([]
byte
,
error
)
{
func
GetBytes
(
url
string
)
([]
byte
,
error
)
{
...
@@ -32,3 +37,35 @@ func GetBytes(url string) ([]byte, error) {
...
@@ -32,3 +37,35 @@ func GetBytes(url string) ([]byte, error) {
}
}
return
body
,
nil
return
body
,
nil
}
}
func
QQMusicSongInfo
(
id
string
)
(
gjson
.
Result
,
error
)
{
d
,
err
:=
GetBytes
(
`https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={%22comm%22:{%22ct%22:24,%22cv%22:0},%22songinfo%22:{%22method%22:%22get_song_detail_yqq%22,%22param%22:{%22song_type%22:0,%22song_mid%22:%22%22,%22song_id%22:`
+
id
+
`},%22module%22:%22music.pf_song_detail_svr%22}}`
)
if
err
!=
nil
{
return
gjson
.
Result
{},
err
}
return
gjson
.
ParseBytes
(
d
)
.
Get
(
"songinfo.data"
),
nil
}
func
NeteaseMusicSongInfo
(
id
string
)
(
gjson
.
Result
,
error
)
{
d
,
err
:=
GetBytes
(
fmt
.
Sprintf
(
"http://music.163.com/api/song/detail/?id=%s&ids=%%5B%s%%5D"
,
id
,
id
))
if
err
!=
nil
{
return
gjson
.
Result
{},
err
}
return
gjson
.
ParseBytes
(
d
)
.
Get
(
"songs.0"
),
nil
}
func
NewXmlMsg
(
template
string
,
ResId
int64
)
*
message
.
ServiceElement
{
var
serviceid
string
if
ResId
==
0
{
serviceid
=
"2"
//默认值2
}
else
{
serviceid
=
strconv
.
FormatInt
(
ResId
,
10
)
}
//println(serviceid)
return
&
message
.
ServiceElement
{
Id
:
int32
(
ResId
),
Content
:
template
,
ResId
:
serviceid
,
SubType
:
"xml"
,
}
}
go.mod
View file @
229098d2
...
@@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
...
@@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
go 1.14
go 1.14
require (
require (
github.com/Mrs4s/MiraiGo v0.0.0-2020082
1182324-7654a7a2a106
github.com/Mrs4s/MiraiGo v0.0.0-2020082
5052841-d3b0f5f9e839
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/gin-gonic/gin v1.6.3
github.com/gorilla/websocket v1.4.2
github.com/gorilla/websocket v1.4.2
...
...
go.sum
View file @
229098d2
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 h1:50yz9Xgup7WgFAxeen/GQ0fCX3YUvv+ipGktZIznDuU=
github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839 h1:TDhaPfWcubIMKDz1HU+N07SwIUjj7oVUQ7EXZBbDUxs=
github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcDm+MRPevKEFg8+VJ9iOGjF4yNOo=
github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 h1:z2oaXbvOmu7/O666OkUeH5SGUjyQ3wUSNjtTOagY8Sk=
github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
...
@@ -49,21 +42,16 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
...
@@ -49,21 +42,16 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/guonaihong/gout v0.1.1 h1:2i3eqQ1KUhTlj7AFeIHqVUFku5QwUhwE2wNgYTVpbxQ=
github.com/guonaihong/gout v0.1.1 h1:2i3eqQ1KUhTlj7AFeIHqVUFku5QwUhwE2wNgYTVpbxQ=
github.com/guonaihong/gout v0.1.1/go.mod h1:vXvv5Kxr70eM5wrp4F0+t9lnLWmq+YPW2GByll2f/EA=
github.com/guonaihong/gout v0.1.1/go.mod h1:vXvv5Kxr70eM5wrp4F0+t9lnLWmq+YPW2GByll2f/EA=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs=
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
...
@@ -71,7 +59,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
...
@@ -71,7 +59,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
...
@@ -80,16 +67,13 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7
...
@@ -80,16 +67,13 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
...
@@ -99,11 +83,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
...
@@ -99,11 +83,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
...
@@ -154,7 +136,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
...
@@ -154,7 +136,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
...
@@ -174,7 +155,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
...
@@ -174,7 +155,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
...
...
main.go
View file @
229098d2
...
@@ -186,6 +186,16 @@ func main() {
...
@@ -186,6 +186,16 @@ func main() {
time
.
Sleep
(
time
.
Second
*
5
)
time
.
Sleep
(
time
.
Second
*
5
)
log
.
Info
(
"开始尝试登录并同步消息..."
)
log
.
Info
(
"开始尝试登录并同步消息..."
)
cli
:=
client
.
NewClient
(
conf
.
Uin
,
conf
.
Password
)
cli
:=
client
.
NewClient
(
conf
.
Uin
,
conf
.
Password
)
cli
.
OnLog
(
func
(
c
*
client
.
QQClient
,
e
*
client
.
LogEvent
)
{
switch
e
.
Type
{
case
"INFO"
:
log
.
Info
(
"Protocol -> "
+
e
.
Message
)
case
"ERROR"
:
log
.
Error
(
"Protocol -> "
+
e
.
Message
)
case
"DEBUG"
:
log
.
Debug
(
"Protocol -> "
+
e
.
Message
)
}
})
rsp
,
err
:=
cli
.
Login
()
rsp
,
err
:=
cli
.
Login
()
for
{
for
{
global
.
Check
(
err
)
global
.
Check
(
err
)
...
@@ -225,6 +235,8 @@ func main() {
...
@@ -225,6 +235,8 @@ func main() {
}
else
{
}
else
{
coolq
.
SetMessageFormat
(
conf
.
PostMessageFormat
)
coolq
.
SetMessageFormat
(
conf
.
PostMessageFormat
)
}
}
coolq
.
IgnoreInvalidCQCode
=
conf
.
IgnoreInvalidCQCode
coolq
.
ForceFragmented
=
conf
.
ForceFragmented
if
conf
.
HttpConfig
!=
nil
&&
conf
.
HttpConfig
.
Enabled
{
if
conf
.
HttpConfig
!=
nil
&&
conf
.
HttpConfig
.
Enabled
{
server
.
HttpServer
.
Run
(
fmt
.
Sprintf
(
"%s:%d"
,
conf
.
HttpConfig
.
Host
,
conf
.
HttpConfig
.
Port
),
conf
.
AccessToken
,
b
)
server
.
HttpServer
.
Run
(
fmt
.
Sprintf
(
"%s:%d"
,
conf
.
HttpConfig
.
Host
,
conf
.
HttpConfig
.
Port
),
conf
.
AccessToken
,
b
)
for
k
,
v
:=
range
conf
.
HttpConfig
.
PostUrls
{
for
k
,
v
:=
range
conf
.
HttpConfig
.
PostUrls
{
...
...
server/http.go
View file @
229098d2
...
@@ -41,7 +41,7 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
...
@@ -41,7 +41,7 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
c
.
Status
(
404
)
c
.
Status
(
404
)
return
return
}
}
if
c
.
Request
.
Method
==
"POST"
&&
c
.
Request
.
Header
.
Get
(
"Content-Type"
)
==
"application/json"
{
if
c
.
Request
.
Method
==
"POST"
&&
strings
.
Contains
(
c
.
Request
.
Header
.
Get
(
"Content-Type"
),
"application/json"
)
{
d
,
err
:=
c
.
GetRawData
()
d
,
err
:=
c
.
GetRawData
()
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Warnf
(
"获取请求 %v 的Body时出现错误: %v"
,
c
.
Request
.
RequestURI
,
err
)
log
.
Warnf
(
"获取请求 %v 的Body时出现错误: %v"
,
c
.
Request
.
RequestURI
,
err
)
...
@@ -400,6 +400,7 @@ func getParamOrDefault(c *gin.Context, k, def string) string {
...
@@ -400,6 +400,7 @@ func getParamOrDefault(c *gin.Context, k, def string) string {
return
def
return
def
}
}
func
getParam
(
c
*
gin
.
Context
,
k
string
)
string
{
func
getParam
(
c
*
gin
.
Context
,
k
string
)
string
{
p
,
_
:=
getParamWithType
(
c
,
k
)
p
,
_
:=
getParamWithType
(
c
,
k
)
return
p
return
p
...
...
server/websocket.go
View file @
229098d2
...
@@ -174,33 +174,31 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) {
...
@@ -174,33 +174,31 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) {
func
(
c
*
websocketClient
)
onBotPushEvent
(
m
coolq
.
MSG
)
{
func
(
c
*
websocketClient
)
onBotPushEvent
(
m
coolq
.
MSG
)
{
if
c
.
eventConn
!=
nil
{
if
c
.
eventConn
!=
nil
{
log
.
Debugf
(
"向WS服务器 %v 推送Event: %v"
,
c
.
eventConn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
log
.
Debugf
(
"向WS服务器 %v 推送Event: %v"
,
c
.
eventConn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
c
.
eventConn
.
Lock
()
conn
:=
c
.
eventConn
defer
c
.
eventConn
.
Unlock
()
conn
.
Lock
()
defer
conn
.
Unlock
()
_
=
c
.
eventConn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
15
))
_
=
c
.
eventConn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
15
))
if
err
:=
c
.
eventConn
.
WriteJSON
(
m
);
err
!=
nil
{
if
err
:=
c
.
eventConn
.
WriteJSON
(
m
);
err
!=
nil
{
log
.
Warnf
(
"向WS服务器 %v 推送Event时出现错误: %v"
,
c
.
eventConn
.
RemoteAddr
()
.
String
(),
err
)
log
.
Warnf
(
"向WS服务器 %v 推送Event时出现错误: %v"
,
c
.
eventConn
.
RemoteAddr
()
.
String
(),
err
)
_
=
c
.
eventConn
.
Close
()
_
=
c
.
eventConn
.
Close
()
if
c
.
conf
.
ReverseReconnectInterval
!=
0
{
if
c
.
conf
.
ReverseReconnectInterval
!=
0
{
go
func
()
{
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
c
.
conf
.
ReverseReconnectInterval
))
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
c
.
conf
.
ReverseReconnectInterval
))
c
.
connectEvent
()
c
.
connectEvent
()
}()
}
}
}
}
}
}
if
c
.
universalConn
!=
nil
{
if
c
.
universalConn
!=
nil
{
log
.
Debugf
(
"向WS服务器 %v 推送Event: %v"
,
c
.
universalConn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
log
.
Debugf
(
"向WS服务器 %v 推送Event: %v"
,
c
.
universalConn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
c
.
universalConn
.
Lock
()
conn
:=
c
.
universalConn
defer
c
.
universalConn
.
Unlock
()
conn
.
Lock
()
defer
conn
.
Unlock
()
_
=
c
.
universalConn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
15
))
_
=
c
.
universalConn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
15
))
if
err
:=
c
.
universalConn
.
WriteJSON
(
m
);
err
!=
nil
{
if
err
:=
c
.
universalConn
.
WriteJSON
(
m
);
err
!=
nil
{
log
.
Warnf
(
"向WS服务器 %v 推送Event时出现错误: %v"
,
c
.
universalConn
.
RemoteAddr
()
.
String
(),
err
)
log
.
Warnf
(
"向WS服务器 %v 推送Event时出现错误: %v"
,
c
.
universalConn
.
RemoteAddr
()
.
String
(),
err
)
_
=
c
.
universalConn
.
Close
()
_
=
c
.
universalConn
.
Close
()
if
c
.
conf
.
ReverseReconnectInterval
!=
0
{
if
c
.
conf
.
ReverseReconnectInterval
!=
0
{
go
func
()
{
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
c
.
conf
.
ReverseReconnectInterval
))
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
c
.
conf
.
ReverseReconnectInterval
))
c
.
connectUniversal
()
c
.
connectUniversal
()
}()
}
}
}
}
}
}
...
@@ -318,18 +316,21 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) {
...
@@ -318,18 +316,21 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) {
func
(
s
*
websocketServer
)
onBotPushEvent
(
m
coolq
.
MSG
)
{
func
(
s
*
websocketServer
)
onBotPushEvent
(
m
coolq
.
MSG
)
{
s
.
eventConnMutex
.
Lock
()
s
.
eventConnMutex
.
Lock
()
defer
s
.
eventConnMutex
.
Unlock
()
defer
s
.
eventConnMutex
.
Unlock
()
pos
:=
0
for
i
,
l
:=
0
,
len
(
s
.
eventConn
);
i
<
l
;
i
++
{
for
_
,
conn
:=
range
s
.
eventConn
{
conn
:=
s
.
eventConn
[
i
]
log
.
Debugf
(
"向WS客户端 %v 推送Event: %v"
,
conn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
log
.
Debugf
(
"向WS客户端 %v 推送Event: %v"
,
conn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
err
:=
conn
.
WriteMessage
(
websocket
.
TextMessage
,
[]
byte
(
m
.
ToJson
()))
if
err
:=
conn
.
WriteMessage
(
websocket
.
TextMessage
,
[]
byte
(
m
.
ToJson
()));
err
!=
nil
{
if
err
!=
nil
{
_
=
conn
.
Close
()
_
=
conn
.
Close
()
s
.
eventConn
=
append
(
s
.
eventConn
[
:
pos
],
s
.
eventConn
[
pos
+
1
:
]
...
)
next
:=
i
+
1
if
pos
>
0
{
if
next
>=
l
{
pos
++
next
=
l
-
1
}
}
s
.
eventConn
[
i
],
s
.
eventConn
[
next
]
=
s
.
eventConn
[
next
],
s
.
eventConn
[
i
]
s
.
eventConn
=
append
(
s
.
eventConn
[
:
next
],
s
.
eventConn
[
next
+
1
:
]
...
)
i
--
l
--
conn
=
nil
}
}
pos
++
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment