Example #1
0
 private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
 {
     LogQueue.Enqueue(new LogEntry($"Stopping server...", ConsoleColor.Red, string.Empty, LogLevel.MASTER));
     stopServer = true;
     TcpListener.Stop();
     e.Cancel = true;
 }
Example #2
0
        private unsafe static void TcpHandleRandomPointRequest(BinaryWriter writer, byte[] bytes)
        {
            RandomPointRequest request = Utils.FromBytes <RandomPointRequest>(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 *pointerStart = request.A.ToArray())
            {
                float[] randomPoint;

                lock (querylock)
                {
                    randomPoint = request.MaxRadius > 0f ? AmeisenNav.GetRandomPointAround(request.MapId, pointerStart, request.MaxRadius)
                                                         : AmeisenNav.GetRandomPoint(request.MapId);
                }

                fixed(float *pRandomPoint = randomPoint)
                {
                    TcpSendData(writer, pRandomPoint, sizeof(Vector3));
                }
            }
        }
Example #3
0
 public void LogAll(IReadOnlyCollection <LogEntry> logs)
 {
     foreach (LogEntry log in logs)
     {
         LogQueue.Enqueue(log);
     }
 }
Example #4
0
 public void Log(string tag, string message, LogLevel logLevel = LogLevel.Debug, [CallerFilePath] string callingClass = "", [CallerMemberName] string callingFunction = "", [CallerLineNumber] int callingCodeline = 0)
 {
     if (logLevel <= ActiveLogLevel)
     {
         LogQueue.Enqueue(new LogEntry(logLevel, $"[{tag}] {message}", Path.GetFileNameWithoutExtension(callingClass), callingFunction, callingCodeline));
     }
 }
Example #5
0
        private static void PreloadMaps()
        {
            LogQueue.Enqueue(new LogEntry($"Preloading Maps: ", ConsoleColor.Green, JsonConvert.SerializeObject(Settings.PreloadMaps), LogLevel.DEBUG));
            foreach (int i in Settings.PreloadMaps)
            {
                AmeisenNav.LoadMap(i);
                LogQueue.Enqueue(new LogEntry($"Preloaded Map: ", ConsoleColor.Green, i.ToString(), LogLevel.DEBUG));
            }

            LogQueue.Enqueue(new LogEntry($"Preloaded {Settings.PreloadMaps.Length} Maps", ConsoleColor.Green, string.Empty, LogLevel.DEBUG));
        }
Example #6
0
        public static List <Vector3> GetPath(Vector3 start, Vector3 end, int mapId, PathRequestFlags flags, string clientIp)
        {
            int            pathSize;
            List <Vector3> path = new List <Vector3>();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            lock (maplock)
            {
                if (!AmeisenNav.IsMapLoaded(mapId))
                {
                    AmeisenNav.LoadMap(mapId);
                }

                unsafe
                {
                    fixed(float *pointerStart = start.ToArray())
                    fixed(float *pointerEnd = end.ToArray())
                    {
                        float *path_raw = AmeisenNav.GetPath(mapId, pointerStart, pointerEnd, &pathSize);

                        // postprocess the raw path to a list of Vector3
                        // the raw path looks like this:
                        // [ x1, y1, z1, x2, y2, z2, ...]
                        for (int i = 0; i < pathSize * 3; i += 3)
                        {
                            path.Add(new Vector3(path_raw[i], path_raw[i + 1], path_raw[i + 2]));
                        }
                    }
                }
            }

            if (flags.HasFlag(PathRequestFlags.NaturalSteeringBehavior))
            {
                path = NaturalSteeringBehavior.Perform(path);
            }

            if (flags.HasFlag(PathRequestFlags.ChaikinCurve))
            {
                path = ChaikinCurve.Perform(path);
            }

            //// bugged atm path = NodeReduction.Perform(path);

            sw.Stop();
            LogQueue.Enqueue(new LogEntry($"[{clientIp}] ", ConsoleColor.Green, $"Building Path with {path.Count} Nodes took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks)", LogLevel.INFO));

            return(path);
        }
Example #7
0
        // Logs string to log file.
        // -----------------------------------------------------------------------
        public static void LogEntry(string log)
        {
            // TODO: These might be used for timeouts later. Needed at this time for proper task creation.
            var source = new CancellationTokenSource();
            var token  = source.Token;

            LogQueue.Enqueue(log);

            // Creates a thread that will write to a log file.
            Task.Factory.StartNew(() =>
            {
                logEntryThreadCall(log, true);
            },
                                  token, TaskCreationOptions.PreferFairness, TaskScheduler.Default);
        }
Example #8
0
 /// <summary>
 /// Flush the stream
 /// </summary>
 public void Flush()
 {
     lock (this)
     {
         LogList entries = new LogList(this);
         this.Clear();
         logQueue.Enqueue(entries);
         WriteLogs();
         //foreach (LogEntry l in entries)
         //{
         //    Writer.WriteLine(l.Content);
         //}
         //Writer.Flush();
     }
 }
Example #9
0
 public static void EnterServerLoop()
 {
     while (!stopServer)
     {
         try
         {
             TcpClient newClient  = TcpListener.AcceptTcpClient();
             Thread    userThread = new Thread(new ThreadStart(() => HandleClient(newClient)));
             userThread.Start();
         }
         catch (Exception e)
         {
             if (!stopServer)
             {
                 string errorMsg = $"{e.GetType()} occured while at the TcpListener\n";
                 LogQueue.Enqueue(new LogEntry(errorMsg, ConsoleColor.Red, e.ToString(), LogLevel.ERROR));
             }
         }
     }
 }
Example #10
0
 public void Log(Level logLevel, string source, string message)
 {
     try
     {
         string currentTime    = DateTime.Now.ToString("hh:mm:ss.s: ");
         string logMessageLine = currentTime + LabelDictionary[logLevel] + source + " - " + message;
         if ((int)logLevel <= (int)GlobalLogLevel)
         {
             LogQueue.Enqueue(logMessageLine);
         }
         if (GuiOutput)
         {
             OnGuiLogPrint?.Invoke(new LogItem(logLevel, logMessageLine));
             MainWindow.GuiLogQueue.Enqueue(new LogItem(logLevel, logMessageLine));
         }
     }
     catch (KeyNotFoundException e)
     {
         Log(Level.ERROR, "LogHelper", "Key from " + source + " - " + e.Message);
     }
 }
Example #11
0
        public static void HandleClient(TcpClient client)
        {
            LogQueue.Enqueue(new LogEntry($"Client connected: {client.Client.RemoteEndPoint}", ConsoleColor.Cyan));

            using (StreamReader reader = new StreamReader(client.GetStream(), Encoding.ASCII))
                using (StreamWriter writer = new StreamWriter(client.GetStream(), Encoding.ASCII))
                {
                    bool isClientConnected = true;
                    Interlocked.Increment(ref clientCount);
                    UpdateConnectedClientCount();

                    while (isClientConnected)
                    {
                        try
                        {
                            string rawData = reader.ReadLine().Replace("&gt;", string.Empty);
                            if (!string.IsNullOrEmpty(rawData))
                            {
                                PathRequest pathRequest = JsonConvert.DeserializeObject <PathRequest>(rawData);

                                List <Vector3> path = GetPath(pathRequest.A, pathRequest.B, pathRequest.MapId, pathRequest.Flags, client.Client.RemoteEndPoint.ToString());

                                writer.WriteLine(JsonConvert.SerializeObject(path) + " &gt;");
                                writer.Flush();
                            }
                        }
                        catch (Exception e)
                        {
                            string errorMsg = $"{e.GetType()} occured at client ";
                            LogQueue.Enqueue(new LogEntry(errorMsg, ConsoleColor.Red, $"{client.Client.RemoteEndPoint}", LogLevel.ERROR));

                            isClientConnected = false;
                        }
                    }

                    Interlocked.Decrement(ref clientCount);
                    UpdateConnectedClientCount();
                    LogQueue.Enqueue(new LogEntry($"Client disconnected: ", ConsoleColor.Cyan, client.Client.RemoteEndPoint.ToString()));
                }
        }
Example #12
0
        /// <summary>
        /// Log a message.
        /// Check first for config and enqueue the message if necessary.
        /// </summary>
        /// <param name="message">The message to log.</param>
        /// <param name="logType">Log type.</param>
        /// <param name="sender">The sender as a string.</param>
        /// <param name="context">The context of the message, this will normally be the sender or this class.</param>
        private static void Log(string message, LogType logType, string sender, Object context)
        {
            // Log everything if application is not playing.
            if (Application.isPlaying)
            {
                if (config == null)
                {
                    LogQueue.Enqueue(new QueueableLog(message, logType, sender, context));

                    if (askedForInitialization)
                    {
                        return;
                    }
                    askedForInitialization = true;

                    ConfigurationManager.OnServiceReady += service =>
                    {
                        config = service.GetConfig <DebugConfig>();

                        if (config == null)
                        {
                            UnityEngine
                            .Debug
                            .LogError("There is no debug config file. Won't be able to log anything!");
                        }
                    };

                    return;
                }

                while (LogQueue.Count > 0)
                {
                    QueueableLog log = LogQueue.Dequeue();
                    LogSingleMessage(log.Message, log.LogType, log.Sender, log.Context);
                }
            }

            LogSingleMessage(message, logType, sender, context);
        }
Example #13
0
        private static Settings LoadConfigFile()
        {
            Settings settings = null;

            try
            {
                if (File.Exists(SettingsPath))
                {
                    settings = JsonConvert.DeserializeObject <Settings>(File.ReadAllText(SettingsPath));

                    if (!settings.MmapsFolder.EndsWith("/") && !settings.MmapsFolder.EndsWith("\\"))
                    {
                        settings.MmapsFolder += "/";
                    }

                    if (settings.LogToFile)
                    {
                        LogCheckFileExistence();
                    }

                    LogQueue.Enqueue(new LogEntry($"MaxPolyPathCount = {settings.MaxPolyPathCount}", ConsoleColor.White));
                    LogQueue.Enqueue(new LogEntry($"MaxPointPathCount = {settings.MaxPointPathCount}", ConsoleColor.White));
                    LogQueue.Enqueue(new LogEntry("Loaded config file", ConsoleColor.Green));
                }
                else
                {
                    settings = new Settings();
                    File.WriteAllText(SettingsPath, JsonConvert.SerializeObject(settings));
                    LogQueue.Enqueue(new LogEntry("Created default config file", ConsoleColor.White));
                }
            }
            catch (Exception ex)
            {
                LogQueue.Enqueue(new LogEntry("Failed to parse config.json...\n", ConsoleColor.Red, ex.ToString(), LogLevel.ERROR));
            }

            return(settings);
        }
Example #14
0
        public void LogRequest(string oldUrl, string referrer)
        {
            var bufferSize = Configuration.Configuration.Instance.BufferSize;

            if (LogQueue.Count > 0 && LogQueue.Count >= bufferSize)
            {
                lock (LogQueue)
                {
                    try
                    {
                        if (LogQueue.Count >= bufferSize)
                        {
                            LogRequests(LogQueue);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("An error occurred while trying to log 404 errors. ", ex);
                    }
                }
            }
            LogQueue.Enqueue(new LogEvent(oldUrl, DateTime.UtcNow, referrer));
        }
Example #15
0
        public unsafe static void TcpHandleClient(TcpClient client)
        {
            LogQueue.Enqueue(new LogEntry($"Client connected: ", ConsoleColor.Cyan, client.Client.RemoteEndPoint.ToString()));

            using Stream stream             = client.GetStream();
            using BinaryReader binaryReader = new BinaryReader(stream);
            using BinaryWriter binaryWriter = new BinaryWriter(stream);

            stream.ReadTimeout  = 3000;
            stream.WriteTimeout = 3000;

            bool isClientConnected = true;

            Interlocked.Increment(ref clientCount);
            UpdateConnectedClientCount();

            int failCounter = 0;

            while (isClientConnected)
            {
                try
                {
                    byte[] sizeBytes = binaryReader.ReadBytes(4);

                    if (sizeBytes.Length > 0)
                    {
                        int dataSize = BitConverter.ToInt32(sizeBytes, 0);

                        if (dataSize > 0)
                        {
                            byte[] bytes = binaryReader.ReadBytes(dataSize);

                            int msgType = BitConverter.ToInt32(bytes, 0);

                            if (bytes != null && Enum.IsDefined(typeof(MsgType), msgType))
                            {
                                switch ((MsgType)msgType)
                                {
                                case MsgType.KeepAlive:
                                    TcpHandleKeepAlive(binaryWriter);
                                    break;

                                case MsgType.Path:
                                    if (bytes.Length == sizeof(PathRequest))
                                    {
                                        TcpHandlePathRequest(binaryWriter, bytes);
                                    }
                                    else
                                    {
                                        LogQueue.Enqueue(new LogEntry("Received malformed PathRequest...", ConsoleColor.Red, $"{client.Client.RemoteEndPoint}", LogLevel.ERROR));
                                    }
                                    break;

                                case MsgType.RandomPoint:
                                    if (bytes.Length == sizeof(RandomPointRequest))
                                    {
                                        Stopwatch sw = Stopwatch.StartNew();

                                        TcpHandleRandomPointRequest(binaryWriter, bytes);

                                        sw.Stop();
                                        LogQueue.Enqueue(new LogEntry("[RANDOMPOINT] ", ConsoleColor.Green, $"took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks)", LogLevel.INFO));
                                    }
                                    else
                                    {
                                        LogQueue.Enqueue(new LogEntry("Received malformed RandomPointRequest...", ConsoleColor.Red, $"{client.Client.RemoteEndPoint}", LogLevel.ERROR));
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (failCounter >= 5)
                        {
                            isClientConnected = false;
                        }

                        Thread.Sleep(500);
                        ++failCounter;
                    }
                }
                catch (IOException)
                {
                    // occurs when client disconnects
                    isClientConnected = false;
                }
                catch (Exception e)
                {
                    string errorMsg = $"{e.GetType()} occured at client: \n{e.StackTrace}";
                    LogQueue.Enqueue(new LogEntry(errorMsg, ConsoleColor.Red, $"{client.Client.RemoteEndPoint}", LogLevel.ERROR));

                    isClientConnected = false;
                }
            }

            Interlocked.Decrement(ref clientCount);
            UpdateConnectedClientCount();
            LogQueue.Enqueue(new LogEntry("Client disconnected: ", ConsoleColor.Cyan, client.Client.RemoteEndPoint.ToString()));
        }
Example #16
0
        public static List <Vector3> GetPath(Vector3 start, Vector3 end, float maxRadius, int mapId, MovementType movementType, PathRequestFlags flags, string clientIp)
        {
            int            pathSize;
            List <Vector3> path = new List <Vector3>();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            lock (querylock)
            {
                if (!AmeisenNav.IsMapLoaded(mapId))
                {
                    AmeisenNav.LoadMap(mapId);
                }

                unsafe
                {
                    fixed(float *pointerStart = start.ToArray())
                    fixed(float *pointerEnd = end.ToArray())
                    {
                        switch (movementType)
                        {
                        case MovementType.MoveToPosition:
                            float[] movePath = AmeisenNav.GetPath(mapId, pointerStart, pointerEnd, &pathSize);

                            for (int i = 0; i < pathSize * 3; i += 3)
                            {
                                path.Add(new Vector3(movePath[i], movePath[i + 1], movePath[i + 2]));
                            }

                            if (flags.HasFlag(PathRequestFlags.ChaikinCurve))
                            {
                                path = ChaikinCurve.Perform(path);
                            }
                            break;

                        case MovementType.MoveAlongSurface:
                            float[] surfacePath = AmeisenNav.MoveAlongSurface(mapId, pointerStart, pointerEnd);
                            path.Add(new Vector3(surfacePath[0], surfacePath[1], surfacePath[2]));
                            break;

                        case MovementType.CastMovementRay:
                            if (AmeisenNav.CastMovementRay(mapId, pointerStart, pointerEnd))
                            {
                                // return end if target is in line of sight
                                path.Add(end);
                            }
                            else
                            {
                                // return none if target is not in line of sight
                                path.Clear();
                            }
                            break;

                        case MovementType.GetRandomPoint:
                            float[] randomPoint = AmeisenNav.GetRandomPoint(mapId);
                            path.Add(new Vector3(randomPoint[0], randomPoint[1], randomPoint[2]));
                            break;

                        case MovementType.GetRandomPointAround:
                            float[] randomPointAround = AmeisenNav.GetRandomPointAround(mapId, pointerStart, maxRadius);
                            path.Add(new Vector3(randomPointAround[0], randomPointAround[1], randomPointAround[2]));
                            break;
                        }
                    }
                }
            }

            sw.Stop();
            LogQueue.Enqueue(new LogEntry($"[{clientIp}] ", ConsoleColor.Green, $"{movementType} with {path.Count}/{Settings.MaxPointPathCount} Nodes took {sw.ElapsedMilliseconds}ms ({sw.ElapsedTicks} ticks)", LogLevel.INFO));
            return(path);
        }
Example #17
0
        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;
                }
            }
        }
Example #18
0
 public void Log(LogEntry log) =>
 LogQueue.Enqueue(log);
Example #19
0
        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;
                }
            }
        }