欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 游戏外挂实现核心代码

程序员文章站 2023-11-22 11:01:16
最近经朋友介绍开始玩 密传 网络游戏 升级升级,突然觉得太费键盘,于是自己用c#写了一个程序,想代替我的操作,自己去打怪物,自己升级 用这个东西升了好多级了,现在把源码贴出...
最近经朋友介绍开始玩 密传 网络游戏
升级升级,突然觉得太费键盘,于是自己用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>

今天发现的模拟键盘的操作,虽然我不能用上,希望有人会到。