You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
8.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package codeforcesbot
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"net/url"
"strconv"
"strings"
)
type User struct {
User_id int64
Nickname string
Card string
Sex string
Age int32
Area string
Level string
Role string
Title string
}
type Event struct {
Time int64
Self_id int64
Post_type string
Message_type string
Sub_type string
Message_id int32
Group_id int64
User_id int64
Message string
Raw_message string
Sender User
}
const GoCqhttpServer = "http://localhost:5700"
func sendPrivateMessage(id int64, s string) (response *http.Response, err error) {
fmt.Println(s)
response, err = http.PostForm(GoCqhttpServer+ "/send_private_msg", url.Values{
"user_id": {fmt.Sprint(id)},
"message": {s},
})
fmt.Printf("Error: %+v\nResponse: %+v\n", err, response)
return response, err
}
func sendGroupMessage(id int64, s string) (response *http.Response, err error) {
fmt.Println(s)
response, err = http.PostForm(GoCqhttpServer+ "/send_group_msg", url.Values{
"group_id": {fmt.Sprint(id)},
"message": {s},
})
fmt.Printf("Error: %+v\nResponse: %+v\n", err, response)
return response, err
}
func ReplyMessage(e *Event, s string) (response *http.Response, err error) {
fmt.Println(s)
if e.Message_type == "group" {
response, err = sendGroupMessage(e.Group_id, s)
} else if e.Message_type == "private" {
response, err = sendPrivateMessage(e.User_id, s)
}
return response, err
}
func StringToImg(s string) string {
return fmt.Sprintf("[CQ:image,file=http://jiuli.xiaoapi.cn/i/text_img.php?text=%s]", url.PathEscape(s))
}
func CQatToQQId(s string) int64 {
if len(s) <= 11 {
return -1
}
ret, err := strconv.ParseInt(s[10:len(s)-1], 10, 64)
if err == nil {
return ret
}
return -1
}
type MessageHandler func(*Event, []string)
type Router map[string]MessageHandler
var MainRouter = make(Router)
func AddRoute(s string, m MessageHandler) {
MainRouter[s] = m
}
func InitializeRouter() {
AddRoute(".contest", func(e *Event, argv []string) {
var s string
if len(argv) >= 2 && argv[1] == "-f" {
_, s = formatContests(getContests(), isUpcoming)
}else{
_, s = formatContests(getContestsCached(), isUpcoming)
}
ReplyMessage(e, StringToImg("即将到来的比赛:\n"+s))
})
AddRoute(".queue", func(e *Event, argv []string) {
x, y := countStuckSubmissions(getRecentSubmissions())
ReplyMessage(e, StringToImg("评测机状态: " + fmt.Sprintf("%d submissions in queue, %d submissions testing\n", x, y)))
})
AddRoute(".help", func(e *Event, argv []string) {
ReplyMessage(e, StringToImg("当前支持的指令:\n.contest 查询即将到来的CF比赛;\n.kitty 获取随机猫图。\n.help 查询关于我的帮助信息;\n.latest *handle* 查询用户名为*handle*的CF帐号最近一次提交记录\n.queue 查询CF当前评测队列状态\n.read *text* AI朗读*text*\n .addCFHandle *handle* 将用户名为*handle*的CF帐号绑定到你的QQ号\n.my 查询你的QQ号下绑定的CF帐号\n.heat 查询你的CF热力值。需要提前将你的所有CF帐号绑定。"))
})
AddRoute(".test", func(e *Event, argv []string) {
if len(argv) >= 2 {
switch argv[1] {
case "hpy":
ReplyMessage(e, "[CQ:json,data={\"app\":\"com.tencent.miniapp\"&#44;\"desc\":\"\"&#44;\"view\":\"notification\"&#44;\"ver\":\"0.0.0.1\"&#44;\"prompt\":\"&#91;应用&#93;\"&#44;\"appID\":\"\"&#44;\"sourceName\":\"\"&#44;\"actionData\":\"\"&#44;\"actionData_A\":\"\"&#44;\"sourceUrl\":\"\"&#44;\"meta\":{\"notification\":{\"appInfo\":{\"appName\":\"全国疫情数据统计\"&#44;\"appType\":4&#44;\"appid\":1109659848&#44;\"iconUrl\":\"http://gchat.qpic.cn/gchatpic_new/719328335/-2010394141-6383A777BEB79B70B31CE250142D740F/0\"}&#44;\"data\":&#91;{\"title\":\"确诊\"&#44;\"value\":\"80932\"}&#44;{\"title\":\"今日确诊\"&#44;\"value\":\"28\"}&#44;{\"title\":\"疑似\"&#44;\"value\":\"72\"}&#44;{\"title\":\"今日疑似\"&#44;\"value\":\"5\"}&#44;{\"title\":\"治愈\"&#44;\"value\":\"60197\"}&#44;{\"title\":\"今日治愈\"&#44;\"value\":\"1513\"}&#44;{\"title\":\"死亡\"&#44;\"value\":\"3140\"}&#44;{\"title\":\"今**亡\"&#44;\"value\":\"17\"}&#93;&#44;\"title\":\"中国加油,武汉加油\"&#44;\"button\":&#91;{\"name\":\"病毒:SARS-CoV-2,其导致疾病命名COVID-19\"&#44;\"action\":\"\"}&#44;{\"name\":\"传染源:新冠肺炎的患者。无症状感染者也可能成为传染源。\"&#44;\"action\":\"\"}&#93;&#44;\"emphasis_keyword\":\"\"}}&#44;\"text\":\"\"&#44;\"sourceAd\":\"\"}]")
case "1":
ReplyMessage(e, "[CQ:tts,text=今天是星期一,该起床上班上学喽。]")
case "vvvvvv":
ReplyMessage(e, "[CQ:record,file=file:///home/hpy/Music/Rick_Astley_-_Never_Gonna_Give_You_Up.mp3]")
default:
for key, val := range argv {
if key > 0 {
ReplyMessage(e, val)
}
}
}
}
})
AddRoute(".kitty", func(e *Event, argv []string) {
str := getKitty()
if str != "" {
ReplyMessage(e, fmt.Sprintf("[CQ:image,file=%s]", str))
}
})
AddRoute(".latest", func(e *Event, argv []string) {
if len(argv) < 2 {
ReplyMessage(e, "ERROR PARAMETER MISSING")
return
}
submissions := getUserSubmissions(argv[1], 1)
if len(submissions) > 0 {
str := getSubmissionJson(submissions[0])
fmt.Println(str)
ReplyMessage(e, str)
} else {
ReplyMessage(e, "ERROR: SUBMISSION NOT FOUND")
}
})
AddRoute(".read", func(e *Event, argv []string) {
if len(argv) < 2 {
ReplyMessage(e, "[CQ:record,file=file:///home/hpy/Music/Rick_Astley_-_Never_Gonna_Give_You_Up.mp3]")
return
}
ReplyMessage(e, fmt.Sprintf("[CQ:tts,text=%s]", argv[1]))
})
AddRoute(".jyr", func(e *Event, argv []string) {
if rand.Intn(10) <= 2 {
ReplyMessage(e, "[CQ:image,file=file:///home/hpy/Pictures/jyr.jpg]")
}
})
AddRoute(".hpy", func(e *Event, argv []string) {
if rand.Intn(77) <= 7 {
ReplyMessage(e, "[CQ:image,file=file:///home/hpy/Pictures/hpy.jpg]")
}
})
/*AddRoute(".sql", func(e *Event, argv []string) {
if len(argv) < 3 {
ReplyMessage(e, "ERROR PARAMETER NOT ENOUGH")
return
}
qqid, err := strconv.ParseInt(argv[1], 10, 64)
CheckErr(err)
ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] %s", qqid, SqlInsertCFid(e.User_id, argv[1])))
})*/
AddRoute(".addCFHandle", func(e *Event, argv []string) {
if len(argv) < 2 {
ReplyMessage(e, "ERROR PARAMETER NOT ENOUGH")
return
}
ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] %s", e.User_id, SqlInsertCFid(e.User_id, argv[1])))
})
AddRoute(".my", func(e *Event, argv []string) {
str := SqlQueryHandles(e.User_id)
rep := fmt.Sprintf("[CQ:at,qq=%v] 您绑定的Codeforces帐号", e.User_id)
for _, handle := range str {
rep = rep + "\n" + handle
}
ReplyMessage(e, rep)
})
AddRoute(".heat", func(e *Event, argv []string) {
if len(argv) <= 1 {
ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] 您的Codeforces热力值高达 %v", e.User_id, getHeatValue(SqlQueryHandles(e.User_id))))
} else {
qqid := CQatToQQId(argv[1])
if qqid < 0 {
ReplyMessage(e, "ERROR PARAMETER INVALID")
} else {
ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] 的Codeforces热力值高达 %v", qqid, getHeatValue(SqlQueryHandles(qqid))))
}
}
})
AddRoute("[CQ:at,qq=2902971635]", func(e *Event, argv []string) {
argvLength := len(argv)
s := ""
for i := 1; i < argvLength; i ++ {
s += argv[i] + " "
}
sendPrivateMessage(2854201761, s);
})
}
func MainHandler(w http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodPost {
var e Event
s, err := ioutil.ReadAll(req.Body)
if err == nil {
json.Unmarshal(s, &e)
if e.Message != "" {
argv := strings.Fields(e.Message)
for _, val := range argv {
fmt.Print("["+val+"]")
}
fmt.Println()
if val, ok := MainRouter[argv[0]]; ok {
go val(&e, argv)
} else if e.User_id == 2854201761 {
sendGroupMessage(779440319, e.Message)
}
}
}
}
}
/*
{"app":"com.tencent.miniapp","desc":"","view":"notification","ver":"0.0.0.1","prompt":"[应用]","appID":"","sourceName":"","actionData":"","actionData_A":"","sourceUrl":"","meta":{"notification":{"appInfo":{"appName":"全国疫情数据统计","appType":4,"appid":1109659848,"iconUrl":"http:\/\/gchat.qpic.cn\/gchatpic_new\/719328335\/-2010394141-6383A777BEB79B70B31CE250142D740F\/0"},"data":[{"title":"确诊","value":"80932"},{"title":"今日确诊","value":"28"},{"title":"疑似","value":"72"},{"title":"今日疑似","value":"5"},{"title":"治愈","value":"60197"},{"title":"今日治愈","value":"1513"},{"title":"死亡","value":"3140"},{"title":"今**亡","value":"17"}],"title":"中国加油, 武汉加油","button":[{"name":"病毒 : SARS-CoV-2, 其导致疾病命名 COVID-19","action":""},{"name":"传染源 : 新冠肺炎的患者。无症状感染者也可能成为传染源。","action":""}[,"emphasis_keyword":""}},"text":"","sourceAd":""}
*/