利用shell解析json内容,实现检测mc版本更新(OPQ框架)


前言


因为酷Q跑路,我又去找了新的框架,框架原生只支持lua,因此这几天我都在重写酷Q用过的插件。 之前酷Q那里我写了一个检测mc版本更新的插件,作用就是检测到更新就会推送至指定群内

4月的截图


使用命令触发的那些插件很快就写完了,当我准备写检测mc更新的时候,惊喜的发现,这绝对不可能(何同学一般感想) lua原生并不支持多线程,那也就意味着定时执行也不存在。那么有没有不调用lua第三方库还能实现定时任务的方法呢 很巧的是,我发现OPQ框架有Web发送接口,这就意味着可以使用http请求来发送内容到群聊;更巧的是,linux内置的crontab再搭配shell不就能实现需求吗 二话不说立马开始行动

开始行动


检测更新的接口来自:http://launchermeta.mojang.com/mc/game/version_manifest.json (只有java版本) 直接访问就可得到非常长的一串json文本,但是我们用到的地方很少 \

接口部分内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"latest": {
"release": "1.16.2", //最新正式版版本
"snapshot": "1.16.2" //最新快照版本,更新正式版时此处显示正式版版本号
},
"versions": [
{
"id": "1.16.2",
"type": "release", //正式版
"url": "https://launchermeta.mojang.com/v1/packages/363cf3fef00f554a93ff3c54b189465efeb3d0bb/1.16.2.json",
"time": "2020-08-14T14:41:03+00:00",
"releaseTime": "2020-08-11T10:13:46+00:00"
},
{
"id": "1.16.2-rc2",
"type": "snapshot", //快照版
"url": "https://launchermeta.mojang.com/v1/packages/8ac7ac3c3625eed1e4c3cfb42f36b817186ae96a/1.16.2-rc2.json",
"time": "2020-08-14T14:42:04+00:00",
"releaseTime": "2020-08-10T11:43:36+00:00"
},
...
]
}

shell原生并不支持解析json,我们需要安装jq以实现处理json jq是开源的(https://github.com/stedolan/jq),我使用阿里源可以直接安装,或者你也可以在github寻找发行版安装。

1
2
3
4
5
echo '{"foo": 0}'  jq .
#打印结果
{
"foo": 0
}

当然我们的需求是解析其中的信息,现在我们拿上面的接口来一个例子

1
2
3
4
5
6
7
#首先我们先获取接口的数据
str=$(curl -s http://launchermeta.mojang.com/mc/game/version_manifest.json)
#然后获取最新的正式版
echo $strjq -r '.latest.release'

#打印的结果
1.16.2

为防止重复推送,我们需要保存版本号以便下次对比

1
2
3
4
5
6
7
8
9
10
11
12
datPash = "/OPQBot/Config/mc-checker.dat"
#检测文件是否存在 不存在将自动创建
if [ ! -f "$datPath" ] ; then
   touch "$datPath"
#创建文件,初始化空版本号
    release="0.0"
    snapshot="0.0"
else
#读取文件内容,利用英文逗号分割字符串,左边正式版,右边快照版
    release=$(echo $(cat $datPath)  cut -d \, -f 1)
    snapshot=$(echo $(cat $datPath)  cut -d \, -f 2)
fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#获取最新版本的版本号、类型和发布时间
Id=$(echo $strjq -r '.versions[0].id')
Type=$(echo $strjq -r '.versions[0].type')
Time=$(echo $strjq -r '.versions[0].time')
if [ $Type = "release" ] ; then
#判断类型
    if [[ $release != $Id ]] ; then
        echo "正式版"
    fi
elif [ $Type = "snapshot" ] ; then
    if [[ $snapshot != $Id ]] ; then
        echo "快照"
    fi
fi
#最后一次更新是1.16.2正式版,因此打印结果为正式版

写入文件我们可以利用cat命令实现(代码内需要顶格写),例如

1
2
3
cat > $datPath << END
1.1.4,5.1.4
END

这是最终的成品


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/bin/bash
#--------------------------------------------
# 检测minecraft(java)新版本 并向群内推送
# author:BluesDawn576
# date: 2020.08.11
#--------------------------------------------
#检测mc新版本 sh脚本(需要OPQBot框架配合)
#本脚本需要安装jq(不是jQuery) 否则将无法运行
#本脚本支持单Q多群 多Q多群自行添加逻辑
#改一下脚本路径就可以每小时执行了 具体其他时长写法请了解Cron表达式
#添加定时计划 每小时执行 命令例:(echo "0 * * * * /home/pi/桌面/IOTQQ_3.0.0_linux_arm64/Time/time.sh" ;crontab -l) crontab
#或使用宝塔面板添加计划任务 任务类型为Shell脚本

#填写你的机器人QQ号
SelfQQ=""
#发送群号 支持多群 多群 一个空格分开
RevGroupArr=("114514" "1919810")
#配置文件储存位置(建议在机器人目录,例如:/root/公共/OPQBot/Config/mc-checker.dat)
datPath=""
#端口号 你运行机器人的那个端口
Post="8888"

#检测文件是否存在 不存在将自动创建
if [ ! -f "$datPath" ] ; then
touch "$datPath"
release="0.0"
snapshot="0.0"
else
release=$(echo $(cat $datPath) cut -d \, -f 1)
snapshot=$(echo $(cat $datPath) cut -d \, -f 2)
fi

str=$(curl -s http://launchermeta.mojang.com/mc/game/version_manifest.json)
#解析json 需要安装jq
Id=$(echo $strjq -r '.versions[0].id')
Type=$(echo $strjq -r '.versions[0].type')
Time=$(echo $strjq -r '.versions[0].time')
#判断类型
if [ $Type = "release" ] ; then
if [[ $release != $Id ]] ; then
_type="正式版"
isNew=true
cat > $datPath << END_TEXT
$Id,$snapshot
END_TEXT
fi
elif [ $Type = "snapshot" ] ; then
if [[ $snapshot != $Id ]] ; then
_type="快照"
isNew=true
cat > $datPath << END_TEXT
$release,$Id
END_TEXT
fi
fi
if [[ $isNew == true ]] ; then
for i in "${!RevGroupArr[@]}"; do
RevGroup=${RevGroupArr[$i]}
#调用WebApi发信接口
curl "http://127.0.0.1:$Post/v1/LuaApiCaller?qq=$SelfQQ&funcname=SendMsg&timeout=10" -H 'Content-Type: application/json' --data-binary '{"toUser":'${RevGroup}',"sendToType":2,"sendMsgType":"TextMsg","content":"发现'$_type'更新: '$Id'\n时间: '$Time'","groupid":0,"atUser":0}'
done
fi

添加定时计划: 每小时执行

命令例

1
(echo "0 * * * * /home/pi/桌面/IOTQQ\_3.0.0\_linux\_arm64/Time/time.sh" ;crontab -l) crontab

或者你可以使用宝塔面板的计划任务执行,类型选择shell脚本

Crontab表达式结构


*        *        *        *        *
分  时   日   月   周

第1列表示分钟 1~59
第2列表示小时 1~23(0表示0点)
第3列表示日期 1~31
第4列表示月份 1~12
第5列标识号星期 0~6(0表示星期天)  

这里列出一些常用的crontab表达式

*/10 * * * * 每十分钟执行一次
*/30 * * * *   每半小时执行一次
0 * * * * 每小时执行一次
0 0 */1 * * 每天0点执行一次
0 0 1 */1 * 每月1日0点执行一次

https://www.matools.com/crontab

框架:https://github.com/OPQBOT/OPQ
个人插件仓库:https://github.com/BluesDawn576/OPQBot-Plugins