|
最近在玩泰拉瑞亚,感觉钓鱼是一件麻烦变乱,鼠标点烂还贼累。搜了半天大多都是点击脚本隔段时间自动收放,这里有个坑,我用python写过的一个自动点击脚本在这里欠好使了,鼠标点击不了。在贴吧上可以看到一个老哥换成了按键实现,我没有去实验,这么感觉用着总是很不爽,服从还低。所以就想从游戏本身出发看看能不能做到自动钓鱼,这篇文章重要是记录一下劳绩。因为都是自己探索的,很多东西零零散散,也希望对入门的mod制作者有一点小小的帮助。
思绪
游戏是使用的C#编写的,单机游戏没有乱七八糟的保护,可以直接反编译。工具重要是使用了vs测试代码,最新版的dnspy调试修改,注意一定要用最新版的,之前老版本总是出现各种奇怪的错误,不得不说这真是一个好东西。
初步打算是找到检测鱼上钩的代码,也就是上钩的时候会有波波的声音那种,然后调用收绳放绳相关的函数。
实践
游戏文件在Steam\steamapps\common\Terraria,打开dnspy搜刮fish方法,然后就是凭借经验+下断点可以定位到FishingCheck这个函数,鱼上钩的时候会调用这个函数。
然后又是一番经验搜刮,搜bait定位到ItemCheck_CheckFishingBobber_PickAndConsumeBait,鼠标点击收杆的时候会调用这里。本来是打算全部走游戏内部,但细致想了想这个函数大概并不是顶层的调用,贸然使用大概会出现大问题。
所以我又想着简化一点吧,颠末FishingCheck的时候直接调用windows的mouse_event,自动收杆后放杆。这个函数声明很简单:
VOID mouse_event( DWORD dwFlags, // motion and click options DWORD dx, // horizontal position or change DWORD dy, // vertical position or change DWORD dwData, // wheel movement ULONG_PTR dwExtraInfo // application-defined information);照着文档直接使用就可以,右键FishingCheck修改方法把下面几句填进去。
[System.Runtime.InteropServices.DllImport("user32")]private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);mouse_event(2, 0, 0, 0, 0);//按下左键mouse_event(4, 0, 0, 0, 0);//松开左键这里我又碰到了之前用python写的脚本一样的问题,就是脚本在游戏里面没有反应,在外面就有效果,我思索了很久,按原理来说这个游戏是没有检测之类的,莫名其妙就失效了,因为之前mc一直用的就是这个脚本。在google上搜有国外老哥说大概是mouse_event的api失效,建议换成sendinput,然后我又鼓捣了一段时间,这段代码我就不贴了,因为也没有效果。
颠末分析,我以为问题出在游戏的输入接收上,之后实验单句按下左键在游戏之中是有效果的,而两句连在一起就不可了,估计游戏输入必须要达到press的效果。于是我在两句中间穿插了Thread.Sleep(100),结果是成功的。
而这填进游戏里又出现了新的问题,因为sleep函数会阻塞当前线程,所以直接加进去依旧是没用,之后继承添加了一个检测线程并且完善了一下。
完善的代码
需要达成的目的:全局设置一个线程执行DoFish函数循环检测用于收杆放杆,FishingCheck检测到有鱼上钩,就调用DoFish。
右键Projectile创建1个方法,创建2个字段,勾选static,达到全局效果。
public static bool fishFlag = false; //钓鱼标志变量,每次检测到上钩置为truepublic static bool createdThread = false;//线程标志,创建完线程后置为truepublic void FishingCheck(){ ...... if (this.bobber && this.Name == "浮标")//制止产生错误,对当前状态进行校验 { if (!Projectile.createdThread) //创建线程 { Thread thread = new Thread(new ThreadStart(this.DoFish)); Projectile.createdThread = true; thread.Start(); } Projectile.fishFalg = true; //设置钓鱼标志位 }}public void DoFish(){ for (;;) { if (Projectile.fishFlag) { //收杆 Projectile.mouse_event(2, 0, 0, 0, 0); Thread.Sleep(100); Projectile.mouse_event(4, 0, 0, 0, 0); Thread.Sleep(100); //下杆 Projectile.mouse_event(2, 0, 0, 0, 0); Thread.Sleep(100); Projectile.mouse_event(4, 0, 0, 0, 0); Thread.Sleep(100); //清除标志位 Projectile.fishFlag = false; } }}效果
将鼠标对准水坑,左键之后就可以挂机了,完美。之后也可以修改其他反人类的地方,比如物品选择栏滚轮方向问题,有的武器要左键一直点而不能够像镐子一样按着不动就行。我就没有时间继承研究了。
末了这是我的成品,想使用的可以直接放在泰拉瑞亚的文件夹下面打开即可,我的版本号是1.4.2.2,一定不要搞错了,另有,因为时间匆忙,我不保证没有什么bug,修改游戏才是我的爱好,建议先备份一下自己的存档。
https://wwr.lanzous.com/imvfdoexgcj
密码:7khj
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|