美服疯狂坦克辅助瞄准外挂C#版开发(四)程序使用说明和完成源代码及其下载
来源:互联网 发布:淘宝卖家质量问题范围 编辑:程序博客网 时间:2024/05/14 02:59
到现在为止,我们已经将疯狂坦克外挂所需相关的功能点及解决方案完成。
先说说常规的使用方法:
1、编译发布程序后,先运行程序(默认不可见),然后进入美服疯狂坦克。
2、在游戏中按(Pause)键启动各种辅助线。
3、在游戏中按(Scroll Lock)键切换你当前所用的坦克。
4、在游戏中鼠标放到你坦克所在的位置(小地图上圆点中心),按下(PrScrn SysRq)键确定曲线起点。
5、通过(Insert)和(Delete)键调节角度标识与游戏中坦克实际角度线端点重合。
6、通过(Home)和(End)键调节风力标识与游戏中风力线边缘重合。
7、通过(PgUp)和(PgDn)建调节力度,直到小地图上的抛物线穿过你要命中的目标。
8、按一下键盘上的左边的(Control)键,将会按照预先设定的抛物线发射炮弹命中目标。
PS:所有调节按键,同时按下(Shift)键为粗调,放开(Shift)键后为精调。
由于游戏中不同的坦克的风力系统、推力系数、重力系数、满力时间不一样,所以请使用各种坦克经过多次测试得出系数。
具体测试各种坦克的相关系数方法:
1、选中某一款坦克,然后多次测试,根据炮弹的落点与小地图上曲线落点的误差调节该坦克的风力系统、推力系数、重力系数,直到精确。
2、多次测试根据推力标识与实际力度边缘线的误差调节该坦克的满力时间这一系数。
3、将各种测量后的系数写入配置文件中保存。
截止到目前为止,一个疯狂坦克辅助瞄准外挂的基本功能就完成了。但是这样的外挂其实是存在一些功能缺陷的,如下:
1、不能够直接读取游戏内存中的数据,来获取当前的角度、风力和力度等值,而是通过绘制和调节辅助线来获取。
2、不能够直接识别出当前正在使用的坦克的名称和加载相关参数,需要通过手动切换坦克。
3、未将各种坦克的四个系数都预设好,因为我真的没有这个时间和耐性。
以上的功能缺陷,最大的一个技术障碍就是不能够在游戏运行过程中从内存中获取相关的数据。
这也是为什么美服没有瞄准外挂而且当初国服的外挂在美服用不了的原因把。
个人推测是因为在某一次游戏更新过程中,将原来直接写到动态内存中的这些相关数据改为加密后再写入内存。
所以不管用FPE或者金山游侠等内存查询工具,均不能够在内存中发现任何的相关数据明文。
如果有朋友对其加密方式有研究,或者能够提供获取这些数据的解决方法,请与我联系指正。
如果能够获取到这些数据,这个外挂功能就算比较完整了,使用起来也没这么麻烦,如国服当年的坦克猎手4.1。
下面是程序的所有源码,稍后我会放到CSDN下载中心一份完整的源码,不知道是否能通过审核。
本程序仅限用于学习研究,请不要破坏游戏平衡,谢谢。
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Xml;
- using System.Windows.Forms;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
- using GlobalMouseKeyBoardHook;
- namespace BBTankAssistant
- {
- public partial class Form1:Form
- {
- #region ====变量定义====
- //全局鼠标钩子
- private KeyboardHook KH;
- //全局键盘钩子
- private MouseHook MH;
- //炮弹初始位置(坦克所在位置坐标)
- private Point PrimaryCoordinate;
- //炮弹运行位置(某一时刻炮弹所在位置坐标)
- private Point MovementCoordinate;
- //炮弹运行轨迹(炮弹可能出现的所有位置坐标)
- private IList<Point> MoveKeyCoordinates;
- //风力大小
- private float WindPower;
- //推力大小
- private float PushPower;
- //推力角度
- private double PushAngle;
- //当前坦克编号
- private int TankNumberNowPlay;
- //当前坦克
- private Tank TankNowPlay;
- //计时器
- private Stopwatch SW;
- #endregion
- #region ====外部方法====
- //外部方法:获取DC
- [DllImport("User32.dll")]
- public extern static System.IntPtr GetDC(System.IntPtr hWnd);
- //外部方法:释放DC
- [DllImport("User32.dll")]
- static extern int ReleaseDC(IntPtr hWnd,IntPtr hDC);
- //外部方法:刷新区域
- [DllImport("user32.dll",CharSet = CharSet.Auto)]
- public static extern bool InvalidateRect(IntPtr hWnd,IntPtr lpRect,bool bErase);
- #endregion
- public Form1()
- {
- InitializeComponent();
- }
- private void Form1_Shown(object sender,EventArgs e)
- {
- this.Hide();
- }
- private void Form1_Load(object sender,EventArgs e)
- {
- #region ====变量初始化====
- KH = new KeyboardHook();
- MH = new MouseHook();
- KH.Start();
- MH.Start();
- KH.KeyDown += new KeyEventHandler(KeyBoardHook_KeyDown);
- KH.KeyUp += new KeyEventHandler(KeyBoardHook_KeyUp);
- KH.KeyPress += new KeyPressEventHandler(KeyBoardHook_KeyPress);
- MH.MouseDown += new MouseEventHandler(MouseHook_MouseDown);
- MH.MouseUp += new MouseEventHandler(MouseHook_MouseUp);
- PrimaryCoordinate = new Point(487,56);
- WindPower = 0;
- PushPower = 0;
- PushAngle = 30;
- TankNumberNowPlay = 0;
- TankNowPlay = Common.GetAllTanks()[0];
- SW = new Stopwatch();
- #endregion
- }
- private void timer1_Tick(object sender,EventArgs e)
- {
- DrawAssistantLine();
- }
- private void timer2_Tick(object sender,EventArgs e)
- {
- if(SW.ElapsedMilliseconds < TankNowPlay.MaxPowerTime * PushPower / 322)
- {
- KeyboardSimulator.KeyDown(Keys.Space);
- }
- else
- {
- KeyboardSimulator.KeyUp(Keys.Space);
- SW.Reset();
- timer2.Enabled = false;
- }
- }
- public void KeyBoardHook_KeyDown(object sender,KeyEventArgs e)
- {
- #region ====按键绑定====
- switch(e.KeyCode)
- {
- case Keys.Pause:
- timer1.Enabled = true;
- break;
- case Keys.Scroll:
- ChangeNextTank();
- break;
- case Keys.Insert:
- PushAngle += e.Shift ? 10 : 1;
- break;
- case Keys.Delete:
- PushAngle -= e.Shift ? 10 : 1;
- break;
- case Keys.Home:
- if(WindPower < 36)
- {
- WindPower += e.Shift ? 10 : 1;
- }
- break;
- case Keys.End:
- if(WindPower > -36)
- {
- WindPower -= e.Shift ? 10 : 1;
- }
- break;
- case Keys.PageUp:
- if(PushPower < 322)
- {
- PushPower += e.Shift ? 10 : 1;
- }
- break;
- case Keys.PageDown:
- if(PushPower > 0)
- {
- PushPower -= e.Shift ? 10 : 1;
- }
- break;
- case Keys.PrintScreen:
- PrimaryCoordinate = MouseSimulator.Position;
- break;
- case Keys.LControlKey:
- SW.Start();
- timer2.Enabled = true;
- break;
- default:
- break;
- }
- #endregion
- }
- public void KeyBoardHook_KeyUp(object sender,KeyEventArgs e)
- {
- }
- public void KeyBoardHook_KeyPress(object sender,KeyPressEventArgs e)
- {
- }
- public void MouseHook_MouseDown(object sender,MouseEventArgs e)
- {
- }
- public void MouseHook_MouseUp(object sender,MouseEventArgs e)
- {
- }
- //切换下一坦克
- public void ChangeNextTank()
- {
- IList<Tank> ILT = new List<Tank>();
- ILT = Common.GetAllTanks();
- if((ILT !=null)&&(ILT.Count > 0))
- {
- if(TankNumberNowPlay < ILT.Count -1 )
- {
- TankNumberNowPlay += 1;
- }
- else
- {
- TankNumberNowPlay = 0;
- }
- TankNowPlay = ILT[TankNumberNowPlay];
- }
- else
- {
- TankNowPlay = null;
- }
- }
- //绘图
- public void DrawAssistantLine()
- {
- #region ====绘图准备====
- Pen Pe = new Pen(Color.Red,1);
- SolidBrush SB = new SolidBrush(Color.Green);
- IntPtr ScreenHandle = GetDC(IntPtr.Zero);
- Graphics G = Graphics.FromHdc(ScreenHandle);
- #endregion
- #region ====绘制坦克名称====
- G.DrawString(TankNowPlay.Name,new Font("宋体",12),SB,PrimaryCoordinate);
- #endregion
- #region ====绘制参考线====
- //绘制角度线条
- G.DrawLine(Pe,74,427,74 + float.Parse((37 * Math.Cos(PushAngle * Math.PI / 180)).ToString()),427 - float.Parse((37 * Math.Sin(PushAngle * Math.PI / 180)).ToString()));
- //绘制角度端点
- G.FillEllipse(SB,72 + float.Parse((37 * Math.Cos(PushAngle * Math.PI / 180)).ToString()),425 - float.Parse((37 * Math.Sin(PushAngle * Math.PI / 180)).ToString()),4,4);
- //绘制风力线
- G.DrawLine(Pe,74 + WindPower,469,74 + WindPower,477);
- //绘制推力线
- G.DrawLine(Pe,224 + PushPower,438,224 + PushPower,454);
- #endregion
- #region ====绘制辅助线====
- ////绘制角度边框
- //G.DrawEllipse(Pe,35,388,74,74);
- ////绘制推力边框
- //G.DrawRectangle(Pe,224,438,322,16);
- ////绘制风力边框
- //G.DrawRectangle(Pe,38,469,72,8);
- ////绘制地图边框
- //G.DrawRectangle(Pe,482,5,153,95);
- #endregion
- #region ====计算运行轨迹====
- MovementCoordinate = PrimaryCoordinate;
- MoveKeyCoordinates = new List<Point>();
- double MoveTime = 0;
- while(((MovementCoordinate.X > Parabola.GraphRangeXmin) && (MovementCoordinate.X < Parabola.GraphRangeXmax)) && ((MovementCoordinate.Y > Parabola.GraphRangeYmin) && (MovementCoordinate.Y < Parabola.GraphRangeYmax)))
- {
- MovementCoordinate = new Point();
- MovementCoordinate.X = int.Parse(Math.Round(PrimaryCoordinate.X + TankNowPlay.PushCoefficient * PushPower * Math.Cos(PushAngle * Math.PI / 180) * MoveTime + (TankNowPlay.WindCoefficient * WindPower * MoveTime * MoveTime) / 2,0).ToString());
- MovementCoordinate.Y = int.Parse(Math.Round(PrimaryCoordinate.Y - TankNowPlay.PushCoefficient * PushPower * Math.Sin(PushAngle * Math.PI / 180) * MoveTime + (TankNowPlay.GravityCoefficient * MoveTime * MoveTime) / 2,0).ToString());
- MoveKeyCoordinates.Add(MovementCoordinate);
- MoveTime += Parabola.GraphFreq;
- }
- #endregion
- #region ====绘制弹道曲线====
- Point[] Ps = new Point[MoveKeyCoordinates.Count];
- MoveKeyCoordinates.CopyTo(Ps,0);
- //绘制弹道曲线
- G.DrawLines(Pe,Ps);
- #endregion
- #region ====释放所有资源====
- //InvalidateRect(System.IntPtr.Zero,System.IntPtr.Zero,false);
- Pe.Dispose();
- SB.Dispose();
- G.Dispose();
- ReleaseDC(IntPtr.Zero,ScreenHandle);
- #endregion
- }
- }
- #region ====通用函数====
- public static class Common
- {
- //读取配置文件内容
- public static string GetConfigValue(string XmlPath)
- {
- XmlDocument XD = new XmlDocument();
- XD.Load(AppDomain.CurrentDomain.BaseDirectory + "../..../../BBTankAssistant.config");
- XmlNode XN = XD.SelectSingleNode(XmlPath);
- if(XN != null)
- {
- return XN.InnerText;
- }
- else
- {
- return null;
- }
- }
- //更新配置文件内容
- public static void SetConfigValue(string XmlPath,string ConfigValue)
- {
- XmlDocument XD = new XmlDocument();
- XD.Load(AppDomain.CurrentDomain.BaseDirectory + "../../BBTankAssistant.config");
- XmlNode XN = XD.SelectSingleNode(XmlPath);
- if(XN != null)
- {
- XN.InnerText = ConfigValue;
- XD.Save(AppDomain.CurrentDomain.BaseDirectory + "../../BBTankAssistant.config");
- }
- }
- //获取所有坦克对象
- public static IList<Tank> GetAllTanks()
- {
- XmlDocument XD = new XmlDocument();
- XD.Load(AppDomain.CurrentDomain.BaseDirectory + "../../BBTankAssistant.config");
- XmlNodeList XNL = XD.SelectNodes("//Tank");
- if(XNL.Count > 0 )
- {
- IList<Tank> ILT = new List<Tank>();
- foreach(XmlNode XN in XNL)
- {
- Tank T = new Tank(XN.FirstChild.InnerText);
- ILT.Add(T);
- }
- return ILT;
- }
- else
- {
- return null;
- }
- }
- }
- #endregion
- #region ====弹道模型====
- public static class Parabola
- {
- //Xmin
- public static int GraphRangeXmin
- {
- get
- {
- return int.Parse(Common.GetConfigValue("//ParabolaGraphRange").Split(',')[0]);
- }
- }
- //Xmax
- public static int GraphRangeXmax
- {
- get
- {
- return int.Parse(Common.GetConfigValue("//ParabolaGraphRange").Split(',')[1]);
- }
- }
- //Ymin
- public static int GraphRangeYmin
- {
- get
- {
- return int.Parse(Common.GetConfigValue("//ParabolaGraphRange").Split(',')[2]);
- }
- }
- //Ymax
- public static int GraphRangeYmax
- {
- get
- {
- return int.Parse(Common.GetConfigValue("//ParabolaGraphRange").Split(',')[3]);
- }
- }
- //Freq
- public static double GraphFreq
- {
- get
- {
- return double.Parse(Common.GetConfigValue("//ParabolaGraphFreq"));
- }
- set
- {
- Common.SetConfigValue("//ParabolaGraphFreq",value.ToString());
- }
- }
- }
- #endregion
- #region ====坦克模型====
- public class Tank
- {
- #region ====字段====
- //名称
- private string m_Name;
- #endregion
- #region ====属性====
- //名称
- public string Name
- {
- get
- {
- return m_Name;
- }
- set
- {
- m_Name = value;
- }
- }
- //风力系数
- public double WindCoefficient
- {
- get
- {
- return double.Parse(Common.GetConfigValue("//Tank[@Name='"+m_Name+"']/WindCoefficient"));
- }
- set
- {
- Common.SetConfigValue("//Tank[@Name='" + m_Name + "']/WindCoefficient",value.ToString());
- }
- }
- //推力系数
- public double PushCoefficient
- {
- get
- {
- return double.Parse(Common.GetConfigValue("//Tank[@Name='" + m_Name + "']/PushCoefficient"));
- }
- set
- {
- Common.SetConfigValue("//Tank[@Name='" + m_Name + "']/PushCoefficient",value.ToString());
- }
- }
- //重力系数
- public double GravityCoefficient
- {
- get
- {
- return double.Parse(Common.GetConfigValue("//Tank[@Name='" + m_Name + "']/GravityCoefficient"));
- }
- set
- {
- Common.SetConfigValue("//Tank[@Name='" + m_Name + "']/GravityCoefficient",value.ToString());
- }
- }
- //满力时间
- public double MaxPowerTime
- {
- get
- {
- return double.Parse(Common.GetConfigValue("//Tank[@Name='" + m_Name + "']/MaxPowerTime"));
- }
- set
- {
- Common.SetConfigValue("//Tank[@Name='" + m_Name + "']/MaxPowerTime",value.ToString());
- }
- }
- #endregion
- #region ====构造函数====
- public Tank(string Name)
- {
- m_Name = Name;
- }
- #endregion
- }
- #endregion
- }
- 美服疯狂坦克辅助瞄准外挂C#版开发(四)程序使用说明和完成源代码及其下载
- 美服疯狂坦克辅助瞄准外挂C#版开发(二)全局鼠标键盘HOOK
- 美服疯狂坦克辅助瞄准外挂C#版开发(一)物理模型及弹道曲线方程
- 美服疯狂坦克辅助瞄准外挂C#版开发(三)在全屏游戏屏幕上绘制弹道曲线
- [原创]QQ农场外挂辅助程序-小萝莉偷菜机器人,提供下载。
- C#中国象棋网络版源代码(四)-辅助类
- dnf辅助外挂C++源代码
- 开发的辅助外挂
- 完成联网版的坦克程序心得
- 图片版坦克大战源代码之坦克类(二)
- 传智播客:六小时搞定坦克大战视频讲解及源代码(C#版)
- C# 一个简单分词程序的思路和代码(六) 源代码 ,测试程序,词库下载地址
- C# QQ连连看外挂(内存版)源代码
- C# QQ连连看外挂(内存版)源代码
- 扫雷外挂程序开发
- 90坦克小游戏基本核心开发完成
- C#开发-----坦克大战游戏
- C#版坦克大战
- 普诺德的SEO优化技巧
- 日常常识
- javascript【eval()函数】
- C#读写XML文件 (转)
- 网站制作
- 美服疯狂坦克辅助瞄准外挂C#版开发(四)程序使用说明和完成源代码及其下载
- 《中华通络操》教学视频下载!
- 关于RadioButtonList,CheckBoxList,DropDownList的Selected Bind
- C#高精度计时
- PS非主流闪字教程
- PLC上位软件开发
- 上班人员必读:“五险一金”详解!
- XML与C#完全版
- 比尔盖茨的审查