Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(QQ): 实现内置 lagrange 的原型版本 #668

Merged
merged 22 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7d2efd5
feat(QQ): 实现内置 lagrange 的原型版本
JustAnotherID Mar 22, 2024
d480d40
chore: make lint happy
JustAnotherID Mar 22, 2024
50a740c
chore: as review
JustAnotherID Mar 24, 2024
17c4a59
Merge branch 'refs/heads/master' into feature/lagrange
JustAnotherID Mar 24, 2024
261618e
Merge remote-tracking branch 'refs/remotes/sealdice/master' into feat…
JustAnotherID Mar 24, 2024
38754da
chore: as review
JustAnotherID Mar 25, 2024
3316637
Merge branch 'refs/heads/master' into feature/lagrange
JustAnotherID Mar 25, 2024
92353f0
imp: 不复制 Lagrange 而是通过更改 workdir 实现多实例
Szzrain Mar 26, 2024
e7bac69
as revew
Szzrain Mar 26, 2024
10c7802
imp: 适配安卓端对接
Szzrain Apr 1, 2024
f420775
fix: typo
Szzrain Apr 1, 2024
1120d1a
imp: 添加连接成功前的 log, 配置文件携带 UIN
Szzrain Apr 1, 2024
ffbd338
imp: 添加连接成功前的 log, 配置文件携带 UIN
Szzrain Apr 1, 2024
f07aa8e
chore: make lint happy
Szzrain Apr 1, 2024
5bf579e
chore: make lint happy x2
Szzrain Apr 1, 2024
198f314
chore: replace localhost to 127.0.0.1
JustAnotherID Apr 2, 2024
e166001
Merge branch 'refs/heads/master' into feature/lagrange
JustAnotherID Apr 2, 2024
68792f2
chore: 内置sign
Szzrain Apr 2, 2024
ef6b38d
fix: uin 错误的字段
Szzrain Apr 2, 2024
dd5ca62
fix: uin 错误的字段(真的修好了)
Szzrain Apr 2, 2024
057f2cc
fix: 启动拉格兰后直接进入连接中 `ep.State=2`
Szzrain Apr 2, 2024
794b8f7
imp: ws 连接出错时打印 url
Szzrain Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ temp/

dist/
go-cqhttp/
lagrange/
frontend/
frontend-overwrite/
backups/
Expand Down
3 changes: 2 additions & 1 deletion api/api_bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func Bind(e *echo.Echo, _myDice *dice.DiceManager) {
e.POST(prefix+"/im_connections/sms_code_get", ImConnectionsSmsCodeGet)
e.POST(prefix+"/im_connections/sms_code_set", ImConnectionsSmsCodeSet)
e.POST(prefix+"/im_connections/gocq_captcha_set", ImConnectionsCaptchaSet)
e.POST(prefix+"/im_connections/add", ImConnectionsAdd)
e.POST(prefix+"/im_connections/add", ImConnectionsAddBuiltinGocq)
Xiangze-Li marked this conversation as resolved.
Show resolved Hide resolved
e.POST(prefix+"/im_connections/addOnebot11ReverseWs", ImConnectionsAddReverseWs)
e.POST(prefix+"/im_connections/addGocqSeparate", ImConnectionsAddGocqSeparate)
e.POST(prefix+"/im_connections/addDiscord", ImConnectionsAddDiscord)
Expand All @@ -400,6 +400,7 @@ func Bind(e *echo.Echo, _myDice *dice.DiceManager) {
e.POST(prefix+"/im_connections/addOfficialQQ", ImConnectionsAddOfficialQQ)
e.POST(prefix+"/im_connections/addSealChat", ImConnectionsAddSealChat)
e.POST(prefix+"/im_connections/addSatori", ImConnectionsAddSatori)
e.POST(prefix+"/im_connections/addLagrange", ImConnectionsAddBuiltinLagrange)
e.POST(prefix+"/im_connections/del", ImConnectionsDel)
e.POST(prefix+"/im_connections/set_enable", ImConnectionsSetEnable)
e.POST(prefix+"/im_connections/set_data", ImConnectionsSetData)
Expand Down
43 changes: 42 additions & 1 deletion api/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func ImConnectionsDel(c echo.Context) error {
myDice.ImSession.EndPoints = append(myDice.ImSession.EndPoints[:index], myDice.ImSession.EndPoints[index+1:]...)
if i.ProtocolType == "onebot" {
dice.GoCqhttpServeProcessKill(myDice, i)
dice.LagrangeServeProcessKill(myDice, i)
}
return c.JSON(http.StatusOK, i)
case "DISCORD":
Expand Down Expand Up @@ -661,7 +662,7 @@ func ImConnectionsAddSlack(c echo.Context) error {
return c.String(430, "")
}

func ImConnectionsAdd(c echo.Context) error {
func ImConnectionsAddBuiltinGocq(c echo.Context) error {
if !doAuth(c) {
return c.JSON(http.StatusForbidden, nil)
}
Expand Down Expand Up @@ -905,3 +906,43 @@ func ImConnectionsAddSatori(c echo.Context) error {
go dice.ServeQQ(myDice, conn)
return Success(&c, Response{})
}

func ImConnectionsAddBuiltinLagrange(c echo.Context) error {
if !doAuth(c) {
return c.JSON(http.StatusForbidden, nil)
}
if dm.JustForTest {
return c.JSON(http.StatusOK, Response{"testMode": true})
}

v := struct {
Account string `yaml:"account" json:"account"`
Protocol int `yaml:"protocol" json:"protocol"`
}{}
err := c.Bind(&v)
if err == nil {
uid := v.Account
for _, i := range myDice.ImSession.EndPoints {
if i.UserID == dice.FormatDiceIDQQ(uid) {
return c.JSON(CodeAlreadyExists, i)
}
}
conn := dice.NewLagrangeConnectInfoItem(v.Account)
conn.UserID = dice.FormatDiceIDQQ(uid)
conn.Session = myDice.ImSession
pa := conn.Adapter.(*dice.PlatformAdapterGocq)
pa.InPackGoCqhttpProtocol = v.Protocol
pa.Session = myDice.ImSession

myDice.ImSession.EndPoints = append(myDice.ImSession.EndPoints, conn)
myDice.LastUpdatedTime = time.Now().Unix()

dice.LagrangeServe(myDice, conn, dice.GoCqhttpLoginInfo{
Protocol: v.Protocol,
IsAsyncRun: true,
})
return c.JSON(http.StatusOK, v)
}

return c.String(430, "")
}
99 changes: 66 additions & 33 deletions dice/platform_adapter_gocq.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ type PlatformAdapterGocq struct {
ConnectURL string `yaml:"connectUrl" json:"connectUrl"` // 连接地址
AccessToken string `yaml:"accessToken" json:"accessToken"` // 访问令牌

UseInPackGoCqhttp bool `yaml:"useInPackGoCqhttp" json:"useInPackGoCqhttp"` // 是否使用内置的gocqhttp
GoCqhttpState int `yaml:"-" json:"loginState"` // 当前状态
CurLoginIndex int `yaml:"-" json:"curLoginIndex"` // 当前登录序号,如果正在进行的登录不是该Index,证明过时
UseInPackGoCqhttp bool `yaml:"useInPackGoCqhttp" json:"useInPackGoCqhttp"` // 是否使用内置的gocqhttp
BuiltinMode string `yaml:"builtinMode" json:"builtinMode"`
GoCqhttpState int `yaml:"-" json:"loginState"` // 当前状态
CurLoginIndex int `yaml:"-" json:"curLoginIndex"` // 当前登录序号,如果正在进行的登录不是该Index,证明过时

GoCqhttpProcess *procs.Process `yaml:"-" json:"-"`
GocqhttpLoginFailedReason string `yaml:"-" json:"curLoginFailedReason"` // 当前登录失败原因
Expand Down Expand Up @@ -355,7 +356,11 @@ func OneBot11CqMessageToArrayMessage(longText string) []interface{} {
}

func (pa *PlatformAdapterGocq) Serve() int {
pa.Implementation = "gocq"
if pa.BuiltinMode == "lagrange" {
pa.Implementation = "lagrange"
} else {
pa.Implementation = "gocq"
}
ep := pa.EndPoint
s := pa.Session
log := s.Parent.Logger
Expand Down Expand Up @@ -1133,24 +1138,40 @@ func (pa *PlatformAdapterGocq) DoRelogin() bool {
if pa.InPackGoCqhttpDisconnectedCH != nil {
pa.InPackGoCqhttpDisconnectedCH <- -1
}
myDice.Logger.Infof("重新启动go-cqhttp进程,对应账号: <%s>(%s)", ep.Nickname, ep.UserID)
pa.CurLoginIndex++
pa.GoCqhttpState = StateCodeInit
go GoCqhttpServeProcessKill(myDice, ep)
time.Sleep(10 * time.Second) // 上面那个清理有概率卡住,具体不懂,改成等5s -> 10s 超过一次重试间隔
GoCqhttpServeRemoveSessionToken(myDice, ep) // 删除session.token
pa.GoCqhttpLastRestrictedTime = 0 // 重置风控时间
myDice.LastUpdatedTime = time.Now().Unix()
myDice.Save(false)
GoCqhttpServe(myDice, ep, GoCqhttpLoginInfo{
Password: pa.InPackGoCqhttpPassword,
Protocol: pa.InPackGoCqhttpProtocol,
AppVersion: pa.InPackGoCqhttpAppVersion,
IsAsyncRun: true,
UseSignServer: pa.UseSignServer,
SignServerConfig: pa.SignServerConfig,
})
return true
if pa.BuiltinMode != "gocq" {
JustAnotherID marked this conversation as resolved.
Show resolved Hide resolved
myDice.Logger.Infof("重新启动 lagrange 进程,对应账号: <%s>(%s)", ep.Nickname, ep.UserID)
pa.CurLoginIndex++
pa.GoCqhttpState = StateCodeInit
go LagrangeServeProcessKill(myDice, ep)
time.Sleep(10 * time.Second) // 上面那个清理有概率卡住,具体不懂,改成等5s -> 10s 超过一次重试间隔
LagrangeServeRemoveSession(myDice, ep) // 删除 keystore
pa.GoCqhttpLastRestrictedTime = 0 // 重置风控时间
myDice.LastUpdatedTime = time.Now().Unix()
myDice.Save(false)
GoCqhttpServe(myDice, ep, GoCqhttpLoginInfo{
IsAsyncRun: true,
})
return true
} else {
myDice.Logger.Infof("重新启动go-cqhttp进程,对应账号: <%s>(%s)", ep.Nickname, ep.UserID)
pa.CurLoginIndex++
pa.GoCqhttpState = StateCodeInit
go GoCqhttpServeProcessKill(myDice, ep)
time.Sleep(10 * time.Second) // 上面那个清理有概率卡住,具体不懂,改成等5s -> 10s 超过一次重试间隔
GoCqhttpServeRemoveSessionToken(myDice, ep) // 删除session.token
pa.GoCqhttpLastRestrictedTime = 0 // 重置风控时间
myDice.LastUpdatedTime = time.Now().Unix()
myDice.Save(false)
GoCqhttpServe(myDice, ep, GoCqhttpLoginInfo{
Password: pa.InPackGoCqhttpPassword,
Protocol: pa.InPackGoCqhttpProtocol,
AppVersion: pa.InPackGoCqhttpAppVersion,
IsAsyncRun: true,
UseSignServer: pa.UseSignServer,
SignServerConfig: pa.SignServerConfig,
})
return true
}
}
return false
}
Expand All @@ -1163,16 +1184,24 @@ func (pa *PlatformAdapterGocq) SetEnable(enable bool) {
pa.DiceServing = false

if pa.UseInPackGoCqhttp {
GoCqhttpServeProcessKill(d, c)
time.Sleep(1 * time.Second)
GoCqhttpServe(d, c, GoCqhttpLoginInfo{
Password: pa.InPackGoCqhttpPassword,
Protocol: pa.InPackGoCqhttpProtocol,
AppVersion: pa.InPackGoCqhttpAppVersion,
IsAsyncRun: true,
UseSignServer: pa.UseSignServer,
SignServerConfig: pa.SignServerConfig,
})
if pa.BuiltinMode != "gocq" {
JustAnotherID marked this conversation as resolved.
Show resolved Hide resolved
LagrangeServeProcessKill(d, c)
time.Sleep(1 * time.Second)
LagrangeServe(d, c, GoCqhttpLoginInfo{
IsAsyncRun: true,
})
} else {
GoCqhttpServeProcessKill(d, c)
time.Sleep(1 * time.Second)
GoCqhttpServe(d, c, GoCqhttpLoginInfo{
Password: pa.InPackGoCqhttpPassword,
Protocol: pa.InPackGoCqhttpProtocol,
AppVersion: pa.InPackGoCqhttpAppVersion,
IsAsyncRun: true,
UseSignServer: pa.UseSignServer,
SignServerConfig: pa.SignServerConfig,
})
}
go ServeQQ(d, c)
} else {
go ServeQQ(d, c)
Expand All @@ -1181,7 +1210,11 @@ func (pa *PlatformAdapterGocq) SetEnable(enable bool) {
c.Enable = false
pa.DiceServing = false
if pa.UseInPackGoCqhttp {
GoCqhttpServeProcessKill(d, c)
if pa.BuiltinMode != "gocq" {
JustAnotherID marked this conversation as resolved.
Show resolved Hide resolved
LagrangeServeProcessKill(d, c)
} else {
GoCqhttpServeProcessKill(d, c)
}
}
if pa.IsReverse && pa.reverseApp != nil {
_ = pa.reverseApp.Close()
Expand Down
5 changes: 3 additions & 2 deletions dice/platform_adapter_gocq_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ func NewGoCqhttpConnectInfoItem(account string) *EndPointInfo {
conn.Adapter = &PlatformAdapterGocq{
EndPoint: conn,
UseInPackGoCqhttp: true,
BuiltinMode: "gocq",
}
return conn
}
Expand All @@ -504,7 +505,7 @@ func GoCqhttpServeProcessKill(dice *Dice, conn *EndPointInfo) {
if !ok {
return
}
if pa.UseInPackGoCqhttp {
if pa.UseInPackGoCqhttp && pa.BuiltinMode == "gocq" {
JustAnotherID marked this conversation as resolved.
Show resolved Hide resolved
JustAnotherID marked this conversation as resolved.
Show resolved Hide resolved
// 重置状态
conn.State = 0
pa.GoCqhttpState = 0
Expand Down Expand Up @@ -580,7 +581,7 @@ func GoCqhttpServe(dice *Dice, conn *EndPointInfo, loginInfo GoCqhttpLoginInfo)
loginIndex := pa.CurLoginIndex
pa.GoCqhttpState = StateCodeInLogin

if pa.UseInPackGoCqhttp { //nolint:nestif
if pa.UseInPackGoCqhttp && (pa.BuiltinMode == "" || pa.BuiltinMode == "gocq") { //nolint:nestif
workDir := gocqGetWorkDir(dice, conn)
_ = os.MkdirAll(workDir, 0o755)

Expand Down
Loading
Loading