最近在玩泰拉瑞亚,感觉钓鱼是一件麻烦事情,鼠标点烂还贼累。搜了半天大多都是点击脚本隔段时间主动收放,这里有个坑,我用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
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |