static OrtogoonInt[] MengeFläceRandUmFläce( OrtogoonInt FläceZuUmrande, int RandGrööse) { if (null == FläceZuUmrande) { return(null); } var RandListeTailFläce = new List <OrtogoonInt>(); for (int SaiteIndex = 0; SaiteIndex < 4; SaiteIndex++) { var AxeIndex = SaiteIndex % 2; var AxeNictIndex = (AxeIndex + 1) % 2; var RictungVorzaice = ((SaiteIndex / 2) % 2) * 2 - 1; var RandTailFläceMiteDistanzVonFläceMite = new Vektor2DInt( (AxeIndex * (FläceZuUmrande.Grööse.A + RandGrööse) / 2) * RictungVorzaice, (AxeNictIndex * (FläceZuUmrande.Grööse.B + RandGrööse) / 2) * RictungVorzaice); var RandTailFläceMite = FläceZuUmrande.ZentrumLaage + RandTailFläceMiteDistanzVonFläceMite; var RandTailFläce = OrtogoonInt.AusPunktZentrumUndGrööse(RandTailFläceMite, new Vektor2DInt( RandGrööse * (1 + AxeNictIndex * 2), RandGrööse * (1 + AxeIndex * 2))); RandListeTailFläce.Add(RandTailFläce); } return(RandListeTailFläce.ToArray()); }
static public IEnumerable <T> OrderByNearestPointOnLine <T>( this IEnumerable <T> sequence, Vektor2DInt lineVector, Func <T, Vektor2DInt?> getPointRepresentingElement) { var LineVectorLength = lineVector.Length(); if (null == getPointRepresentingElement || LineVectorLength < 1) { return(sequence); } var LineVectorNormalizedMilli = (lineVector * 1000) / LineVectorLength; return (sequence?.Select(element => { Int64?LocationOnLine = null; var PointRepresentingElement = getPointRepresentingElement(element); if (PointRepresentingElement.HasValue) { LocationOnLine = PointRepresentingElement.Value.A * LineVectorNormalizedMilli.A + PointRepresentingElement.Value.B * LineVectorNormalizedMilli.B; } return new { Element = element, LocationOnLine = LocationOnLine }; }) ?.OrderBy(elementAndLocation => elementAndLocation.LocationOnLine) ?.Select(elementAndLocation => (T)elementAndLocation.Element)); }
public static IEnumerable <T> OrderByNearestPointOnLine <T>(this IEnumerable <T> sequence, Vektor2DInt lineVector, Func <T, Vektor2DInt?> getPointRepresentingElement) { long num = lineVector.Length(); if (getPointRepresentingElement == null || num < 1) { return(sequence); } Vektor2DInt LineVectorNormalizedMilli = lineVector * 1000L / num; return(sequence?.Select(delegate(T element) { long?locationOnLine = null; Vektor2DInt?vektor2DInt = getPointRepresentingElement(element); if (vektor2DInt.HasValue) { locationOnLine = vektor2DInt.Value.A * LineVectorNormalizedMilli.A + vektor2DInt.Value.B * LineVectorNormalizedMilli.B; } return new { Element = element, LocationOnLine = locationOnLine }; })?.OrderBy(elementAndLocation => elementAndLocation.LocationOnLine)?.Select(elementAndLocation => elementAndLocation.Element)); }
public static IEnumerable <T> OrderByCenterDistanceToPoint <T>(this IEnumerable <T> sequence, Vektor2DInt point) where T : IUIElement { return(sequence?.OrderBy(delegate(T element) { Vektor2DInt value = point; Vektor2DInt?subtrahend = (element != null) ? element.RegionCenter() : null; return (value - subtrahend)?.LengthSquared() ?? long.MaxValue; })); }
virtual public InProcessGbsFläceRectekOrto Versezt(Vektor2DInt Versaz) { var FläceTailSctaatisc = this.FläceTailSctaatisc; //var FläceTailSctaatiscVersezt = // null == FläceTailSctaatisc ? null : FläceTailSctaatisc.Versezt(Versaz); var FläceTailSctaatiscVersezt = FläceTailSctaatisc.Versezt(Versaz); return(new InProcessGbsFläceRectekOrto(FläceTailSctaatiscVersezt)); }
static public Vektor2DInt?ClientToScreen(this IntPtr hWnd, Vektor2DInt locationInClient) { var structWinApi = locationInClient.AsWindowsPoint(); if (!BotEngine.WinApi.User32.ClientToScreen(hWnd, ref structWinApi)) { return(null); } return(structWinApi.AsVektor2DInt()); }
static public UIElement CopyWithRegionSizeSubstituted( this UIElement UIElement, Vektor2DInt SizeSubstitute) { if (null == UIElement) { return(null); } return(UIElement.CopyWithRegionSubstituted(UIElement.Region.GrööseGeseztAngelpunktZentrum(SizeSubstitute))); }
static public void User32MouseEvent( Vektor2DInt MousePositionOnScreen, IEnumerable <MouseButtonIdEnum> MouseButtonDown, IEnumerable <MouseButtonIdEnum> MouseButtonUp) { var MouseEventFlag = User32MouseEventFlagAggregate(MouseButtonDown, MouseButtonUp); User32.mouse_event( (uint)MouseEventFlag | (uint)User32.MouseEventFlagEnum.MOUSEEVENTF_ABSOLUTE, (uint)MousePositionOnScreen.A, (uint)MousePositionOnScreen.B, 0, UIntPtr.Zero); }
static public void MouseMoveLinearContinuous( this IMotor motor, Vektor2DInt origin, Vektor2DInt destiniation) { var Distance = destiniation - origin; var DistanceLength = Distance.Length(); for (int i = 0; i < DistanceLength; i++) { var interpolated = origin + (Distance * i) / DistanceLength; motor?.MouseMove(interpolated); } motor?.MouseMove(destiniation); }
static public IEnumerable<ITaskParam> Resolve( this UIElementHideParam Param, Bot Bot) { var UIElementToHide = Param?.UIElement; if (null == UIElementToHide) { yield break; } if (UIElementToHide.IsMessageConnectionLost()) { // in this case, closing the MessageBox would result in the eve process exiting. // since relogin is not implemented yet, leave the message on screen so the user can tell what happened only by looking at eve client. yield return new ToClientStatusParam("connection lost", TaskStatusEnum.Failed); } if (UIElementToHide.IsOccludingModal() || UIElementToHide is Menu) { yield return WindowsInput.Native.VirtualKeyCode.ESCAPE.AsMotionParam(); yield break; } if (UIElementToHide is PanelGroup) { // to close a PanelGroup, click somewhere. Try to choose a region where clicking will not trigger any other actions. // the region beside the top of the neocom should be good for that. var Neocom = Bot?.SequenceStepLastState()?.MemoryMeasurement?.Wert?.Neocom; var RegionToClickCenter = new Vektor2DInt(Neocom.Region.Max0 + 30, 10); yield return new MotionParam( new[] { new MotionParamMouseRegion(UIElementToHide, (RegionToClickCenter - UIElementToHide.RegionCenter() ?? new Vektor2DInt()).OrtogonFromCenterAndSize(new Vektor2DInt(60, 16))) }, MouseButtonIdEnum.Right); yield break; } // other methods not implemented yet (e.g. minimize button on Window) yield return new ToClientStatusParam(TaskStatusEnum.Failed); }
static public void MouseMoveToPointInClientRect( IntPtr WindowHandle, Vektor2DInt DestinationPointInClientRect, out POINT DestinationPointInScreen) { DestinationPointInScreen = DestinationPointInClientRect.AsWindowsPoint(); // get screen coordinates BotEngine.WinApi.User32.ClientToScreen(WindowHandle, ref DestinationPointInScreen); var lParam = (IntPtr)((((int)DestinationPointInClientRect.B) << 16) | ((int)DestinationPointInClientRect.A)); var wParam = IntPtr.Zero; BotEngine.WinApi.User32.SetCursorPos(DestinationPointInScreen.x, DestinationPointInScreen.y); BotEngine.WinApi.User32.SendMessage(WindowHandle, (uint)SictMessageTyp.WM_MOUSEMOVE, wParam, lParam); }
static public IUIElement WithRegionSizeBoundedMaxPivotAtCenter(this IUIElement @base, Vektor2DInt regionSizeMax) => null == @base ? null : @base.WithRegion(@base.Region.WithSizeBoundedMaxPivotAtCenter(regionSizeMax));
static public Vektor2DInt? ClientToScreen(this IntPtr hWnd, Vektor2DInt locationInClient) { var structWinApi = locationInClient.AsWindowsPoint(); if (!BotEngine.WinApi.User32.ClientToScreen(hWnd, ref structWinApi)) return null; return structWinApi.AsVektor2DInt(); }
static public void MouseMove(this ISmartSession session, Vektor2DInt destination) => session.MouseMove((int)destination.A, (int)destination.B);
public BotStepResult Step( bool motionEnabled, Func <Request, Response> service) { lock (Lock) { var StartTime = DateTime.Now; Exception Exception = null; string UIMessageText = null; KeyValuePair <UInt32[], int> windowClientRaster = default(KeyValuePair <UInt32[], int>); ImagePatternMatch[] RasterSetPatternMatch = null; ImagePatternMatch[] RasterSetPatterMatchTriggered = null; IconHandling[] SetIconCandidate = null; var ImageSearchDelegate = new Func <KeyValuePair <UInt32[], int>, IEnumerable <ImagePatternMatch> >(raster => service?.Invoke(new Request { ImagePatternMatchSearch = new ImagePatternMatchSearchRequest { Raster = raster, }, })?.ImagePatternMatchSearch?.SetMatch); try { var WindowHandle = this.WindowHandle; if (!WindowHandle.HasValue) { throw new ArgumentException("no window selected"); } BotEngine.Windows.RECT WindowClientRect; BotEngine.WinApi.User32.GetClientRect(WindowHandle.Value, out WindowClientRect); var WindowClientSize = new Vektor2DInt(WindowClientRect.Width, WindowClientRect.Height); var Motor = new Motor.WindowMotor(WindowHandle.Value); BotEngine.WinApi.User32.SetForegroundWindow(WindowHandle.Value); windowClientRaster = WinApi.Raster32BitFromClientRectFromWindowMitHandleOverDesktop(WindowHandle.Value); if (windowClientRaster.Value < 1) { throw new Exception("failed to take image of window."); } RasterSetPatternMatch = ImageSearchDelegate?.Invoke(windowClientRaster)?.ToArray(); var MouseMoveToRest = new Action(() => { UIMessageText += "move mouse to rest location." + Environment.NewLine; Motor.MouseMoveLinearContinuous(MouseRestLocation + new Vektor2DInt(44, 44), MouseRestLocation); }); var subsetMatchWithPatternIdContaining = new Func <string, IEnumerable <ImagePatternMatch> >(idPortion => RasterSetPatternMatch?.Where(match => match?.SourcePatternId?.RegexMatchSuccessIgnoreCase(Regex.Escape(idPortion)) ?? false)); var hourglassMatch = subsetMatchWithPatternIdContaining(PatternIdConfig.Hourglass)?.ToArray(); var closeButtonMatch = subsetMatchWithPatternIdContaining("close.button")?.FirstOrDefault(); var progressBarMatch = subsetMatchWithPatternIdContaining("progress")?.FirstOrDefault(); var clickToCollectMatch = subsetMatchWithPatternIdContaining("collect")?.FirstOrDefault(); var IdleIconMatch = subsetMatchWithPatternIdContaining(PatternIdConfig.Idle); SetIconCandidate = new[] { subsetMatchWithPatternIdContaining(PatternIdConfig.Coin), subsetMatchWithPatternIdContaining(PatternIdConfig.WorkshopProductReady), subsetMatchWithPatternIdContaining(PatternIdConfig.Idle), } .ConcatNullable() ?.WhereNotDefault() ?.Select(match => new IconHandling { PatternId = match.SourcePatternId, Location = match.Area.Center(), }) ?.Where(icon => SecurityMarginThickness < icon.Location.A && Math.Max(SecurityMarginThicknessTop, SecurityMarginThickness) < icon.Location.B && icon.Location.A + SecurityMarginThickness < WindowClientSize.A && icon.Location.B + SecurityMarginThickness < WindowClientSize.B) ?.ToArray(); foreach (var Icon in SetIconCandidate.EmptyIfNull()) { var lastVisit = ListIconVisited?.CastToNullable()?.LastOrDefault(visit => visit.Value.Key.PatternId == Icon.PatternId && DistanceInBoundProductIconAnim(visit.Value.Key.Location - Icon.Location)); Icon.LastVisitAge = (DateTime.Now - lastVisit?.Value)?.TotalSeconds; } var ListToVisit = SetIconCandidate // only consider icons which were already present in last step to prevent distraction by temporary floating icons triggered by collection. ?.Where(icon => StepLast?.SetIconCandidate?.Any(lastStepIcon => (lastStepIcon.Location - icon.Location).Length() < 3) ?? false) ?.OrderByDescending(t => t.LastVisitAge ?? int.MaxValue) ?.ThenBy(t => t.Location.B) ?.ToArray(); var IconToVisitNext = ListToVisit?.FirstOrDefault(); // production button contains a hourglass icon. // we want the shortest time and assume that is the one closest to the upper left. var productionPreferredButtonLocation = hourglassMatch ?.OrderBy(match => match.Area.Center().Length()) ?.FirstOrDefault(); // Baracks dialog has an hourglass too. var DialogIsProduction = 3 < hourglassMatch?.Length; UIMessageText += "next icon to visit: " + ((null == IconToVisitNext) ? "null" : ("'" + IconToVisitNext?.PatternId + "'" + " at " + IconToVisitNext.Location.RenderForUI() + " (last visited " + (((int?)IconToVisitNext.LastVisitAge)?.ToString() ?? "????") + "s ago)")) + Environment.NewLine; if (motionEnabled) { if (null != closeButtonMatch) { if (null != productionPreferredButtonLocation && DialogIsProduction) { UIMessageText += "click on production start button."; Motor.MouseClickLeft(productionPreferredButtonLocation.Area.Center()); goto StepEnd; } UIMessageText += "click on dialog close button."; Motor.MouseClickLeft((closeButtonMatch?.Area.Center()).Value); goto StepEnd; } if (null != progressBarMatch || null != clickToCollectMatch) { UIMessageText += "tooltip detected, move mouse to rest location."; MouseMoveToRest(); goto StepEnd; } if (null != IconToVisitNext && !(IconToVisitNext?.LastVisitAge < VisitDistanceMin)) { var BuildingProductIconReadyLocation = IconToVisitNext.Location; var IconIdMessage = "under icon of type " + IconToVisitNext?.PatternId + " at " + BuildingProductIconReadyLocation.RenderForUI(); UIMessageText += IconIdMessage + ":" + Environment.NewLine; var mouseDestination = BuildingProductIconReadyLocation + FromProductIconToBuildingOffset; ListIconVisited.Enqueue(new KeyValuePair <IconHandling, DateTime>(IconToVisitNext, DateTime.Now)); ListIconVisited.ListeKürzeBegin(400); BotEngine.WinApi.User32.SetForegroundWindow(WindowHandle.Value); if (IconToVisitNext.PatternId == PatternIdConfig.Idle) { UIMessageText += "open dialog at " + mouseDestination.RenderForUI() + "." + Environment.NewLine; Motor.MouseClick(mouseDestination, MouseButtonIdEnum.Left); } else { UIMessageText += "collect at " + mouseDestination.RenderForUI() + "." + Environment.NewLine; var PathStretch = new Vektor2DInt(CollectDragDistance, 0).RotatedByMikro((int)new Random((int)Bib3.Glob.StopwatchZaitMiliSictInt()).Next().SictUmgebrocen(0, 1000) * 1000); var collectLocationDistant = mouseDestination + PathStretch; var middle = (mouseDestination + collectLocationDistant) / 2; var listWaypoint = Extension.ListPointInterpolated(mouseDestination, collectLocationDistant, (int)Extension.RandomInt().SictUmgebrocen(7, 16)).ToArray(); listWaypoint = listWaypoint.Concat(listWaypoint.Reversed()).ToArray(); var LocationInScreenFromLocationInWindow = new Func <Vektor2DInt, Vektor2DInt>(windowClient => { var PointInScreen = new BotEngine.Windows.POINT { x = (int)windowClient.A, y = (int)windowClient.B }; BotEngine.WinApi.User32.ClientToScreen(Motor.WindowHandle, ref PointInScreen); return(new Vektor2DInt(PointInScreen.x, PointInScreen.y)); }); var simulator = new WindowsInput.InputSimulator(); simulator.Mouse.LeftButtonUp(); bool mouseButtonDown = false; foreach (var waypointInWindow in listWaypoint) { var locationOnScreen = LocationInScreenFromLocationInWindow(waypointInWindow); Thread.Sleep((int)Extension.RandomInt().SictUmgebrocen(0, 33)); BotEngine.WinApi.User32.SetCursorPos((int)locationOnScreen.A, (int)locationOnScreen.B); if (!mouseButtonDown) { mouseButtonDown = true; simulator.Mouse.LeftButtonDown(); } } simulator.Mouse.LeftButtonUp(); Thread.Sleep(111); } MouseMoveToRest(); goto StepEnd; } } StepEnd :; } catch (Exception tException) { Exception = tException; } var StepResult = new BotStepResult { StartTime = StartTime, Exception = Exception, UIMessageText = UIMessageText + " " + Bib3.Glob.SictString(Exception, true), WindowClientRaster = windowClientRaster, RasterSetPatternMatch = RasterSetPatternMatch, RasterSetPatterMatchTriggered = RasterSetPatterMatchTriggered, SetIconCandidate = SetIconCandidate, MotionEnabled = motionEnabled, EndTime = DateTime.Now, }; StepLast = StepResult; if (motionEnabled) { MotionEnabledStepLast = StepResult; } return(StepResult); } }
public static IUIElement WithRegionSizeBoundedMaxPivotAtCenter(this IUIElement @base, Vektor2DInt regionSizeMax) { return(@base?.WithRegion(@base.Region.WithSizeBoundedMaxPivotAtCenter(regionSizeMax))); }
static public bool DistanceInBoundProductIconAnim(Vektor2DInt iconDistance) => Math.Abs(iconDistance.A) < 4 && Math.Abs(iconDistance.B) < 30;
static public IUIElement WithRegionSizeBoundedMaxPivotAtCenter(this IUIElement Base, Vektor2DInt RegionSizeMax) => null == Base ? null : Base.WithRegion(Base.Region.WithSizeBoundedMaxPivotAtCenter(RegionSizeMax));
static public System.Windows.Point AlsSystemWindowsPoint(Vektor2DInt Vektor) { return(new System.Windows.Point(Vektor.A, Vektor.B)); }
static public void User32MouseEvent( Vektor2DInt MousePositionOnScreen, IEnumerable<MouseButtonIdEnum> MouseButtonDown, IEnumerable<MouseButtonIdEnum> MouseButtonUp) { var MouseEventFlag = User32MouseEventFlagAggregate(MouseButtonDown, MouseButtonUp); User32.mouse_event( (uint)MouseEventFlag | (uint)User32.MouseEventFlagEnum.MOUSEEVENTF_ABSOLUTE, (uint)MousePositionOnScreen.A, (uint)MousePositionOnScreen.B, 0, UIntPtr.Zero); }
public IEnumerable <KeyValuePair <string, ImagePatternMatch> > SetMatchInImage(KeyValuePair <UInt32[], int> raster) { if (null == raster.Key) { return(null); } var rasterSizeA = raster.Value; var rasterSizeB = raster.Key.Length / rasterSizeA; var setTypeIdAndPattern = setTypeSetPattern .SelectMany(typeIdAndSetPattern => typeIdAndSetPattern.Value.Select(pattern => new KeyValuePair <string, ImagePattern>(typeIdAndSetPattern.Key, pattern))) .ToArray(); var setPatternMatch = setTypeIdAndPattern .AsParallel() .Select(typeIdAndPattern => { var patternFirstElement = typeIdAndPattern.Value.ListElement.FirstOrDefault(); var patternSetOffset = typeIdAndPattern.Value.ListElement.SelectMany(elem => elem.locationOption).ToArray(); var boundRect = patternSetOffset.BoundingRectangle(); var tolerance = 0x20; var patternSetMatchLocation = new List <Vektor2DInt>(); for (int rasterLocB = Math.Max(0, (int)-boundRect.Min1); rasterLocB < rasterSizeB - Math.Max(0, boundRect.Max1 + 1); rasterLocB++) { for (int rasterLocA = Math.Max(0, (int)-boundRect.Min0); rasterLocA < rasterSizeA - Math.Max(0, boundRect.Max1 + 1); rasterLocA++) { var rasterLoc = new Vektor2DInt(rasterLocA, rasterLocB); bool match = true; for (int patternElemIndex = 0; patternElemIndex < typeIdAndPattern.Value.ListElement.Length; ++patternElemIndex) { var elem = typeIdAndPattern.Value.ListElement[patternElemIndex]; var elemMatch = false; foreach (var elemLoc in elem.locationOption) { var inRasterLocation = rasterLoc + elemLoc; var rasterPixelIndex = inRasterLocation.A + inRasterLocation.B * rasterSizeA; var rasterColorAggr = raster.Key[rasterPixelIndex]; var rasterR = (rasterColorAggr >> 16) & 0xff; var rasterG = (rasterColorAggr >> 8) & 0xff; var rasterB = (rasterColorAggr >> 0) & 0xff; var ColorConstraint = elem.ColorConstraintDelegate; if (null == ColorConstraint) { var DiffR = Math.Abs(rasterR - elem.ColorR); var DiffG = Math.Abs(rasterG - elem.ColorG); var DiffB = Math.Abs(rasterB - elem.ColorB); if (!(tolerance < DiffR || tolerance < DiffG || tolerance < DiffB)) { elemMatch = true; } } else { elemMatch = ColorConstraint((int)rasterR, (int)rasterG, (int)rasterB); } if (elemMatch) { break; } } if (!elemMatch) { match = false; break; } } if (match) { patternSetMatchLocation.Add(rasterLoc); } } } return(new KeyValuePair <string, IEnumerable <ImagePatternMatch> >(typeIdAndPattern.Key, patternSetMatchLocation.Select(matchLocation => new ImagePatternMatch() { SourcePatternId = typeIdAndPattern.Value.Id, Area = RectInt.FromCenterAndSize(matchLocation, new Vektor2DInt()), }))); }) .ToArray(); var setTypeIdAndSetMatchAggregated = setPatternMatch .GroupBy(typeIdAndSetMatch => typeIdAndSetMatch.Key) .Select(group => new KeyValuePair <string, ImagePatternMatch[]>(group.Key, group.Values().ConcatNullable().PatternMatchLocationAggregated(4).ToArray())) .ToArray(); return (setTypeIdAndSetMatchAggregated .SelectMany(typeIdAndSetMatchAggregated => typeIdAndSetMatchAggregated.Value .Select(match => new KeyValuePair <string, ImagePatternMatch>(typeIdAndSetMatchAggregated.Key, match)))); }
static public Int64 LengthSquared(this Vektor2DInt Vector) => Vector.BetraagQuadriirt;
static public IEnumerable <T> OrderByCenterDistanceToPoint <T>( this IEnumerable <T> sequence, Vektor2DInt point) where T : IUIElement => sequence?.OrderBy(element => (point - element?.RegionCenter())?.LengthSquared() ?? Int64.MaxValue);
static public string RenderForUI(this Vektor2DInt vektor) => vektor.A + "|" + vektor.B;
static public IEnumerable <Vektor2DInt> ListPointInterpolated(Vektor2DInt start, Vektor2DInt end, int count) => Enumerable.Range(0, count).Select(i => start + (end - start) / Math.Max(0, count - 1) * i);
public static POINT AsWindowsPoint(this Vektor2DInt vector) { return(new POINT((int)vector.A, (int)vector.B)); }
static public Int64 Length(this Vektor2DInt Vector) => Vector.Betraag;