|
|
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\",\"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\":\"\"}]")
|
|
|
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":""}
|
|
|
*/ |