using RichCreator.Utility;
|
using RichCreator.Utility.Captures;
|
using RichCreator.Utility.CV;
|
using RichCreator.Utility.InputControl;
|
using RichCreator.Utility.Structs;
|
using RichCreator.Utility.Utilitys;
|
using Emgu.CV;
|
using Emgu.CV.Structure;
|
using RichCreator.Jobs.StateMachines;
|
using RichCreator.Maps;
|
using RichCreator.Models;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using ZTImage.Configuration;
|
using RichCreator.StateMachines;
|
using RichCreator.Utility.Maps;
|
using RichCreator.Maps.Kalete;
|
using RichCreator.Maps.Lindong;
|
using RichCreator.Maps.SkillSetting;
|
using RichCreator.Maps.Test;
|
using RichCreator.Dnf;
|
|
namespace RichCreator.Jobs
|
{
|
public class DNFJob : JobBase
|
{
|
public DNFJob(MapType mapType,RichCreatorConfig config) : base(config)
|
{
|
this.MapType = mapType;
|
}
|
|
/// <summary>
|
/// 游戏窗口
|
/// </summary>
|
public ZTRectangle GameRect;
|
|
/// <summary>
|
/// 地图类型
|
/// </summary>
|
public MapType MapType { get; private set; }
|
|
private Int32 runningStep = 0;
|
|
public override ZTResult Do(CancellationToken cancellationToken, Int32 runningStep)
|
{
|
this.runningStep = runningStep;
|
RunningModel runningModel = ConfigHelper.GetInstance<RunningModel>();
|
RichCreatorConfig config = ConfigHelper.GetInstance<RichCreatorConfig>();
|
|
ZTRectangle startGameButtonRect = ZTRectangle.Empty;
|
if (runningStep <= RunningStep.SelectRole)
|
{
|
//查找游戏窗口
|
bool result = FuncUtils.TimeoutCancelableWrap(config.StartWaitSecond * 1000, cancellationToken, () =>
|
{
|
return DnfCVHelper.IsSelectRoleWindow( out startGameButtonRect);
|
});
|
|
if (!result)
|
{
|
G.Instance.InfoWriter("启动DNF游戏失败");
|
return ZTResult.Failed;
|
}
|
G.Instance.InfoWriter($"已进入DNF角色界面,{startGameButtonRect.ToString()}");
|
}
|
|
WindowUtils.GetDnfRect(out this.GameRect);
|
|
//循环刷所有角色
|
ZTResult playResult = ZTResult.Success;
|
Int32 roleIndex = runningModel.RoleIndex>0? runningModel.RoleIndex - 1:0;
|
for (; roleIndex < config.RoleCount; roleIndex++)
|
{
|
RunningModel.UpdateRoleIndex(roleIndex+1);
|
if (cancellationToken.IsCancellationRequested)
|
{
|
return ZTResult.Cancel;
|
}
|
DateTime startRoleTime = DateTime.Now;
|
G.Instance.InfoWriter($"Play Role:{roleIndex+1}");
|
|
playResult = PlayRole(cancellationToken, roleIndex, startGameButtonRect);
|
|
StateProvider.Instance.PreRoleTime = (Int32)(DateTime.Now - startRoleTime).TotalSeconds;
|
StateProvider.Instance.RoleTimePassed = 0;
|
|
if (playResult != ZTResult.Success)
|
{
|
G.Instance.InfoWriter($"角色刷图失败,第{roleIndex+1}个角色");
|
return playResult;
|
}
|
G.Instance.InfoWriter($"角色刷图完成");
|
}
|
|
RunningModel.UpdateRoleIndex(1);
|
return ZTResult.Success;
|
}
|
|
/// <summary>
|
/// 刷单一角色
|
/// </summary>
|
/// <param name="cancellationToken"></param>
|
/// <param name="roleIndex"></param>
|
/// <returns></returns>
|
private ZTResult PlayRole(CancellationToken cancellationToken, Int32 roleIndex, ZTRectangle startGameButtonRect)
|
{
|
bool result = true;
|
Int32 pilaozhi = 1;
|
RichCreatorConfig config = ConfigHelper.GetInstance<RichCreatorConfig>();
|
if (this.runningStep < RunningStep.War)
|
{
|
//查找游戏窗口
|
result = FuncUtils.TimeoutCancelableWrap(5 * 60 * 1000, cancellationToken, () =>
|
{
|
return DnfCVHelper.IsSelectRoleWindow(out startGameButtonRect);
|
});
|
|
if (!result)
|
{
|
G.Instance.InfoWriter("非角色选择界面");
|
return ZTResult.Failed;
|
}
|
|
//进入赛丽亚的房间
|
result = IntoSailiyaRoom(cancellationToken, startGameButtonRect, roleIndex);
|
if (!result)
|
{
|
G.Instance.InfoWriter("未进入赛丽亚的房间");
|
return ZTResult.Failed;
|
}
|
G.Instance.InfoWriter("进入赛丽亚的房间");
|
|
|
//频道选择和网络断开重试
|
ChannelStateMachine csm = new ChannelStateMachine();
|
ZTResult workResult = csm.Work(this.GameRect, config.IsGroup, cancellationToken, 5 * 60 * 1000);
|
if (workResult != ZTResult.Success)
|
{
|
G.Instance.InfoWriter("切换频道没有成功," + workResult);
|
Thread.Sleep(5 * 60 * 1000);
|
return workResult;
|
}
|
G.Instance.InfoWriter("切换频道成功");
|
|
//查询疲劳值
|
pilaozhi = DnfCVHelper.GetPiLaoZhi(this.GameRect);
|
G.Instance.InfoWriter("疲劳值:" + pilaozhi);
|
}
|
|
|
ZTResult mapResult = ZTResult.Success;
|
if (pilaozhi > 0)
|
{
|
//刷图,并保持在可按esc退出的状态
|
MapInfo map = CreateMap( cancellationToken);
|
mapResult = map.Start(this.runningStep);
|
}
|
runningStep = RunningStep.None;
|
|
|
if (mapResult==ZTResult.Success)
|
{
|
//按ESC,退到选角色界面
|
if (ReturnToSelectRole(cancellationToken))
|
{
|
return ZTResult.Success;
|
}
|
return ZTResult.Failed;
|
}
|
|
return mapResult;
|
}
|
|
/// <summary>
|
/// 开始游戏
|
/// </summary>
|
/// <param name="cancelToken"></param>
|
/// <param name="timeoutSecond"></param>
|
/// <param name="startGameButtonRect"></param>
|
/// <param name="roleIndex"></param>
|
/// <returns></returns>
|
private bool IntoSailiyaRoom(CancellationToken cancelToken, ZTRectangle startGameButtonRect, Int32 roleIndex)
|
{
|
bool result = FuncUtils.NoChangeRetryCallWrap(
|
() =>
|
{
|
WindowUtils.SetDnfToTop();
|
|
if (SelectRoleIndex(roleIndex))
|
{
|
//点进入游戏
|
G.Instance.InputControl.MoveToAndClick(startGameButtonRect.GetCenterPoint());
|
return true;
|
}
|
Thread.Sleep(1000);
|
return false;
|
|
},
|
() =>
|
{
|
return FuncUtils.TimeoutCancelableWrap(3 * 60 * 1000, cancelToken, () =>
|
{
|
return DnfCVHelper.IsInSaiLiYaHouse(this.GameRect);
|
});
|
},
|
() =>
|
{
|
if (DnfCVHelper.IsSelectRoleWindow(out startGameButtonRect))
|
{
|
return true;
|
}
|
return false;
|
},3);
|
return result;
|
}
|
|
|
|
/// <summary>
|
/// 选角色时的角色选择偏移
|
/// </summary>
|
private static ZTPoint[] RoleOffset = new Utility.Structs.ZTPoint[] {
|
new ZTPoint (133,191),
|
new ZTPoint (249,191),
|
new ZTPoint (371,191),
|
new ZTPoint (499,191),
|
|
|
new ZTPoint (133,398),
|
new ZTPoint (249,398),
|
new ZTPoint (371,398),
|
new ZTPoint (499,398),
|
|
new ZTPoint (133,398),
|
new ZTPoint (249,398)
|
};
|
|
|
/// <summary>
|
/// 选择角色
|
/// </summary>
|
/// <param name="roleIndex"></param>
|
/// <returns></returns>
|
private bool SelectRoleIndex(Int32 roleIndex)
|
{
|
if (roleIndex < 8)
|
{
|
//移到顶端
|
if (!ScrollMoveToTop())
|
{
|
return false;
|
}
|
|
}
|
else
|
{
|
//移到顶端,向下一格
|
if (!ScrollMoveToDownOne())
|
{
|
return false;
|
}
|
}
|
|
Thread.Sleep(1000);
|
//选角色
|
G.Instance.InputControl.MoveToAndClick(this.GameRect.Start.Add(RoleOffset[roleIndex]));
|
Thread.Sleep(500);
|
return true;
|
}
|
|
/// <summary>
|
/// 滚动条移动到顶端
|
/// </summary>
|
/// <returns></returns>
|
private bool ScrollMoveToTop()
|
{
|
ZTRectangle upButton = ZTRectangle.Empty;
|
ZTRectangle downButton = ZTRectangle.Empty;
|
ZTRectangle scrollButton = ZTRectangle.Empty;
|
|
|
//查找滚动条位置
|
if (DnfCVHelper.FindSelectRoleScroll(out upButton, out downButton, out scrollButton, this.GameRect))
|
{
|
//是在顶部
|
if (Math.Abs(upButton.End.Y - scrollButton.Start.Y) < 3)
|
{
|
return true;
|
}
|
}
|
|
|
|
Int32 counter = 4;
|
while(counter>0)
|
{
|
counter--;
|
//查找滚动条位置
|
if (!DnfCVHelper.FindSelectRoleScroll(out upButton, out downButton, out scrollButton, this.GameRect))
|
{
|
continue;
|
}
|
|
//是在顶部
|
if (Math.Abs(upButton.End.Y - scrollButton.Start.Y) < 3)
|
{
|
return true;
|
}
|
|
ZTPoint targetPoint = scrollButton.GetCenterPoint();
|
G.Instance.InputControl.MoveTo(targetPoint.X, targetPoint.Y, false, false, false);
|
G.Instance.InputControl.Move(0, 0, true, false, false);
|
targetPoint = upButton.GetCenterPoint();
|
G.Instance.InputControl.MoveTo(targetPoint.X, targetPoint.Y, true, false, false);
|
G.Instance.InputControl.Move(0, 0, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
G.Instance.InputControl.MoveTo(this.GameRect.End.X, this.GameRect.Start.Y, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
}
|
|
|
return false;
|
}
|
|
/// <summary>
|
/// 滚动条移动到下一格
|
/// </summary>
|
/// <returns></returns>
|
private bool ScrollMoveToDownOne()
|
{
|
ZTRectangle upButton = ZTRectangle.Empty;
|
ZTRectangle downButton = ZTRectangle.Empty;
|
ZTRectangle scrollButton = ZTRectangle.Empty;
|
|
|
//查找滚动条位置
|
if (DnfCVHelper.FindSelectRoleScroll(out upButton, out downButton, out scrollButton, this.GameRect))
|
{
|
//是在下一格
|
if (Math.Abs(upButton.End.Y - scrollButton.Start.Y) > 3&& Math.Abs(upButton.End.Y - scrollButton.Start.Y)<30)
|
{
|
return true;
|
}
|
}
|
|
|
|
Int32 counter = 4;
|
while (counter > 0)
|
{
|
counter--;
|
//查找滚动条位置
|
if (!DnfCVHelper.FindSelectRoleScroll(out upButton, out downButton, out scrollButton, this.GameRect))
|
{
|
continue;
|
}
|
|
//是在第一格
|
if (Math.Abs(upButton.End.Y - scrollButton.Start.Y) > 3 && Math.Abs(upButton.End.Y - scrollButton.Start.Y) < 30)
|
{
|
return true;
|
}
|
|
ZTPoint targetPoint = scrollButton.GetCenterPoint();
|
G.Instance.InputControl.MoveTo(targetPoint.X, targetPoint.Y, false, false, false);
|
G.Instance.InputControl.Move(0, 0, true, false, false);
|
targetPoint = upButton.GetCenterPoint();
|
G.Instance.InputControl.MoveTo(targetPoint.X, targetPoint.Y, true, false, false);
|
G.Instance.InputControl.Move(0, 0, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
|
|
G.Instance.InputControl.MoveToAndClick(downButton.GetCenterPoint());
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
G.Instance.InputControl.MoveTo(this.GameRect.End.X, this.GameRect.Start.Y, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
}
|
|
|
return false;
|
}
|
|
|
/// <summary>
|
/// 返回选择角色界面
|
/// </summary>
|
/// <param name="cancelToken"></param>
|
/// <param name="gameRect"></param>
|
/// <returns></returns>
|
private bool ReturnToSelectRole(CancellationToken cancelToken)
|
{
|
//打开系统菜单
|
int counter = 10;
|
bool result = false;
|
WindowUtils.SetDnfToTop();
|
while (counter > 0)
|
{
|
G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Escape);
|
bool findPanelResult = FuncUtils.TimeoutCancelableWrap(3000, cancelToken, () =>
|
{
|
return DnfCVHelper.IsOpenSystemPanel(this.GameRect);
|
});
|
|
if (findPanelResult)
|
{
|
result = true;
|
break;
|
}
|
counter--;
|
}
|
|
if (result)
|
{
|
//点击切换角色按钮388,445
|
G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(this.GameRect.Start.X + 388, this.GameRect.Start.Y + 445));
|
return true;
|
}
|
G.Instance.InfoWriter("退回选择角色界面失败");
|
return false;
|
}
|
|
/// <summary>
|
/// 根据当前选择的地图实例化DNF地图
|
/// </summary>
|
/// <param name="config"></param>
|
/// <returns></returns>
|
private MapInfo CreateMap(CancellationToken cancelToken)
|
{
|
switch (this.MapType)
|
{
|
case MapType.Lingdong:
|
return new LindongMap(this.GameRect,cancelToken);
|
case MapType.Kalete:
|
return new KaleteMap(this.GameRect, cancelToken);
|
case MapType.SkillSetting:
|
return new SkillSettingMap(this.GameRect, cancelToken);
|
case MapType.Test:
|
return new TestMap(this.GameRect, cancelToken);
|
}
|
throw new Exception("this task index is error");
|
}
|
}
|
}
|