Grasscutter的CDK功能好像一直都没修,看到隔壁倒狗好像都在用同一家的CDK系统,就把前端页面给他爬了下来自己写了一个玩玩=w=
他们用的看上去也是模板引擎渲染,于是我采用了我比较熟悉的Django框架。Django版本是3.2
项目已在Github开源:Zhaokugua/Grasscutter-CDKeySystem: Grasscutter-CDKeySystem by Django3.2 (github.com)
现在这个项目已经比较完善了,除了CDK的生成和兑换外,还加入了许多新功能。
(当然实际上好多是看着他们用的页面里面有然后才加上的)
现在支持的功能:
通过opencommand连接Grasscutter.
通过YSGM(MUIP)连接官方服务端.
CDKey兑换 - 玩家可以兑换已经生成的CDKey.
CDKey生成 - 管理者可以生成CDKey的内容,支持批量生成。
开启地图和深渊 - 玩家可以一键开启地图和深渊(仅限Grasscutter).
设置世界等级 - 玩家可以任意设置世界等级(仅限Grasscutter).
远程执行 - 可以远程执行命令.
每日签到 - 签到系统(默认是Grasscutter的命令,每天1000摩拉).
自定义背景图 - 可以自定义页面的背景图链接(比如随机图).
幸运抽奖 - 抽奖系统.
更多 - Comming soon...
展示一下CDK生成的页面(我不知道他们的CDK是怎么生成的,这个是我自己造的页面)
项目日记
下面就以日记的形式记录一下我写这个项目的前因后果....(可能有点流水账)
10月10日 接到需求
我在tg群收到了个老哥的私聊,他向我展示了别的Grasscutter的网页CDK系统,并且 给了我两个地址,问我能不能扒下来然后整一个出来。
恰巧当时有点兴趣,也有点时间,就稍微扒下来想着做着玩一下w
本来我想的是使用MeaMail邮件插件,以邮件的方式来发送兑换码的奖励,但是当时MeaMail插件还有很多bug,几乎无法使用,官方的mail命令也不是很完善。
于是我转变思路,尝试以直接执行命令的方式来发送兑换码的奖励。这种方法的弊端就是玩家必须在线。
我就想,正常玩家兑换CDK应该都是在线的吧,而且这种方法实现起来比较简单,就这样做了。
当天晚上时间比较晚了,而且那天学校熄灯,笔记本也快没电了。我把需要的页面扒下来然后粗略地写了两个模型(一个用来存CDK的信息,一个用来存兑换记录),然后就睡觉了。
10月11日 初次尝试
突然有个奇怪的需求,说要直接发满命角色,如果用邮件的话是不可能的,只能发角色和对应的命星,然后手动点命座。
但是执行命令就不同了,可以直接给满命角色,这更加坚定了我用执行命令的方式发放CDK奖励的决心。
兑换CDK时要考虑到很多失败的因素,比如用户不存在、兑换码无效、兑换码已过期、兑换码已被使用、没填写uid、玩家离线、执行命令时出错等等,这一天写了不少错误判断的逻辑。
不过,第一个CDK也在今天兑换成功!
10月12日 第一版诞生!
完善了一下功能,第一版在这一天诞生了。
他只有纯粹的CDK生成和兑换功能,而且还有很多问题。
CDK每次只能生成一个,不能批量生成
可以设置一个CDK使用多次,但是没有对UID做限制(也就是说当时同一个UID可以多次使用同一个可以多次使用的CDK)
默认的过期时间定死在2023-10-1,需要按格式手动填写,格式不正确会报错
生成cdk的页面没有校验,也就是说只要知道地址谁都可以进去生成cdk
因为有批量生成CDK的需求,因此这一天也加上了批量生成的功能。
因为怕路径公开之后不安全,因此也是这几天加上了auth认证,只有输入密码之后才能进去生成cdk
然后顺便加上了设置世界等级和解锁地图深渊
基本完成之后,我创建了Github仓库,把他第一次提交了上去。
我当时没有在任何地方发过我这个项目的链接,也没想着宣传,不知道哪天tg里的群友突然翻到了然后发群里了2333
11月15日 新增MUIP(YSGM)的支持
游戏的官方客户端泄漏想必大家都有所耳闻。既然是不一样的服务端,这个CDK系统自然也就不能直接换一个服务端使用。
这天悦酱在QQ上问我能不能把我的CDK系统改一改,因为官方服务端有写任务会卡住,需要执行一些命令跳过这些任务。
而官方服务端是不能直接在游戏内执行命令的,于是就想到了我这个东西。
于是当天花时间稍微研究了一下如何连接MUIP,是看的YSGM(一个桌面端带有GUI界面的命令执行工具)的源代码亿点点摸索的。
首先在配置文件中新增了YSGM的有关配置(我当时以为她真的就叫YSGM,后来我才知道是MUIP,嘛,怕有BUG就不改了)
要想连接MUPI的话需要一个MUIP_HOST地址和一个MUIP_TARGET_REGION信息。
然后我去研究YSGM是如何执行命令的。
使用Fiddler抓包分析之后,发现每次执行命令都是发送一个get请求。
有以下几个参数:
cmd:要执行的命令代号,比如1101是获取服务器在线人数
region:就是设置的MUIP_TARGET_REGION
ticket:YSGM@当前时间的时间戳
还有个sign看上去是一串加密的东西,不知道是什么。
于是我又找到了YSGM的源代码,查看他是如何构建这些请求的参数的。
发现,这个sign是一个sha256的加密
要获取这个sign,首先要把之前的参数写成url编码的那种格式(key1=value1&key2=value2这种)
我用这样一个语句来快速生成它
params就是之前的参数字典。
&'.join([f'{x}={params[x]}' for x in params])
然后,要把这个和1d8z98SAKF98bdf878skswa8kdjfy1m9dses这个字符串拼接一下
用utf8编码之后最后计算sha256的值。
这就是sign的来历。
研究透彻之后,兼容性就好做了,初始化的时候判断一下到底是连接的官方服务端还是Grasscutter,获取在线人数和执行命令都做了函数封装,稍微改一下函数就大致没问题了。
哦,还有一个问题。执行命令的时候MUIP指定UID时是作为单独的参数,而Grasscutter是直接在命令里加上@UID来指定的,于是我稍微修改了一下执行命令的函数,加了个uid参数,这样就可以解决很多问题。
使用的过程中第一次出现了之前留的 「同一个UID可以多次使用同一个可以多次使用的CDK」的问题,也顺便修复了。
现在可以在生成CDK的时候设置同一个UID可以使用这一个CDK的次数(默认为1)
顺便在每日签到和抽奖的地方加了段注释样例,方便直接使用。
(但是当时每日签到没有记录,所以说当时可以反复刷签到领取奖励)
11月16日 BUG修复
昨天加了好多功能,果然有bug
一个是MUIP执行命令失败时,里面的信息是None,直接不给错误信息,导致我根据错误信息判断错误返回的时候直接报错(
然后还是同一个UID可以使用这一个CDK的次数的问题,昨天修的是把能兑换多次改成了能兑换2次,还没根除,,
于是在比较的地方把>改成了>=就好了,,
然后直接把每日签到的地方的注释去掉了,现在签到功能正式可用了(也是执行命令的原理,默认是Grasscutter给100摩拉的命令)
当然也做了签到的记录,用来限制每天只能签到一次。
签到时出现异常之后渲染的页面模板也写错了,修复了一下qwq
bug真多
11月26日 远程命令执行
在另一个朋友的建议下新增了远程执行命令的功能给玩家开放
由于我执行命令已经封装好了函数,所以开放这个功能并不是难事。
不过,由于我没有测试,遗留除了好多bug(
11月28日 修bug
我那朋友测试的时候发现无论怎么输都显示“请输入UID”的报错信息,我一看
html里面表单里面的输入框的name没改过来,和后端的名字对不上(
改了之后又提示执行了空命令,这才发现命令的输入框name也没改,,
直接复制的html果然有问题,,
11月30日 修bug
我那朋友又问命令为啥有长度限制
我一想可能是get请求有url长度的限制吧
一看不是,是输入框的限制,,
还是那天复制html的时候出的问题,,因为是拿cdk的输入框改的
cdk的长度是有限制的,提醒用户位数多了可能是输错了
然后复制过来的时候没把长度限制给删了,,,
12月8日 修bug&优化
issue里有人提到连续点击兑换按钮有概率刷出多倍奖励,了解过数据库的锁的机制应该知道这个问题。
嘛,就简单修一下吧,前端页面加一个点击按钮就让按钮变灰点不了了,这样页面响应之前再怎么点也没用了嘿嘿
onclick="{this.disabled=true;document.getElementById('form1').submit();}"
测试的时候发现签到的时候不填uid也会提示签到成功,修复了一下
然后优化了一下功能
首先创建cdk的时候可以选择日期了,这样比手动输入方便一点
同时这样也能手动输入,可以二者兼得
然后也加入了动态设置cdk的过期时间,毕竟2023-10-1可能随着时间的推移也不那么合适了
最后就是饱受诟病的由于每次加载页面都获取一遍在线人数导致的页面加载缓慢
之前悦酱还以为加载慢是cdn不行=w= 现在加入了个缓存机制,可以设置缓存时间
这样短时间内操作就会体验到丝滑的感觉了嘿嘿
12月14日 修bug&自定义背景图
评论区反馈了兑换CDK时输入uid的时候可以加入字母、空格等不是uid数字的元素来多次领取的问题
前端的对应位置加入了oninput验证,同时执行MUIP相关命令的时候也加入了uid的数字验证,如果uid不是纯数字则会立即返回执行失败,uid不是纯数字。
另外配置文件中加入了自定义背景图链接的选项,现在可以更加方便的自定义背景图了,也可以换成一些随机图,可以参考随机图API接口分享 - 赵苦瓜のBlog (jixiaob.cn)这篇博客。
2023年1月23日 新增时延命令
issue里出现了提示兑换码兑换失败但是实际上物品已经到账导致玩家重复刷的问题
增加了时延命令sleep尝试减缓命令执行速度尝试解决
本文地址:https://blog.jixiaob.cn/?post=92
版权声明:若无注明,本文皆为“赵苦瓜のBlog~”原创,转载请保留文章出处。
- 使用Python写一个QQ机器人以图搜动漫图的插件接入SauceNAO ascii2d trace.moe animetrace
- 【点滴记录】Django框架的入门 - 第六篇(模型迁移原理、模型关系、静态文件、文件上传、邮件发送)
- 【点滴记录】C语言的基础入门
- 小米手环/手机复制加密门卡教程
- 【点滴记录】选学课程-计算机网络技术基础
- 【点滴记录】Python进阶——类和实例、面向对象
- 【点滴记录】Django框架的入门 - 第五篇(会话技术、CSRF)
- 【点滴记录】MySQL的基本语法&&Python接入(pymysql)
- 【点滴记录】E0144 "const char *" 类型的值不能用于初始化 "char *" 类型的实体
- 【点滴记录】Python程序设计——基础补充
sql-3.2.7z
srv-bins.7z
welink-pkg.7z
后来有他们集成打包好的
https://www.123pan.com/s/u5LA-PlyGh
兑换的时候只要在uid前加上0
即可无限兑换(uid有填入次数限制可以忽略)
比如我的uid是1
1可以兑换一次,01可以兑换一次,001可以兑换一次,0001可以兑换一次,一直类推
value=value.replace(/[^\d]|^[0&2-9]+/g,'')
另外附上我的解决方法,我只单纯的禁止了oninput不可输入字母,当然这样已经可以隔绝很多人了
另外苦瓜兄的图片api可以用用这个https://api.mtyqx.cn/tapi/random.php
找不到文件?是否是在manage.py路径下运行的命令行呢?