只是转贴哈,不是原创,不要问我问题,我也不太懂,只是想着好,给大家共享一下。 
最近经朋友介绍开始玩 密传 网络游戏 
升级升级,突然觉得太费键盘,于是自己用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; 

解决方案 »

  1.   

    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 
      

  2.   


    /// <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 


    } } 
    } 以上是全部代码 
    设置功能未完善,可以通过手动修改XML配置文件实现其他类似游戏的外挂 
    附带典型(12级)外挂配置,配置文件随着各人级别不同和技能不同自己做修改。 
    附加我从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> 
    全文完
    另,请有northwind这个示例数据库的朋友,能够发一个给我metababy#163.com,为了防垃圾邮件,请半#换为@,谢谢。这个.net的作为例子提供的数据库文件在你电脑里名为nwind.mdb请帮帮忙。
      

  3.   

    请有northwind这个示例数据库的朋友,能够发一个给我metababy#163.com,为了防垃圾邮件,请半#换为@,谢谢。这个.net的作为例子提供的数据库文件在你电脑里名为nwind.mdb请帮帮忙。
      

  4.   

    请有northwind这个示例数据库的朋友,能够发一个给我metababy#163.com,为了防垃圾邮件,请半#换为@,谢谢。这个.net的作为例子提供的数据库文件在你电脑里名为nwind.mdb请帮帮忙。
    谁给我发来,我会回复另一个截屏的C#源代码,以表谢意