mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-20 06:20:08 +08:00
feat:添加月幕galgame网站图 (#138)
* feat:添加月幕galgame网站图 * fix:修lint * fix:不重复更新 * fix:增加命令提醒语 * fix:增加日语匹配 * fix:换位置加锁 * fix:隐式声明 * fix:copy数组 * Update ai_tts.go Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
This commit is contained in:
parent
a469000d7a
commit
5c620d6268
@ -287,6 +287,12 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
|
|||||||
- **煎蛋网无聊图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan"`
|
- **煎蛋网无聊图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan"`
|
||||||
- [x] 来份屌图
|
- [x] 来份屌图
|
||||||
- [x] 更新屌图
|
- [x] 更新屌图
|
||||||
|
- **月幕galgame图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal"`
|
||||||
|
- [x] 随机galCG
|
||||||
|
- [x] 随机gal表情包
|
||||||
|
- [x] galCG[xxx]
|
||||||
|
- [x] gal表情包[xxx]
|
||||||
|
- [x] 更新gal
|
||||||
- **TODO...**
|
- **TODO...**
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|||||||
1
main.go
1
main.go
@ -100,6 +100,7 @@ import (
|
|||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
|
||||||
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
|
||||||
|
|
||||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
||||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili_push" // b站推送
|
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili_push" // b站推送
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/pkumza/numcn"
|
"github.com/pkumza/numcn"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -38,18 +39,26 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ttsInstances struct {
|
type ttsInstances struct {
|
||||||
|
sync.RWMutex
|
||||||
m map[string]tts.TTS
|
m map[string]tts.TTS
|
||||||
l []string
|
l []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ttsInstances) List() []string {
|
func (t *ttsInstances) List() []string {
|
||||||
return t.l
|
t.RLock()
|
||||||
|
cl := make([]string, len(t.l))
|
||||||
|
_ = copy(cl, t.l)
|
||||||
|
t.RUnlock()
|
||||||
|
return cl
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
engine := control.Register(ttsServiceName, order.AcquirePrio(), &control.Options{
|
engine := control.Register(ttsServiceName, order.AcquirePrio(), &control.Options{
|
||||||
DisableOnDefault: false,
|
DisableOnDefault: true,
|
||||||
Help: "语音回复(包括拟声鸟和百度)\n- @Bot 任意文本(任意一句话回复)\n- 设置语音模式拟声鸟阿梓 | 设置语音模式拟声鸟药水哥 | 设置语音模式百度女声 | 设置语音模式百度男声| 设置语音模式百度度逍遥 | 设置语音模式百度度丫丫",
|
Help: "语音回复(包括拟声鸟和百度)\n" +
|
||||||
|
"- @Bot 任意文本(任意一句话回复)\n" +
|
||||||
|
"- 设置语音模式[拟声鸟阿梓 | 拟声鸟药水哥 | 百度女声 | 百度男声| 百度度逍遥 | 百度度丫丫]\n" +
|
||||||
|
"- 设置默认语音模式[拟声鸟阿梓 | 拟声鸟药水哥 | 百度女声 | 百度男声| 百度度逍遥 | 百度度丫丫]\n",
|
||||||
})
|
})
|
||||||
engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
@ -78,7 +87,13 @@ func init() {
|
|||||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功"))
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前模式为", param))
|
||||||
|
})
|
||||||
|
engine.OnRegex(`^设置默认语音模式(.*)$`, ctxext.FirstValueInList(t)).SetBlock(true).
|
||||||
|
Handle(func(ctx *zero.Ctx) {
|
||||||
|
param := ctx.State["regex_matched"].([]string)[1]
|
||||||
|
t.setDefaultSoundMode(param)
|
||||||
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,默认模式为", param))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,12 +108,14 @@ func (t *ttsInstances) setSoundMode(ctx *zero.Ctx, name string) error {
|
|||||||
gid = -ctx.Event.UserID
|
gid = -ctx.Event.UserID
|
||||||
}
|
}
|
||||||
var index int64
|
var index int64
|
||||||
|
t.RLock()
|
||||||
for i, s := range t.l {
|
for i, s := range t.l {
|
||||||
if s == name {
|
if s == name {
|
||||||
index = int64(i)
|
index = int64(i)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t.RUnlock()
|
||||||
m, ok := control.Lookup(ttsServiceName)
|
m, ok := control.Lookup(ttsServiceName)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("no such plugin")
|
return errors.New("no such plugin")
|
||||||
@ -113,6 +130,8 @@ func (t *ttsInstances) getSoundMode(ctx *zero.Ctx) (name string) {
|
|||||||
}
|
}
|
||||||
m, ok := control.Lookup(ttsServiceName)
|
m, ok := control.Lookup(ttsServiceName)
|
||||||
if ok {
|
if ok {
|
||||||
|
t.RLock()
|
||||||
|
defer t.RUnlock()
|
||||||
index := m.GetData(gid)
|
index := m.GetData(gid)
|
||||||
if int(index) < len(t.l) {
|
if int(index) < len(t.l) {
|
||||||
return t.l[index]
|
return t.l[index]
|
||||||
@ -120,3 +139,18 @@ func (t *ttsInstances) getSoundMode(ctx *zero.Ctx) (name string) {
|
|||||||
}
|
}
|
||||||
return "拟声鸟阿梓"
|
return "拟声鸟阿梓"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *ttsInstances) setDefaultSoundMode(name string) {
|
||||||
|
var index int
|
||||||
|
t.RLock()
|
||||||
|
for _, s := range t.l {
|
||||||
|
if s == name {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
t.RUnlock()
|
||||||
|
t.Lock()
|
||||||
|
t.l[0], t.l[index] = t.l[index], t.l[0]
|
||||||
|
t.Unlock()
|
||||||
|
}
|
||||||
276
plugin/ymgal/model.go
Normal file
276
plugin/ymgal/model.go
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
package ymgal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/antchfx/htmlquery"
|
||||||
|
_ "github.com/fumiama/sqlite3" // import sql
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"math/rand"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// gdb 得分数据库
|
||||||
|
var gdb *ymgaldb
|
||||||
|
|
||||||
|
// ymgaldb galgame图片数据库
|
||||||
|
type ymgaldb gorm.DB
|
||||||
|
|
||||||
|
var mu sync.RWMutex
|
||||||
|
|
||||||
|
// ymgal gal图片储存结构体
|
||||||
|
type ymgal struct {
|
||||||
|
ID int64 `gorm:"column:id" `
|
||||||
|
Title string `gorm:"column:title" `
|
||||||
|
PictureType string `gorm:"column:picture_type" `
|
||||||
|
PictureDescription string `gorm:"column:picture_description;type:varchar(1024)" `
|
||||||
|
PictureList string `gorm:"column:picture_list;type:varchar(20000)" `
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName ...
|
||||||
|
func (ymgal) TableName() string {
|
||||||
|
return "ymgal"
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize 初始化ymgaldb数据库
|
||||||
|
func initialize(dbpath string) *ymgaldb {
|
||||||
|
var err error
|
||||||
|
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
|
||||||
|
// 生成文件
|
||||||
|
f, err := os.Create(dbpath)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
}
|
||||||
|
gdb, err := gorm.Open("sqlite3", dbpath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
gdb.AutoMigrate(&ymgal{})
|
||||||
|
return (*ymgaldb)(gdb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gdb *ymgaldb) insertOrUpdateYmgalByID(id int64, title, pictureType, pictureDescription, pictureList string) (err error) {
|
||||||
|
db := (*gorm.DB)(gdb)
|
||||||
|
y := ymgal{
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
PictureType: pictureType,
|
||||||
|
PictureDescription: pictureDescription,
|
||||||
|
PictureList: pictureList,
|
||||||
|
}
|
||||||
|
if err = db.Debug().Model(&ymgal{}).First(&y, "id = ? ", id).Error; err != nil {
|
||||||
|
if gorm.IsRecordNotFoundError(err) {
|
||||||
|
err = db.Debug().Model(&ymgal{}).Create(&y).Error // newUser not user
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = db.Debug().Model(&ymgal{}).Where("id = ? ", id).Update(map[string]interface{}{
|
||||||
|
"title": title,
|
||||||
|
"picture_type": pictureType,
|
||||||
|
"picture_description": pictureDescription,
|
||||||
|
"picture_list": pictureList,
|
||||||
|
}).Error
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gdb *ymgaldb) getYmgalByID(id string) (y ymgal) {
|
||||||
|
db := (*gorm.DB)(gdb)
|
||||||
|
db.Debug().Model(&ymgal{}).Where("id = ?", id).Take(&y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gdb *ymgaldb) randomYmgal(pictureType string) (y ymgal) {
|
||||||
|
db := (*gorm.DB)(gdb)
|
||||||
|
var count int
|
||||||
|
s := db.Debug().Model(&ymgal{}).Where("picture_type = ?", pictureType).Count(&count)
|
||||||
|
if count == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Offset(rand.Intn(count)).Take(&y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gdb *ymgaldb) getYmgalByKey(pictureType, key string) (y ymgal) {
|
||||||
|
db := (*gorm.DB)(gdb)
|
||||||
|
var count int
|
||||||
|
s := db.Debug().Model(&ymgal{}).Where("picture_type = ? and (picture_description like ? or title like ?) ", pictureType, "%"+key+"%", "%"+key+"%").Count(&count)
|
||||||
|
if count == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Offset(rand.Intn(count)).Take(&y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
webURL = "https://www.ymgal.com"
|
||||||
|
cgType = "Gal CG"
|
||||||
|
emoticonType = "其他"
|
||||||
|
webPicURL = webURL + "/co/picset/"
|
||||||
|
reNumber = `\d+`
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cgURL = webURL + "/search?type=picset&sort=default&category=" + url.QueryEscape(cgType) + "&page="
|
||||||
|
emoticonURL = webURL + "/search?type=picset&sort=default&category=" + url.QueryEscape(emoticonType) + "&page="
|
||||||
|
commonPageNumberExpr = "//*[@id='pager-box']/div/a[@class='icon item pager-next']/preceding-sibling::a[1]/text()"
|
||||||
|
cgIDList []string
|
||||||
|
emoticonIDList []string
|
||||||
|
)
|
||||||
|
|
||||||
|
func initPageNumber() (maxCgPageNumber, maxEmoticonPageNumber int) {
|
||||||
|
doc, err := htmlquery.LoadURL(cgURL + "1")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
maxCgPageNumber, err = strconv.Atoi(htmlquery.FindOne(doc, commonPageNumberExpr).Data)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
doc, err = htmlquery.LoadURL(emoticonURL + "1")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
maxEmoticonPageNumber, err = strconv.Atoi(htmlquery.FindOne(doc, commonPageNumberExpr).Data)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPicID(pageNumber int, pictureType string) {
|
||||||
|
var picURL string
|
||||||
|
if pictureType == cgType {
|
||||||
|
picURL = cgURL + strconv.Itoa(pageNumber)
|
||||||
|
} else if pictureType == emoticonType {
|
||||||
|
picURL = emoticonURL + strconv.Itoa(pageNumber)
|
||||||
|
}
|
||||||
|
doc, err := htmlquery.LoadURL(picURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
list := htmlquery.Find(doc, "//*[@id='picset-result-list']/ul/div/div[1]/a")
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
re := regexp.MustCompile(reNumber)
|
||||||
|
picID := re.FindString(list[i].Attr[0].Val)
|
||||||
|
if pictureType == cgType {
|
||||||
|
cgIDList = append(cgIDList, picID)
|
||||||
|
} else if pictureType == emoticonType {
|
||||||
|
emoticonIDList = append(emoticonIDList, picID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePic() {
|
||||||
|
maxCgPageNumber, maxEmoticonPageNumber := initPageNumber()
|
||||||
|
for i := 1; i <= maxCgPageNumber; i++ {
|
||||||
|
getPicID(i, cgType)
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
for i := 1; i <= maxEmoticonPageNumber; i++ {
|
||||||
|
getPicID(i, emoticonType)
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
CGLOOP:
|
||||||
|
for i := len(cgIDList) - 1; i >= 0; i-- {
|
||||||
|
mu.RLock()
|
||||||
|
y := gdb.getYmgalByID(cgIDList[i])
|
||||||
|
mu.RUnlock()
|
||||||
|
if y.PictureList == "" {
|
||||||
|
mu.Lock()
|
||||||
|
storeCgPic(cgIDList[i])
|
||||||
|
mu.Unlock()
|
||||||
|
} else {
|
||||||
|
break CGLOOP
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
EMOTICONLOOP:
|
||||||
|
for i := len(emoticonIDList) - 1; i >= 0; i-- {
|
||||||
|
mu.RLock()
|
||||||
|
y := gdb.getYmgalByID(emoticonIDList[i])
|
||||||
|
mu.RUnlock()
|
||||||
|
if y.PictureList == "" {
|
||||||
|
mu.Lock()
|
||||||
|
storeEmoticonPic(emoticonIDList[i])
|
||||||
|
mu.Unlock()
|
||||||
|
} else {
|
||||||
|
break EMOTICONLOOP
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeCgPic(picIDStr string) {
|
||||||
|
picID, err := strconv.ParseInt(picIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
pictureType := cgType
|
||||||
|
doc, err := htmlquery.LoadURL(webPicURL + picIDStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
title := htmlquery.FindOne(doc, "//meta[@name='name']").Attr[1].Val
|
||||||
|
pictureDescription := htmlquery.FindOne(doc, "//meta[@name='description']").Attr[1].Val
|
||||||
|
pictureNumberStr := htmlquery.FindOne(doc, "//div[@class='meta-info']/div[@class='meta-right']/span[2]/text()").Data
|
||||||
|
re := regexp.MustCompile(reNumber)
|
||||||
|
pictureNumber, err := strconv.Atoi(re.FindString(pictureNumberStr))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
pictureList := ""
|
||||||
|
for i := 1; i <= pictureNumber; i++ {
|
||||||
|
picURL := htmlquery.FindOne(doc, fmt.Sprintf("//*[@id='main-picset-warp']/div/div[2]/div/div[@class='swiper-wrapper']/div[%d]", i)).Attr[1].Val
|
||||||
|
if i == 1 {
|
||||||
|
pictureList += picURL
|
||||||
|
} else {
|
||||||
|
pictureList += "," + picURL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = gdb.insertOrUpdateYmgalByID(picID, title, pictureType, pictureDescription, pictureList)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeEmoticonPic(picIDStr string) {
|
||||||
|
picID, err := strconv.ParseInt(picIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
pictureType := emoticonType
|
||||||
|
doc, err := htmlquery.LoadURL(webPicURL + picIDStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
title := htmlquery.FindOne(doc, "//meta[@name='name']").Attr[1].Val
|
||||||
|
pictureDescription := htmlquery.FindOne(doc, "//meta[@name='description']").Attr[1].Val
|
||||||
|
pictureNumberStr := htmlquery.FindOne(doc, "//div[@class='meta-info']/div[@class='meta-right']/span[2]/text()").Data
|
||||||
|
re := regexp.MustCompile(reNumber)
|
||||||
|
pictureNumber, err := strconv.Atoi(re.FindString(pictureNumberStr))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
pictureList := ""
|
||||||
|
for i := 1; i <= pictureNumber; i++ {
|
||||||
|
picURL := htmlquery.FindOne(doc, fmt.Sprintf("//*[@id='main-picset-warp']/div/div[@class='stream-list']/div[%d]/img", i)).Attr[1].Val
|
||||||
|
if i == 1 {
|
||||||
|
pictureList += picURL
|
||||||
|
} else {
|
||||||
|
pictureList += "," + picURL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = gdb.insertOrUpdateYmgalByID(picID, title, pictureType, pictureDescription, pictureList)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("[ymgal]:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
95
plugin/ymgal/ymgal.go
Normal file
95
plugin/ymgal/ymgal.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Package ymgal 月幕galgame
|
||||||
|
package ymgal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/FloatTech/zbputils/control"
|
||||||
|
"github.com/FloatTech/zbputils/control/order"
|
||||||
|
"github.com/FloatTech/zbputils/ctxext"
|
||||||
|
"github.com/FloatTech/zbputils/file"
|
||||||
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
engine := control.Register("ymgal", order.AcquirePrio(), &control.Options{
|
||||||
|
DisableOnDefault: false,
|
||||||
|
Help: "月幕galgame\n- 随机galCG\n- 随机gal表情包\n- galCG[xxx]\n- gal表情包[xxx]\n- 更新gal\n",
|
||||||
|
PublicDataFolder: "Ymgal",
|
||||||
|
})
|
||||||
|
dbfile := engine.DataFolder() + "ymgal.db"
|
||||||
|
go func() {
|
||||||
|
defer order.DoneOnExit()()
|
||||||
|
_, _ = file.GetLazyData(dbfile, false, false)
|
||||||
|
gdb = initialize(dbfile)
|
||||||
|
log.Println("[ymgal]加载月幕gal数据库")
|
||||||
|
}()
|
||||||
|
engine.OnRegex("^随机gal(CG|表情包)$").Limit(ctxext.LimitByUser).SetBlock(true).
|
||||||
|
Handle(func(ctx *zero.Ctx) {
|
||||||
|
ctx.Send("少女祈祷中......")
|
||||||
|
pictureType := ctx.State["regex_matched"].([]string)[1]
|
||||||
|
var y ymgal
|
||||||
|
if pictureType == "表情包" {
|
||||||
|
y = gdb.randomYmgal(emoticonType)
|
||||||
|
} else {
|
||||||
|
y = gdb.randomYmgal(cgType)
|
||||||
|
}
|
||||||
|
sendYmgal(y, ctx)
|
||||||
|
})
|
||||||
|
engine.OnRegex("^gal(CG|表情包)([一-龥ぁ-んァ-ヶA-Za-z0-9]{1,25})$").Limit(ctxext.LimitByUser).SetBlock(true).
|
||||||
|
Handle(func(ctx *zero.Ctx) {
|
||||||
|
ctx.Send("少女祈祷中......")
|
||||||
|
pictureType := ctx.State["regex_matched"].([]string)[1]
|
||||||
|
key := ctx.State["regex_matched"].([]string)[2]
|
||||||
|
var y ymgal
|
||||||
|
if pictureType == "CG" {
|
||||||
|
y = gdb.getYmgalByKey(cgType, key)
|
||||||
|
} else {
|
||||||
|
y = gdb.getYmgalByKey(emoticonType, key)
|
||||||
|
}
|
||||||
|
sendYmgal(y, ctx)
|
||||||
|
})
|
||||||
|
engine.OnFullMatch("更新gal", zero.SuperUserPermission).SetBlock(true).Handle(
|
||||||
|
func(ctx *zero.Ctx) {
|
||||||
|
ctx.Send("少女祈祷中......")
|
||||||
|
updatePic()
|
||||||
|
ctx.Send("ymgal数据库已更新")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendYmgal(y ymgal, ctx *zero.Ctx) {
|
||||||
|
if y.PictureList == "" {
|
||||||
|
ctx.SendChain(message.Text(zero.BotConfig.NickName[0] + "暂时没有这样的图呢"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m := message.Message{
|
||||||
|
message.CustomNode(
|
||||||
|
ctx.Event.Sender.NickName,
|
||||||
|
ctx.Event.UserID,
|
||||||
|
y.Title,
|
||||||
|
)}
|
||||||
|
if y.PictureDescription != "" {
|
||||||
|
m = append(m,
|
||||||
|
message.CustomNode(
|
||||||
|
ctx.Event.Sender.NickName,
|
||||||
|
ctx.Event.UserID,
|
||||||
|
y.PictureDescription,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
for _, v := range strings.Split(y.PictureList, ",") {
|
||||||
|
m = append(m,
|
||||||
|
message.CustomNode(
|
||||||
|
ctx.Event.Sender.NickName,
|
||||||
|
ctx.Event.UserID,
|
||||||
|
[]message.MessageSegment{
|
||||||
|
message.Image(v),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if id := ctx.SendGroupForwardMessage(
|
||||||
|
ctx.Event.GroupID,
|
||||||
|
m).Get("message_id").Int(); id == 0 {
|
||||||
|
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user