private unsafe static void TcpHandlePathRequest(BinaryWriter writer, byte[] bytes) { PathRequest request = Utils.FromBytes <PathRequest>(bytes); lock (querylock) { if (!AmeisenNav.IsMapLoaded(request.MapId)) { LogQueue.Enqueue(new LogEntry("[MMAPS] ", ConsoleColor.Green, $"Loading Map: {request.MapId}", LogLevel.INFO)); AmeisenNav.LoadMap(request.MapId); } } Stopwatch sw = Stopwatch.StartNew(); fixed(float *pStartPosition = request.A.ToArray()) fixed(float *pEndPosition = request.B.ToArray()) { switch (request.MovementType) { case MovementType.FindPath: int pathSize = 0; float[] movePath = null; try { lock (querylock) { movePath = AmeisenNav.GetPath(request.MapId, pStartPosition, pEndPosition, &pathSize); } } catch { } if (movePath != null && movePath.Length != 0) { // we can't apply the chaikin-curve on a path that has just a single node if (request.Flags.HasFlag(PathRequestFlags.ChaikinCurve) && pathSize > 1) { movePath = ChaikinCurve.Perform(movePath, Settings.ChaikinIterations); } // we can't apply the catmull-rom-spline on a path with less than 4 nodes if (request.Flags.HasFlag(PathRequestFlags.CatmullRomSpline) && pathSize >= 4) { movePath = CatmullRomSpline.Perform(movePath, Settings.CatmullRomSplinePoints); } pathSize = movePath.Length / 3; fixed(float *pPath = movePath) { TcpSendData(writer, pPath, sizeof(Vector3) * pathSize); } } sw.Stop(); LogQueue.Enqueue(new LogEntry("[FINDPATH] ", ConsoleColor.Green, $"took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks) Nodes: {pathSize}/{Settings.MaxPointPathCount} Flags: {request.Flags}")); break; case MovementType.MoveAlongSurface: float[] surfacePath; lock (querylock) { surfacePath = AmeisenNav.MoveAlongSurface(request.MapId, pStartPosition, pEndPosition); } fixed(float *pSurfacePath = surfacePath) { TcpSendData(writer, pSurfacePath, sizeof(Vector3)); } sw.Stop(); // LogQueue.Enqueue(new LogEntry("[MOVEALONGSURFACE] ", ConsoleColor.Green, $"took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks)")); break; case MovementType.CastMovementRay: Vector3 castRayResult; lock (querylock) { castRayResult = AmeisenNav.CastMovementRay(request.MapId, pStartPosition, pEndPosition) ? request.B : Vector3.Zero; } TcpSendData(writer, &castRayResult, sizeof(Vector3)); sw.Stop(); LogQueue.Enqueue(new LogEntry("[CASTMOVEMENTRAY] ", ConsoleColor.Green, $"took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks)")); break; } } }
private unsafe static void HandlePathRequest(BinaryWriter writer, byte[] bytes) { PathRequest request = Utils.FromBytes <PathRequest>(bytes); lock (querylock) { if (!AmeisenNav.IsMapLoaded(request.MapId)) { LogQueue.Enqueue(new LogEntry("[MMAPS] ", ConsoleColor.Green, $"Loading Map: {request.MapId}", LogLevel.INFO)); AmeisenNav.LoadMap(request.MapId); } } fixed(float *pStartPosition = request.A.ToArray()) fixed(float *pEndPosition = request.B.ToArray()) { switch (request.MovementType) { case MovementType.FindPath: int pathSize = 0; float[] movePath; Stopwatch swPath = Stopwatch.StartNew(); try { lock (querylock) { movePath = AmeisenNav.GetPath(request.MapId, pStartPosition, pEndPosition, &pathSize); } } catch { movePath = null; } List <Vector3> path = new List <Vector3>(movePath != null ? movePath.Length * 3 : 1); if (movePath == null || movePath.Length == 0) { path.Add(Vector3.Zero); fixed(Vector3 *pPath = path.ToArray()) SendData(writer, pPath, sizeof(Vector3)); return; } for (int i = 0; i < pathSize * 3; i += 3) { path.Add(new Vector3(movePath[i], movePath[i + 1], movePath[i + 2])); } if (request.Flags.HasFlag(PathRequestFlags.ChaikinCurve)) { if (path.Count > 1) { path = ChaikinCurve.Perform(path, Settings.ChaikinIterations); } else { request.Flags &= ~PathRequestFlags.ChaikinCurve; } } if (request.Flags.HasFlag(PathRequestFlags.CatmullRomSpline)) { if (path.Count >= 4) { path = CatmullRomSpline.Perform(path, Settings.CatmullRomSplinePoints); } else { request.Flags &= ~PathRequestFlags.CatmullRomSpline; } } int size = sizeof(Vector3) * path.Count; fixed(Vector3 *pPath = path.ToArray()) SendData(writer, pPath, size); swPath.Stop(); LogQueue.Enqueue(new LogEntry("[FINDPATH] ", ConsoleColor.Green, $"Generating path with {path.Count}/{Settings.MaxPointPathCount} nodes took {swPath.ElapsedMilliseconds}ms ({swPath.ElapsedTicks} ticks) (Flags: {request.Flags})", LogLevel.INFO)); break; case MovementType.MoveAlongSurface: Stopwatch swMoveAlongSurface = Stopwatch.StartNew(); float[] surfacePath; lock (querylock) { surfacePath = AmeisenNav.MoveAlongSurface(request.MapId, pStartPosition, pEndPosition); } fixed(float *pSurfacePath = surfacePath) SendData(writer, pSurfacePath, sizeof(Vector3)); swMoveAlongSurface.Stop(); LogQueue.Enqueue(new LogEntry("[MOVEALONGSURFACE] ", ConsoleColor.Green, $"MoveAlongSurface took {swMoveAlongSurface.ElapsedMilliseconds}ms ({swMoveAlongSurface.ElapsedTicks} ticks)", LogLevel.INFO)); break; case MovementType.CastMovementRay: Stopwatch swCastMovementRay = Stopwatch.StartNew(); Vector3 castRayResult; lock (querylock) { castRayResult = AmeisenNav.CastMovementRay(request.MapId, pStartPosition, pEndPosition) ? request.B : Vector3.Zero; } SendData(writer, &castRayResult, sizeof(Vector3)); swCastMovementRay.Stop(); LogQueue.Enqueue(new LogEntry("[CASTMOVEMENTRAY] ", ConsoleColor.Green, $"CastMovementRay took {swCastMovementRay.ElapsedMilliseconds}ms ({swCastMovementRay.ElapsedTicks} ticks)", LogLevel.INFO)); break; } } }