MainWindow

private void button_0_Click(object sender, RoutedEventArgs e)
{
Configuration.Instance.SaveAll();
this.button_0.IsEnabled = false;
this.comboBox_1.IsEnabled = false;
this.comboBox_0.IsEnabled = false;
this.checkBox_0.IsEnabled = false;
this.listBox_0.IsEnabled = false;
try
{
this.bool_0 = false;
if (BotManager.IsRunning)
{
BotManager.Stop();
}
else
{
BotManager.Start();
}
}
finally
{
this.bool_0 = true;
}
this.stopwatch_0.Restart();
}

BotManager

public static bool Start()
{
object obj = BotManager.object_0;
bool result;
lock (obj)
{
if (BotManager.IsRunning)
{
BotManager.ilog_0.ErrorFormat("[Start] The BotThread is already running. Please use BotManager.Stop first.", Array.Empty<object>());
result = false;
}
else if (!TritonHs.Initialized)
{
BotManager.ilog_0.ErrorFormat("[Start] TritonHs is not initialized yet.", Array.Empty<object>());
result = false;
}
else if (BotManager.CurrentBot == null)
{
BotManager.ilog_0.ErrorFormat("[Start] There is no bot to run. Please assign a bot first.", Array.Empty<object>());
result = false;
}
else
{
BotManager.ilog_0.InfoFormat("[Start] Now creating the BotThread.", Array.Empty<object>());
BotManager.bool_3 = false;
BotManager.BotThread = new Thread(new ThreadStart(BotManager.smethod_4));
BotManager.BotThread.Start();
result = true;
}
}
return result;
}
private static void smethod_4()
{
object obj = BotManager.object_0;
lock (obj)
{
Thread.Sleep();
}
TritonHs.Memory.DisableCache();
TritonHs.Memory.ClearCache();
TritonHs.Memory.Executor.FrameDropWaitTime = 15000u;
TritonHs.Memory.Executor.ExecuteWaitTime = ;
try
{
TritonHs.smethod_2(true);
}
catch
{
}
try
{
BotManager.smethod_0(BotManager.CurrentBot);
goto IL_FA;
}
catch
{
BotManager.autoResetEvent_0.Set();
goto IL_FA;
}
IL_87:
try
{
if (BotManager.MsBeforeNextTick != )
{
Thread.Sleep(BotManager.MsBeforeNextTick);
BotManager.MsBeforeNextTick = ;
}
BotManager.smethod_1(BotManager.CurrentBot);
BotManager.bool_3 = false;
if (BotManager.MsBetweenTicks != )
{
Thread.Sleep(BotManager.MsBetweenTicks);
}
}
catch (InjectionDesyncException)
{
BotManager.ilog_0.DebugFormat("[BotThreadFunction] An InjectionDesyncException was detected.", Array.Empty<object>());
BotManager.bool_3 = true;
TritonHs.InvokeEvent(BotManager.eventHandler_1, new object[]
{
null,
new ClientFrozenEventArgs()
});
}
catch
{
}
IL_FA:
if (!BotManager.autoResetEvent_0.WaitOne())
{
goto IL_87;
}
try
{
BotManager.smethod_2(BotManager.CurrentBot);
}
catch
{
}
BotManager.BotThread = null;
if (BotManager.bool_3)
{
TritonHs.InvokeEvent(BotManager.eventHandler_1, new object[]
{
null,
new ClientFrozenEventArgs()
});
return;
}
try
{
TritonHs.smethod_2(true);
}
catch
{
}
}

重点在ibot_1.Start();,这里启动后,进入DefaultBot的流程

internal static void smethod_0(IBot ibot_1)
{
try
{
object obj = BotManager.object_0;
lock (obj)
{
if (BotManager.bool_0)
{
return;
}
BotManager.bool_0 = true;
}
BotManager.smethod_3(ibot_1, BotManager.botEvent_0);
try
{
using (TritonHs.AcquireFrame())
{
using (TritonHs.Memory.TemporaryCacheState(false))
{
TritonHs.Memory.ClearCache();
ibot_1.Start();
}
}
}
catch (Exception exception)
{
BotManager.ilog_0.Error("[Start] Exception during execution:", exception);
throw;
}
BotManager.smethod_3(ibot_1, BotManager.botEvent_1);
}
finally
{
object obj = BotManager.object_0;
lock (obj)
{
BotManager.bool_0 = false;
}
}
}

MainWindow

private void method_11(IBot ibot_0)
{
base.Dispatcher.BeginInvoke(new Action(this.method_35), Array.Empty<object>());
if (this.bool_0)
{
base.Dispatcher.BeginInvoke(new Action(this.method_36), Array.Empty<object>());
}
}

DefaultBot

namespace Triton.Bot.Logic.Bots.DefaultBot
{
// Token: 0x02000256 RID: 598
public class DefaultBot : IRunnable, IAuthored, IBase, IBot, IConfigurable

public void Start()
{
this.coroutine_0 = new Coroutine(new Func<Task>(this.method_53));
this.bool_2 = false;
GameEventManager.Instance.Start();
PluginManager.Start();
RoutineManager.Start();
ProcessHookManager.Enable();
GameEventManager.NewGame += this.method_18;
GameEventManager.GameOver += this.method_19;
GameEventManager.MulliganConfirm += this.method_16;
InactivePlayerKicker inactivePlayerKicker = InactivePlayerKicker.Get();
if (inactivePlayerKicker != null)
{
inactivePlayerKicker.SetShouldCheckForInactivity(false);
}
}

DefaultBot.Tick方法中,以下三行代码

GameEventManager.Instance.Tick();
PluginManager.Tick();
RoutineManager.Tick();

public void Tick()
{
if (this.coroutine_0.IsFinished)
{
DefaultBot.ilog_0.DebugFormat("The bot coroutine has finished in a state of {0}", this.coroutine_0.Status);
BotManager.Stop();
return;
}
if (!TritonHs.IsClientInUsableState(true))
{
BotManager.MsBeforeNextTick += ;
this.method_17();
return;
}
if (!this.bool_2 && ChatMgr.Get().FriendListFrame != null)
{
DefaultBot.ilog_0.ErrorFormat("[Tick] FriendListFrame != null.", Array.Empty<object>());
Client.LeftClickAtDialog(BnetBar.Get().m_friendButton.m_OnlineCountText.Transform.Position);
BotManager.MsBeforeNextTick += ;
this.method_17();
return;
}
bool flag;
if (TritonHs.HandleDialog(new ShouldAcceptFriendlyChallengeDelegate(this.ShouldAcceptFriendlyChallenge), out flag))
{
if (flag)
{
BotManager.Stop();
}
BotManager.MsBeforeNextTick += ;
this.method_17();
return;
}
GameEventManager.Instance.Tick();
PluginManager.Tick();
RoutineManager.Tick();
try
{
this.coroutine_0.Resume();
}
catch
{
this.method_17();
throw;
}
}

RoutineManager.Tick

RoutineManager.CurrentRoutine就是silver fish

public static void Tick()
{
RoutineManager.Tick(RoutineManager.CurrentRoutine);
}

调试的时候,routine.Tick();会自动反编译,加载出一个DefaultRoutine.dll【这里的调试必须是F11】

public static void Tick(IRoutine routine)
{
RoutineManager.smethod_0(routine, RoutineManager.routineEvent_2);
try
{
routine.Tick();
}
catch (Exception exception)
{
RoutineManager.ilog_0.Error("Exception during routine Tick.", exception);
}
RoutineManager.smethod_0(routine, RoutineManager.routineEvent_3);
}

namespace Buddy.Coroutines
{
// Token: 0x0200009E RID: 158
public sealed class Coroutine : IDisposable

public void Resume()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (this.IsFinished)
{
throw new InvalidOperationException("This coroutine has finished execution and cannot be resumed.");
}
if (Coroutine.coroutine_0 == this)
{
throw new InvalidOperationException("A coroutine cannot resume itself");
}
this.method_0(false);
}
    private void method_0(bool bool_2)
{
SynchronizationContext synchronizationContext = SynchronizationContext.Current;
Coroutine coroutine = Coroutine.coroutine_0;
try
{
Coroutine.coroutine_0 = this;
SynchronizationContext.SetSynchronizationContext(null);
Action action = this.action_0;
this.action_0 = null;
action();
if (!bool_2)
{
this.Ticks++;
}
this.method_2(bool_2);
}
finally
{
Coroutine.coroutine_0 = coroutine;
SynchronizationContext.SetSynchronizationContext(synchronizationContext);
}
}

[CompilerGenerated]
private sealed class Class67

public void method_0()
{
Task<object> task;
try
{
task = this.func_0();
}
catch (Exception innerException)
{
throw this.coroutine_0.method_1(new CoroutineUnhandledException("Exception was thrown by root coroutine task producer", innerException));
}
if (task == null)
{
throw this.coroutine_0.method_1(new CoroutineBehaviorException("The root coroutine task producer returned null"));
}
this.coroutine_0.task_0 = task;
}

上面的default routine加载后,直接搜索getHoldList

定位到出错的地方

ERROR Logger (null) - [Tick] Exception during execution:
Buddy.Coroutines.CoroutineUnhandledException: Exception was thrown by coroutine ---> System.NullReferenceException: Object reference not set to an instance of an object.
at HREngine.Bots.Mulligan.getHoldList(MulliganData mulliganData, Behavior behave) in

Routines\DefaultRoutine\Silverfish\ai\Mulligan.cs:line 307
at HREngine.Bots.DefaultRoutine.d__41.MoveNext() in

public async Task<bool> Logic(string type, object context)
{
bool flag = type == "mulligan";
bool result;
if (flag)
{
await this.MulliganLogic(context as MulliganData);
result = true;
}
else if (type == "emote")
{
await this.EmoteLogic(context as EmoteData);
result = true;
}
else if (type == "our_turn")
{
await this.OurTurnLogic();
result = true;
}
else if (type == "opponent_turn")
{
await this.OpponentTurnLogic();
result = true;
}
else if (type == "our_turn_combat")
{
await this.OurTurnCombatLogic();
result = true;
}
else if (type == "opponent_turn_combat")
{
await this.OpponentTurnCombatLogic();
result = true;
}
else if (type == "arena_draft")
{
await this.ArenaDraftLogic(context as ArenaDraftData);
result = true;
}
else if (type == "handle_quests")
{
await this.HandleQuestsLogic(context as QuestData);
result = true;
}
else
{
result = false;
}
return result;
}

在DefaultRoutine加载后,可以直接添加监视

CardDB.Instance.cardIdstringToEnum("ULD_194") ,ULD_194 ,HREngine.Bots.CardDB.cardIDEnum

- CardDB.Instance.getCardDataFromID(HREngine.Bots.CardDB.cardIDEnum.ULD_194) ,{HREngine.Bots.CardDB.Card} ,HREngine.Bots.CardDB.Card

cost是0x3E8=1000,name是unknown

HearthBuddy BotManager的更多相关文章

  1. HearthBuddy Plugin编写遇到的问题

    错误1 赋值问题 貌似编译器版本有点低,无法识别C#的高级语法糖 属性的初始值,必须是public bool IsEnabled { get{return true;} } 不能写成public bo ...

  2. HearthBuddy的plugin加载

    // Hearthbuddy.Windows.MainWindow // Token: 0x060001FF RID: 511 RVA: 0x0008951C File Offset: 0x00087 ...

  3. HearthBuddy修改系统时间

    将以下代码保存在.bat文件,然后用管理员权限运行 pushd "%~dp0" #下面修改时间,根据操作系统的语言不同,会有不同的格式,比如2019-10-26date 10/26 ...

  4. HearthBuddy的class276以及class247

    使用de4dot-cex反编译原版的hearthbuddy得到的 链接: https://pan.baidu.com/s/1hT79LpIjbyvODsjnkSe_5A 提取码: iemx class ...

  5. HearthBuddy Ai调试实战1-->出牌的时候,少召唤了图腾就结束回合

    期望通过ai的调试,来搞明白出牌的逻辑. 55是投火无面者63是恐狼前锋34是风怒36是自动漩涡打击装置13是空灵召唤者, "LocStringZhCn": "<b ...

  6. HearthBuddy 日志模块

    // Triton.Common.LogUtilities.CustomLogger // Token: 0x04000BD8 RID: 3032 private Level level_0 = Le ...

  7. HearthBuddy炉石兄弟 如何调试ai

    Sepefeets's update to botmaker's Silverfish AI This AI is a Custom Class for Hearthranger and Hearth ...

  8. HearthBuddy CSharpCodeProvider 如何编译cs文件

    源码 源码1 namespace Hearthbuddy.Windows{    // Token: 0x02000041 RID: 65    public class MainWindow : W ...

  9. HearthBuddy DONOTDELETE.bin

    namespace Hearthbuddy{    // Token: 0x02000022 RID: 34    public class App : System.Windows.Applicat ...

随机推荐

  1. elment-ui表单验证

    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-widt ...

  2. vue 导航守卫

    1.全局守卫(在所有路由展示前触发)//在main.js中 router.beforeEach((to, from, next) => {      to 即将要进入的到的路由,值为路由    ...

  3. C8051F环境搭建

    https://www.silabs.com/ USB调试器 U-EC6: 支持JTAG模式.C2模式 JTAG接口定义: 适用型号C8051F00x C8051F01x C8051F02x C805 ...

  4. PHP中RabbitMQ之amqp扩展实现(四)

    目前我在PHP里接触实现RabbitMQ的方式有两种,一种是通过amqp扩展,一种是使用php-amqplib,本章讲诉RabbitMQ的安装及amqp扩展及amqp扩展如何实现RabbitMQ 环境 ...

  5. 【Distributed】限流技巧

    一.概述 1.1 高并发服务限流特技 1.2 为什么要互联网项目要限流 1.3 高并发限流解决方案 二.限流算法 2.1 计数器 2.2 滑动窗口计数 2.3 令牌桶算法 使用RateLimiter实 ...

  6. django框架—终端命令

    创建一个虚拟环境:在虚拟环境中创建项目目录 cd到项目根目录 创建项目:django-admin startproject "项目名称" 创建app:python manage.p ...

  7. Windows Phone惨遭微软放弃

    微软在电脑操作系统上的用户保有量一直处于遥遥领先的地位,特别是最新的Windows 10系统,一经推出,市场表现就比较好,但相比起来,微软的手机操作系统Windows Phone就被贴上“差等生”的标 ...

  8. Maven 基础概念

    Project:任何你想构建的事务Maven都可以认为它们是工程,这些工程被定义为工程对象模型(project Object Model POM) 一个工程可以依赖其他的工程,一个工程也可以由多个子工 ...

  9. CAFFE(0):Ubuntu 下安装anaconda2和anaconda3

    这个步骤可以看做是安装caffe可以进行或者不必要的步骤,不过笔者建议安装anaconda2和anaconda3,里面会包含很多的模块,省去caffe学习过程中出现模块不存在的各种错误. 第一步.进入 ...

  10. Git---初入开源代码管理库的学习过程003

    Git常用命令总结 上接<Git 初入开源代码管理库的学习过程>学了一周Git,基本有了个认识.每一位比我厉害的,都是大牛,网上找了几篇博客和教材(感谢你们),边学习边实践用了四天,写笔记 ...