引言
在《魔兽世界》中,自动化脚本可以帮助玩家完成重复性任务,如打怪、拾取物品、售卖物品等。WRobot是一个可用在私服上的自动化工具,支持使用C#编写自定义脚本。
本文将介绍如何使用C#编写一个的WRobot自动化循环刷本脚本。
1. 环境准备
在开始编写脚本之前,确保你已经安装了WRobot,并熟悉其基本操作。WRobot提供了一个插件系统,允许用户通过C#编写自定义逻辑。
对应版本:魔兽世界-暗影国度 9.27 + WRobot 2.8.0 (大概在国服开10.0的时,国外有了个9版本的私服,就写了这脚本用来刷G,后来刷了100多w也没啥用,游戏也弃了,回归国服继续肝正式服)
2. 创建插件
WRobot插件是一个实现了wManager.Plugin.IPlugin
接口的C#类。以下是一个简单的插件模板:
csharp复制代码
using System;
using System.Threading;
using robotManager.Helpful;
using wManager.Wow.Class;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
public class MyPlugin : wManager.Plugin.IPlugin
{
private bool isLaunched;
public void Initialize()
{
isLaunched = true;
Logging.Write("插件已启动");
// 在这里添加你的逻辑
while (isLaunched)
{
// 执行任务
Thread.Sleep(1000);
}
}
public void Dispose()
{
isLaunched = false;
Logging.Write("插件已停止");
}
public void Settings()
{
// 插件设置
}
}
3. 关键功能实现
在Initialize
方法中,你可以编写插件的核心逻辑。以下是一些常见的功能实现:
3.1 移动和导航
使用GoToTask.ToPosition
方法可以让角色移动到指定位置:
csharp复制代码
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-786.707f, 6100.32f, 4.649368f));
3.2 与NPC交互
使用GoToTask.ToPositionAndIntecractWithNpc
方法可以与指定NPC交互:
csharp复制代码
wManager.Wow.Bot.Tasks.GoToTask.ToPositionAndIntecractWithNpc(new Vector3(-786.707f, 6100.32f, 4.649368f), 89257);
以下是完整代码:
using System;
using System.Threading;
using robotManager.Helpful;
using robotManager.Products;
using wManager.Wow.Class;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
using Timer = robotManager.Helpful.Timer;
using System.Collections.Generic;
using System.Configuration;
using System.ComponentModel;
using robotManager;
using System.IO;
using robotManager.FiniteStateMachine;
using wManager.Wow.Bot.States;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using wManager.Wow.Bot.Tasks;
using wManager;
using robotManager.Events;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using wManager.Wow.Enums;
using System.Windows;
using System.Text.RegularExpressions;
// using 主要从wrobot中获取wManager 和 robotManager 命名空间
// 一些注释代码是做一些备用功能或备忘录用的
public class Mainasl: wManager.Plugin.IPlugin
{
private bool isLaunched;
// ContinentId = 1220 1456
//return Usefuls.ContinentId == 1456;
private void test()
{
robotManager.Helpful.Mouse.ClickLeft();
//robotManager.Helpful.Keyboard.PressKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle, System.Windows.Forms.Keys.);
//rbotManager.Helpful.XmlSerializer.
}
public void Initialize()
{
var originStr = "";
var regStr = @"!\w+\s\d+";
var resultStr = string.Empty;
MatchCollection matches = Regex.Matches(originStr, regStr);
foreach(Match match in matches)
{
resultStr = match.Value;
}
if(!string.IsNullOrWhiteSpace(resultStr))
{
// 输入
}
robotManager.Events.ProductEvents.OnProductLoaded += ProductEvents_OnProductLoaded;
robotManager.Products.Products.LoadProducts("");
isLaunched = true;
if(Usefuls.AreaId != 7334 && Usefuls.ContinentId != 1456)
{
Products.ProductStop();
Logging.Write("非阿苏纳地图或者非艾萨拉之眼地图,停止WR");
}
if(Usefuls.AreaId == 7334)
{
if(wManager.Wow.Helpers.Bag.GetContainerNumFreeSlots <= 60) //判断包裹剩余格子
{
wManager.Wow.Bot.Tasks.GoToTask.ToPositionAndIntecractWithNpc(new Vector3(-786.707 f, 6100.32 f, 4.649368 f), 89257);
List < WoWItem > wiList = Bag.GetBagItem();
List < string > itemSell = new List < string > ();
List < string > itemNoSell = new List < string > ();
itemNoSell.Add("炉石");
itemNoSell.Add("飞行管理员的哨子");
List < WoWItemQuality > itemQuality = new List < WoWItemQuality > ();
itemQuality.Add(WoWItemQuality.Artifact);
itemQuality.Add(WoWItemQuality.Common);
itemQuality.Add(WoWItemQuality.Epic);
itemQuality.Add(WoWItemQuality.Heirloom);
itemQuality.Add(WoWItemQuality.Legendary);
itemQuality.Add(WoWItemQuality.Poor);
itemQuality.Add(WoWItemQuality.Rare);
itemQuality.Add(WoWItemQuality.Uncommon);
for(int i = 0; i < wiList.Count; i++)
{
itemSell.Add(wiList[i].Name);
}
Vendor.SellItems(itemSell, itemNoSell, itemQuality);//卖掉所有东西
Thread.Sleep(1000 * 3);
}
Logging.Write("回到艾萨拉之眼副本门口");
Lua.LuaDoString("ResetInstances();");
Logging.Write("重置副本");
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-2.174723 f, 5800.943 f, 2.098947 f));
Logging.Write("进本");
// 门口模拟按键
Move.StrafeLeft(Move.MoveAction.PressKey, 100);
Move.Forward(Move.MoveAction.PressKey, 2000);
}
// sell point to 0 - 3
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-771.9302 f, 6111.996 f, 51.47897 f));
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-606.0879 f, 5991.238 f, 67.36471 f));
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-403.6466 f, 5857.353 f, 101.1433 f));
Thread.Sleep(1000 * 30);
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-201.3126 f, 5747.511 f, 135.9531 f));
//PositionWithoutType = -786.707 ; 6100.32 ; 4.649368 ; "None"
//PositionRelativeWithoutType = -786.707; 6100.32; 4.649368; "None"
if(Usefuls.ContinentId == 1220 && wManager.Wow.Helpers.Bag.GetContainerNumFreeSlots <= 2)
{
wManager.Wow.Bot.Tasks.GoToTask.ToPositionAndIntecractWithNpc(new Vector3(-786.707 f, 6100.32 f, 4.649368 f), 89257);
List < WoWItem > wiList = Bag.GetBagItem();
List < string > itemSell = new List < string > ();
List < string > itemNoSell = new List < string > ();
itemNoSell.Add("炉石");
itemNoSell.Add("飞行管理员的哨子");
List < WoWItemQuality > itemQuality = new List < WoWItemQuality > ();
itemQuality.Add(WoWItemQuality.Artifact);
itemQuality.Add(WoWItemQuality.Common);
itemQuality.Add(WoWItemQuality.Epic);
itemQuality.Add(WoWItemQuality.Heirloom);
itemQuality.Add(WoWItemQuality.Legendary);
itemQuality.Add(WoWItemQuality.Poor);
itemQuality.Add(WoWItemQuality.Rare);
itemQuality.Add(WoWItemQuality.Uncommon);
for(int i = 0; i < wiList.Count; i++)
{
itemSell.Add(wiList[i].Name);
}
Vendor.SellItems(itemSell, itemNoSell, itemQuality);
}
// 回到坐标 -2.174723 ; 5800.943 ; 2.098947
wManager.Wow.Bot.Tasks.GoToTask.ToPosition(new Vector3(-2.174723 f, 5800.943 f, 2.098947 f));
Logging.Write("111" + Lua.LuaDoString < string > ("GetDungeonDifficulty();"));
Lua.LuaDoString("SetDungeonDifficulty(2);");
Move.Forward(Move.MoveAction.PressKey, 3000);
Move.StrafeLeft(Move.MoveAction.PressKey, 100);
Write("初始化...");
// 以下配置是可以在Wrobot工具中配置,也可以在这里写代码直接配置好
wManagerSetting.CurrentSetting.CloseAfterXMin = 60 * 3; // XX分钟后停止WR
wManagerSetting.CurrentSetting.LootMobs = true; //拾取
//被GM传送关闭游戏
wManagerSetting.CurrentSetting.CloseIfPlayerTeleported = false;
//目标周围怪物数量
wManagerSetting.CurrentSetting.MaxUnitsNear = 99;
//可攻击灰名怪
wManagerSetting.CurrentSetting.CanAttackUnitsAlreadyInFight = true;
//可攻击精英怪
wManagerSetting.CurrentSetting.AttackElite = true;
//主动攻击敌对玩家
wManagerSetting.CurrentSetting.AttackBeforeBeingAttacked = false;
//寻怪搜索范围
wManagerSetting.CurrentSetting.SearchRadius = 25;
//避免在玩家附近拾取
wManagerSetting.CurrentSetting.HarvestAvoidPlayersRadius = 0;
//远距离拾取41
wManagerSetting.CurrentSetting.HarvestDuringLongMove = true;
wManagerSetting.CurrentSetting.Repair = false; // 修理
wManagerSetting.CurrentSetting.Selling = false; // 售卖
wManagerSetting.CurrentSetting.HarvestHerbs = false; // 采集
//wManagerSetting.CurrentSetting.acc
wManager.wManagerSetting.CurrentSetting.LootChests = true; //拾取
wManager.wManagerSetting.CurrentSetting.LootChests = true;
Logging.Stop();
robotManager.Helpful.Logging.Stop();
wManagerSetting.CurrentSetting.UseFlyingMount = true;
wManagerSetting.CurrentSetting.FlyAboveGroundHeight = 60;
wManagerGlobalSetting.CurrentSetting.Save();
while(true)
{
isLaunched = true;
GO();
robotManager.Events.LoggingEvents.OnAddLog += delegate(Logging.Log log)
{
if(!log.Text.Contains("[ToTown] Unable to reach the vendor, blacklist it 120 minutes (you can disable this NPC in NPC DB tab 'Tools').")) return;
foreach(var n in NpcDB.ListNpc)
{
n.BlackList(-1);
}
};
robotManager.Events.LoggingEvents.OnAddLog += (robotManager.Helpful.Logging.Log log) =>
{
log.Text = string.Empty;
};
while(Products.IsStarted)
{
try
{
try
{
if(Usefuls.ContinentId == 1220)
{
Move.Forward(Move.MoveAction.PressKey, 300); // 运行过程中会有问题,导致角色不动了,用个纠错移动来继续执行脚本。大概率是wow服务器问题
Logging.Write("纠错移动");
}
}
catch(Exception)
{}
Thread.Sleep(1000 * 60 * 2);
}
catch(Exception)
{}
}
}
}
private void ProductEvents_OnProductLoaded(string str)
{
throw new NotImplementedException();
}
// 其实判断装备好坏是个很难的问题,涉及到很多代码,不想写了,毕竟刷本是用来刷G的
//private void EventsLuaWithArgs_OnEventsLuaWithArgs(string eventName, List<string> args)
//{
// if (eventName == "CHAT_MSG_LOOT") // 监听物品拾取事件
// {
// string lootMessage = args.FirstOrDefault();
// if (lootMessage != null)
// {
// // 解析物品链接
// string itemLink = Lua.LuaDoString<string>(lootMessage);
// if (!string.IsNullOrEmpty(itemLink))
// {
// // 判断拾取的物品是否为装备
// if (ItemsManager.GetItemType(itemLink) == WoWItemType.Armor ||
// ItemsManager.GetItemType(itemLink) == WoWItemType.Weapon)
// {
// // 比较装备,判断是否更好
// if (IsBetterEquipment(itemLink))
// {
// // 装备物品
// EquipItem(itemLink);
// }
// }
// }
// }
// }
//}
public static bool IsWorldFrame()
{
string cmd = "return WorldFrame:IsVisible();";
Logging.Write(Lua.LuaDoString < string > (cmd));
return Lua.LuaDoString < bool > (cmd);
Lua.LuaDoString("WorldFrame:Click()");
Lua.LuaDoString("print('[WorldFrame错误点击]');");
Logging.Write("[WorldFrame错误点击]");
}
//private bool IsBetterEquipment(string itemLink)
//{
// // 获取角色当前装备的同一部位的物品
// WoWItem equippedItem = ObjectManager.Me.Inventory.GetItemBySlot(itemLink.GetInventorySlot());
// // 比较物品的属性来判断是否更好
// if (equippedItem != null)
// {
// WoWItem newItem = new WoWItem(itemLink);
// newItem.GetItemInfo.
// return newItem.GetTotalStatValue() > equippedItem.GetTotalStatValue();
// }
// return true; // 如果当前部位没有装备,直接判断为更好
//}
//private void EquipItem(string itemLink)
//{
// Lua.LuaDoString("UseContainerItem(" + itemLink.GetBagIndex() + ", " + itemLink.GetBagSlot() + ")");
//}
public static void ShaoTaGaoDi(int EntryId)
{
EventsLuaWithArgs.OnEventsLuaWithArgs += EventsLuaWithArgs_OnEventsLuaWithArgs;
if(Lua.LuaDoString < string > ("local status = GetBattlefieldStatus(1)\r\nif status == \"active\" then\r\n return \"0\" ") == "0")
{}
if(ObjectManager.GetObjectWoWUnit().Count(o => o.IsValid && !o.IsDead) < 10)
{}
var target = ObjectManager.GetNearestWoWGameObject(ObjectManager.GetWoWGameObjectByEntry(EntryId));
if(target.IsValid)
{
MovementManager.MoveTo(target.Position);
wManager.Wow.Bot.Tasks.GoToTask.ToPositionAndIntecractWithGameObject(target.Position, EntryId);
}
}
private static void EventsLuaWithArgs_OnEventsLuaWithArgs(LuaEventsId id, List < string > args)
{
throw new NotImplementedException();
}
public void GO()
{
Products.ProductStop();
Products.ProductStart();
//Move.Forward(Move.MoveAction.PressKey, 5000); //
}
public void Write(string text)
{
Logging.Write(text);
Lua.LuaDoString("print('" + text + "');");
}
public void Dispose()
{
isLaunched = false;
}
public void Settings()
{}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库