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;
}
///
/// 游戏窗口
///
public ZTRectangle GameRect;
///
/// 地图类型
///
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();
RichCreatorConfig config = ConfigHelper.GetInstance();
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;
}
///
/// 刷单一角色
///
///
///
///
private ZTResult PlayRole(CancellationToken cancellationToken, Int32 roleIndex, ZTRectangle startGameButtonRect)
{
bool result = true;
Int32 pilaozhi = 1;
RichCreatorConfig config = ConfigHelper.GetInstance();
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;
}
///
/// 开始游戏
///
///
///
///
///
///
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;
}
///
/// 选角色时的角色选择偏移
///
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)
};
///
/// 选择角色
///
///
///
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;
}
///
/// 滚动条移动到顶端
///
///
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;
}
///
/// 滚动条移动到下一格
///
///
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;
}
///
/// 返回选择角色界面
///
///
///
///
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;
}
///
/// 根据当前选择的地图实例化DNF地图
///
///
///
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");
}
}
}