C# 游戏 * 实现核心代码
发布时间:2021-12-28 14:47:40
最近经朋友介绍开始玩 密传 网络游戏
升级升级,突然觉得太费键盘,于是自己用C#写了一个程序,想代替我的操作,自己去打怪物,自己升级
用这个东西升了好多级了,现在把源码贴出来,和大家共享,欢迎大家批评指正,感激不尽。
程序大概分成两个部分,一个部分是类库,一个是应用程序
大概的思路就是找到游戏进程的主窗口句柄,然后发送游戏按键消息(模拟按键)。
XDF.GamePlugInCommon 类库项目
//API.cs 文件,定义一些常用API函数及常量
using System;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace XDF.GamePlugInCommon
{
/// <summary>
/// API 的摘要说明。
/// </summary>
public sealed class API
{
public static int WM_KEYDOWN = 0x0100;
public static int WM_KEYUP = 0x0101;
public static int WM_SYSKEYDOWN = 0x0104;
public static int WM_SYSKEYUP = 0x0105;
public static int WM_MOUSEMOVE = 0x0200;
public static int WM_LBUTTONDOWN = 0x0201;
public static int WM_LBUTTONUP = 0x0202;
public static int WM_LBUTTONDBLCLK = 0x0203;
public static int WM_RBUTTONDOWN = 0x0204;
public static int WM_RBUTTONUP = 0x0205;
public static int WM_RBUTTONDBLCLK = 0x0206;
public static int WM_USER = 0x0400;
public static int MK_LBUTTON = 0x0001;
public static int MK_RBUTTON = 0x0002;
public static int MK_SHIFT = 0x0004;
public static int MK_CONTROL = 0x0008;
public static int MK_MBUTTON = 0x0010;
public static int MK_XBUTTON1 = 0x0020;
public static int MK_XBUTTON2 = 0x0040;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd,int Msg,int wParam,int lParam);
//此处主要用来让窗口置于最前(SetWindowPos(this.Handle,-1,0,0,0,0,0x4000|0x0001|0x0002);)
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd,
int hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
int uFlags
);
/// <summary>
/// 窗口置前
/// </summary>
/// <param name="hWnd"></param>
public static void SetWindowPos(IntPtr hWnd)
{
SetWindowPos(hWnd,-1,0,0,0,0,0x4000|0x0001|0x0002);
}
/// <summary>
///
/// </summary>
/// <param name="processName"></param>
/// <returns></returns>
public static Process GetGameProcess(string processName)
{
Process pro = null;
Process[] pros = Process.GetProcessesByName(processName);
if(pros.Length > 0)
{
pro = pros[0];
}
return pro;
}
}
}
项目(应用程序)
XDF.TantraPlugIn
//ControlItem.cs
using System;
using System.IO;
using System.Xml.Serialization;
namespace XDF.TantraPlugIn
{
/// <summary>
/// ControlItem 的摘要说明。
/// </summary>
[Serializable]
public sealed class ControlItem
{
private string m_Name = "";
public string Name
{
get
{
return this.m_Name;
}
set
{
this.m_Name = value;
}
}
private char m_KeyChar = 'a';
public char KeyChar
{
get
{
return this.m_KeyChar;
}
set
{
this.m_KeyChar = value;
}
}
private int m_DelayTime = 100;
public int DelayTime
{
get
{
return this.m_DelayTime;
}
set
{
this.m_DelayTime = value;
}
}
public ControlItem()
{
}
}
[Serializable]
public sealed class ControlItemCollection : System.Collections.CollectionBase
{
public ControlItem this[int index]
{
get
{
return (ControlItem)List[index];
}
set
{
List[index] = value;
}
}
public ControlItemCollection()
{
}
public int Add(ControlItem item)
{
return List.Add(item);
}
public void Remove(ControlItem item)
{
List.Remove(item);
}
}
}
//TantraConfig.cs
using System;
using System.IO;
using System.Xml.Serialization;
namespace XDF.TantraPlugIn
{
/// <summary>
/// TantraConfig 的摘要说明。
/// </summary>
[Serializable]
public class TantraConfig
{
private ControlItemCollection m_KillControls = new ControlItemCollection();
public ControlItemCollection KillControls
{
get
{
return this.m_KillControls;
}
set
{
this.m_KillControls = value;
}
}
private ControlItemCollection m_BloodControls = new ControlItemCollection();
public ControlItemCollection BloodControls
{
get
{
return this.m_BloodControls;
}
set
{
this.m_BloodControls = value;
}
}
private int m_BloodRate = 25;
public int BloodRate
{
get
{
return this.m_BloodRate;
}
set
{
this.m_BloodRate = value;
}
}
private string m_ProcessName = "HTLauncher";
public string ProcessName
{
get
{
return this.m_ProcessName;
}
set
{
this.m_ProcessName = value;
}
}
public TantraConfig()
{
}
public bool Save(string file)
{
bool result = false;
try
{
FileStream fs = new FileStream(file,FileMode.Create,FileAccess.Write);
XmlSerializer xsl = new XmlSerializer(this.GetType());
xsl.Serialize(fs,this);
fs.Close();
result = true;
}
catch
{
result = false;
}
return result;
}
public static TantraConfig LoadFromFile(string file)
{
TantraConfig config = null;
try
{
FileStream fs = new FileStream(file,FileMode.Open,FileAccess.Read);
XmlSerializer xsl = new XmlSerializer(typeof(TantraConfig));
config = (TantraConfig)xsl.Deserialize(fs);
fs.Close();
}
catch
{
}
return config;
}
}
}
//Frmmain.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using XDF.GamePlugInCommon;
namespace XDF.TantraPlugIn
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Frmmain : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnSetup;
private System.Windows.Forms.Timer timerMain;
private System.Windows.Forms.Button btnStart;
private System.ComponentModel.IContainer components;
public Frmmain()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
this.Closing +=new CancelEventHandler(Frmmain_Closing);
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Frmmain));
this.btnStart = new System.Windows.Forms.Button();
this.btnSetup = new System.Windows.Forms.Button();
this.timerMain = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(8, 16);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(65, 22);
this.btnStart.TabIndex = 0;
this.btnStart.Text = "开始(&S)";
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// btnSetup
//
this.btnSetup.Location = new System.Drawing.Point(152, 16);
this.btnSetup.Name = "btnSetup";
this.btnSetup.Size = new System.Drawing.Size(65, 22);
this.btnSetup.TabIndex = 1;
this.btnSetup.Text = "设置(&C)";
this.btnSetup.Click += new System.EventHandler(this.btnSetup_Click);
//
// Frmmain
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(226, 55);
this.Controls.Add(this.btnSetup);
this.Controls.Add(this.btnStart);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Frmmain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Tantra PlugIn beta1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Frmmain());
}
private TantraConfig m_TantraConfig = null;
private Thread m_Thread = null;
private bool m_Stop = true;
private IntPtr m_GameMainWindowHandle = IntPtr.Zero;
private void btnSetup_Click(object sender, System.EventArgs e)
{
TantraConfig config = new TantraConfig();
ControlItemCollection items = config.KillControls;
ControlItem item_e = new ControlItem();
item_e.DelayTime = 50;
item_e.KeyChar = 'E';
item_e.Name = "选择最近的攻击目标";
items.Add(item_e);
ControlItem item_r = new ControlItem();
item_r.DelayTime = 6000;
item_r.KeyChar = 'R';
item_r.Name = "攻击选定的目标";
items.Add(item_r);
ControlItem item_f = new ControlItem();
item_f.DelayTime = 500;
item_f.KeyChar = 'F';
item_f.Name = "捡起打完怪物掉下的物品";
items.Add(item_f);
ControlItem item_f2 = new ControlItem();
item_f2.DelayTime = 500;
item_f2.KeyChar = 'F';
item_f2.Name = "捡起打完怪物掉下的金币";
items.Add(item_f2);
ControlItem item_blood = new ControlItem();
item_blood.DelayTime = 1000;
item_blood.KeyChar = '1';
item_blood.Name = "自动增加体能秘技";
config.BloodControls.Add(item_blood);
config.Save("c:\\tantra.xml");
}
private void btnStart_Click(object sender, System.EventArgs e)
{
if(this.m_Stop)
{
this.StartControl();
}
else
{
this.StopControl();
}
this.btnStart.Text = (this.m_Stop)?"开始(&S)":"停止(&S)";
}
private void StartControl()
{
string file = Environment.CurrentDirectory + "\\tantra.xml";
this.m_TantraConfig = TantraConfig.LoadFromFile(file);
if(this.m_TantraConfig == null)
{
MessageBox.Show("配置文件未找到,无法启动!");
return;
}
//HTLauncher
//string proname = "TantraPlugIn";
System.Diagnostics.Process pro = API.GetGameProcess(this.m_TantraConfig.ProcessName);
if(pro == null)
{
MessageBox.Show("游戏进程 "+this.m_TantraConfig.ProcessName+" 未找到,无法启动!");
return;
}
this.m_GameMainWindowHandle = pro.MainWindowHandle;
this.Text = "Game name:" + pro.ProcessName;
this.m_Stop = false;
this.m_Thread = new Thread(
new ThreadStart(TantraControl));
this.m_Thread.Start();
}
private void StopControl()
{
if(this.m_Thread != null)
{
this.m_Stop = true;
this.m_Thread.Abort();
}
}
private void TantraControl()
{
int count = 0;
while(!this.m_Stop)
{
for(int i=0;i<this.m_TantraConfig.KillControls.Count;i++)
{
API.SendMessage(this.m_GameMainWindowHandle,API.WM_KEYDOWN,
Convert.ToInt32(this.m_TantraConfig.KillControls[i].KeyChar),0);
Thread.Sleep(this.m_TantraConfig.KillControls[i].DelayTime);
}
count ++;
if(count >= this.m_TantraConfig.BloodRate)
{
count = 0;
for(int i=0;i<this.m_TantraConfig.BloodControls.Count;i++)
{
API.SendMessage(this.m_GameMainWindowHandle,API.WM_KEYDOWN,
Convert.ToInt32(this.m_TantraConfig.BloodControls[i].KeyChar),0);
Thread.Sleep(this.m_TantraConfig.BloodControls[i].DelayTime);
}
}
}
}
protected override void WndProc(ref Message m)
{
base.WndProc (ref m);
if(m.Msg == API.WM_KEYDOWN)
{
this.Text = m.WParam.ToInt32().ToString();
if(this.Text == "1")
{
MessageBox.Show("blood");
}
}
}
private void Frmmain_Closing(object sender, CancelEventArgs e)
{
try
{
this.StopControl();
}
catch
{
}
}
}
}
附加我从12级开始 * 的配置文件
<?xml version="1.0"?>
<TantraConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<KillControls>
<ControlItem>
<Name>选择最近的攻击目标</Name>
<KeyChar>69</KeyChar>
<DelayTime>50</DelayTime>
</ControlItem>
<ControlItem>
<Name>攻击选定的目标</Name>
<KeyChar>82</KeyChar>
<DelayTime>5000</DelayTime>
</ControlItem>
<ControlItem>
<Name>捡起打完怪物掉下的物品</Name>
<KeyChar>70</KeyChar>
<DelayTime>500</DelayTime>
</ControlItem>
<ControlItem>
<Name>捡起打完怪物掉下的金币</Name>
<KeyChar>70</KeyChar>
<DelayTime>500</DelayTime>
</ControlItem>
</KillControls>
<BloodControls>
<ControlItem>
<Name>自动增加体能秘技</Name>
<KeyChar>49</KeyChar>
<DelayTime>1000</DelayTime>
</ControlItem>
</BloodControls>
<BloodRate>20</BloodRate>
<ProcessName>HTLauncher</ProcessName>
</TantraConfig>
今天发现的模拟键盘的操作,虽然我不能用上,希望有人会到。
猜你喜欢
- 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。代码public cla
- Spring Bean的生命周期?首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;Sp
- 一、String类概述概述java.lang.String 类代表字符串。Java程序中所有的字符串文字(例如"abc"
- 一、日志1、配置日志级别日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、D
- 前言本文简单介绍抽象类,接口以及它们的异同点,另附简单的代码举例。一、抽象类是什么?在 Java 语言中使用 abstract class
- 一、将控件内容拖到其他控件在开发过程中,经常会有这样的要求,拖动一个控件的数据到另外一个控件中。例如将其中一个ListBox中的数据拖到另一
- 前言Java8 由Oracle在2014年发布,是继Java5之后最具革命性的版本。Java8吸收其他语言的精髓带来了函数式编程,lambd
- 目录概述准备工作使用概述springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式
- 在我们做项目的过程中,有可能会遇到跨域请求,所以需要我们自己组装支持跨域请求的JSONP数据,而在4.1版本以后的SpringMVC中,为我
- 求数组中最大的数的值:1、数组的max函数:class Program { &nb
- 首先说明这是我一个不熟悉idea和SSM框架的新手小白遇到的坑,适合用idea搭建SSM框架的小伙伴看一看,老鸟就不用看了。以下为详细步骤(
- 本文实例为大家分享了java实现马踏棋盘的具体代码,供大家参考,具体内容如下马踏棋盘算法介绍8X8棋盘,马走日字,要求每个方格只进入一次,走
- 今天给大家讲讲android的目录实现方法,就像大家看到的小说目录一样,android 提供了ExpandableListView控件可以实
- 如图,左图是效果,右图是原理,右图X轴代表图像一个像素点的灰度,Y轴代表RGB三个颜色对应的伪彩 * 颜色。代码如下:for (int y =
- Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序员能在不涉及到具
- Java float和double精度范围大小要想理解float和double的取值范围和计算精度,必须先了解小数是如何在计算机中存储的:举
- EntityWrapper使用解析1、项目中引入jar包,我这里使用Maven构建<dependency> &nbs
- 1. 绪论当我们编写了自己的C#程序,有程序自定义的文件类型时,通常希望它满足以下需求:双击自定义文件打开自定义程序 自定义文件有着自己的图
- 1. 栈1.1 概念栈:是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。特点:栈中的数据元素遵循先进后出的原则,但要注意进的
- Android 双击返回键退出程序的方法总结下面先说说LZ思路,具体如下: 1. 第一种就是根据用户点击俩次的时间间隔去判断是否退出程序;