Esempio n. 1
0
        //Thread for parallel coroutines runner
        async Task ParallelCoroutineRunner()
        {
            var parallelFps = 0;

            while (true)
            {
                if (CoroutineRunnerParallel.IsRunning)
                {
                    try
                    {
                        CoroutineRunnerParallel.Update();
                    }
                    catch (Exception e)
                    {
                        DebugPlugin.LogMsg($"{e.Message}", 100);
                    }
                }
                else
                {
                    await Task.Delay(100);
                }
                parallelFps++;
                if (parallelFps >= Performance.ParallelCoroutineLimit)
                {
                    await Task.Delay(1);

                    DebugInformation["Parallel Coroutine FPS"] = parallelFps;
                    parallelFps = 0;
                }
            }
        }
Esempio n. 2
0
 private void DebugPerformance()
 {
     DebugPlugin.LogInfoMsg($"FPS Infinite While: {Graphics.FpsLoop}");
     DebugPlugin.LogInfoMsg($"FPS Data: {Graphics.FpsData}");
     DebugPlugin.LogInfoMsg($"FPS Render: {Graphics.FpsRender}");
     DebugPlugin.LogInfoMsg($"Thread Sleep: {Graphics.Sleep}");
 }
Esempio n. 3
0
 private void Debug(string message, int time = 1)
 {
     if (_Debug)
     {
         DebugPlugin.LogMsg(message, time);
         File.AppendAllText("Debug.txt", message + Environment.NewLine);
     }
 }
Esempio n. 4
0
 public static void LogMessage(object message, float displayTime, Color color)
 {
     if (message == null)
     {
         DebugPlugin.LogMsg("null", displayTime, color);
     }
     else
     {
         DebugPlugin.LogMsg(message.ToString(), displayTime, color);
     }
 }
        public void Decode(string jsonTree)
        {
            Nodes = new List <SkillNode>();
            var jss = new JsonSerializerSettings
            {
                Error = (sender, args) =>
                {
                    // This one is known: "509":{"x":_,"y":_,"oo":[],"n":[]}} has an Array in "oo".
                    // if (args.ErrorContext.Path != "groups.509.oo")
                    // PoeHUD.Plugins.BasePlugin.LogError("Exception while deserializing Json tree" + args.ErrorContext.Error, 5);
                    if (args.ErrorContext.Path == null || !args.ErrorContext.Path.EndsWith(".oo"))
                    {
                        DebugPlugin.LogMsg("Exception while deserializing Json tree" + args.ErrorContext.Error, 2);
                    }
                    args.ErrorContext.Handled = true;
                }
            };

            SkillTree  = JsonConvert.DeserializeObject <PoESkillTree>(jsonTree, jss);
            Skillnodes = new Dictionary <ushort, SkillNode>();
            NodeGroups = new List <SkillNodeGroup>();
            foreach (var nd in SkillTree.nodes)
            {
                var skillNode = new SkillNode {
                    Id = nd.Value.id, Name = nd.Value.dn, Orbit = nd.Value.o, OrbitIndex = nd.Value.oidx, bJevel = nd.Value.isJewelSocket, bKeyStone = nd.Value.ks, bMastery = nd.Value.m, bMult = nd.Value.isMultipleChoice, bNotable = nd.Value.not, linkedNodes = nd.Value._out
                };
                Nodes.Add(skillNode);
                Skillnodes.Add(nd.Value.id, skillNode);
            }
            NodeGroups = new List <SkillNodeGroup>();
            foreach (var gp in SkillTree.groups)
            {
                var ng = new SkillNodeGroup();
                ng.OcpOrb   = gp.Value.oo;
                ng.Position = new Vector2((float)gp.Value.x, (float)gp.Value.y);
                foreach (var node in gp.Value.n)
                {
                    var nodeToAdd = Skillnodes[node];
                    ng.Nodes.Add(nodeToAdd);
                    nodeToAdd.SkillNodeGroup = ng;
                }

                NodeGroups.Add(ng);
            }
        }
Esempio n. 6
0
        public void WhileLoop()
        {
            Task.Run(ParallelCoroutineRunner);
            DebugInformation["FpsLoop"]             = 0;
            DebugInformation["FpsRender"]           = 0;
            DebugInformation["FpsCoroutine"]        = 0;
            DebugInformation["ElapsedMilliseconds"] = 0;
            var   sw                = Stopwatch.StartNew();
            float nextRenderTick    = sw.ElapsedMilliseconds;
            var   tickEverySecond   = sw.ElapsedMilliseconds;
            var   skipTicksRender   = 0f;
            int   fpsLoop           = 0;
            int   fpsRender         = 0;
            int   fpsCoroutine      = 0;
            float updateRate        = 1f / 60f;
            float loopLimit         = 1;
            int   updateAreaLimit   = 100;
            int   updateEntityLimit = 50;
            int   updateStashTabs   = 500;
            int   updateIngameState = 100;
            int   deltaError        = 500;

            //Pause?resumt coroutines in plugins
            foreach (var setting in pluginsSettings)
            {
                setting.Value.Enable.OnValueChanged += () =>
                {
                    var coroutines = CoroutineRunner.Coroutines.Where(x => x.Owner == setting.Key).Concat(CoroutineRunnerParallel.Coroutines.Where(x => x.Owner == setting.Key)).ToList();
                    foreach (var coroutine in coroutines)
                    {
                        if (setting.Value.Enable)
                        {
                            if (coroutine.AutoResume)
                            {
                                coroutine.Resume();
                            }
                        }
                        else
                        {
                            coroutine.Pause();
                        }
                    }
                };
            }
            void MainCoroutineAction()
            {
                var coroutines = CoroutineRunner.Coroutines.Concat(CoroutineRunnerParallel.Coroutines).ToList();

                if (!InGame || !IsForeGroundCache || IsLoading)
                {
                    Clear.SafeInvoke();
                    foreach (var cor in coroutines)
                    {
                        cor.Pause();
                    }
                    AutoResume = true;
                }
                else
                {
                    if (AutoResume)
                    {
                        foreach (var coroutine in coroutines)
                        {
                            if (pluginsSettings.TryGetValue(coroutine.Owner, out var result))
                            {
                                if (result.Enable && coroutine.AutoResume)
                                {
                                    coroutine.Resume();
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            if (coroutine.AutoResume)
                            {
                                coroutine.Resume();
                            }
                        }
                        AutoResume = false;
                    }
                    foreach (var coroutine in coroutines)
                    {
                        if (pluginsSettings.TryGetValue(coroutine.Owner, out var result) && !result.Enable)
                        {
                            coroutine.Pause();
                        }
                    }
                }
            }

            //Main work for coroutines logic when you not in game
            var updateCoroutine = new Coroutine(MainCoroutineAction, 250, nameof(GameController), "$#Main#$")
            {
                Priority = CoroutinePriority.Critical
            };
            //Coroutine for update area
            var updateArea = (new Coroutine(() => { Area.RefreshState(); }, updateAreaLimit, nameof(GameController), "Update area")
            {
                Priority = CoroutinePriority.High
            });
            //Coroutine for update entity list
            var updateEntity = (new Coroutine(() => { EntityListWrapper.RefreshState(); }, updateEntityLimit, nameof(GameController), "Update Entity")
            {
                Priority = CoroutinePriority.High
            });

            var checkTabs = (new Coroutine(() => { StashController.CheckStashTabsLoop(); }, updateStashTabs, nameof(StashTabController), "Stash Tab Controller")
            {
                Priority = CoroutinePriority.Normal
            });

            //
            //Control cache for game status
            var updateGameState = (new Coroutine(() => {
                InGame = InGameReal;
                IsForeGroundCache = Performance.AlwaysForeground || WinApi.IsForegroundWindow(Window.Process.MainWindowHandle);
                Cache.ForceUpdateWindowCache();
                IsLoading = Game.IsGameLoading;
            }, updateIngameState, nameof(GameController), "Update Game State")
            {
                Priority = CoroutinePriority.Critical
            }).Run();

            //Update coroutine setting when change settings in menu
            if (Performance != null)
            {
                loopLimit         = Performance.LoopLimit;
                skipTicksRender   = 1000f / Performance.RenderLimit;
                Cache.Enable      = Performance.Cache;
                updateAreaLimit   = Performance.UpdateAreaLimit;
                updateEntityLimit = Performance.UpdateEntityDataLimit;
                updateIngameState = Performance.UpdateIngemeStateLimit;
                Performance.UpdateEntityDataLimit.OnValueChanged += () =>
                {
                    CoroutineRunner.Coroutines.Concat(CoroutineRunnerParallel.Coroutines).FirstOrDefault(x => x.Name == "Update Entity")
                    ?.UpdateCondtion(new WaitTime(1000 / Performance.UpdateEntityDataLimit.Value));
                };
                Performance.RenderLimit.OnValueChanged     += () => { skipTicksRender = 1000f / Performance.RenderLimit; };
                Performance.LoopLimit.OnValueChanged       += () => { loopLimit = 300 + Performance.LoopLimit; };
                Performance.UpdateAreaLimit.OnValueChanged += () => { CoroutineRunner.Coroutines.Concat(CoroutineRunnerParallel.Coroutines).FirstOrDefault(x => x.Name == "Update Entity")
                                                                      ?.UpdateCondtion(new WaitTime(Performance.UpdateAreaLimit)); };
                Performance.UpdateIngemeStateLimit.OnValueChanged += () => { CoroutineRunner.Coroutines.Concat(CoroutineRunnerParallel.Coroutines).FirstOrDefault(x => x.Name == "Update Entity")
                                                                             ?.UpdateCondtion(new WaitTime(Performance.UpdateIngemeStateLimit)); };
                Performance.Cache.OnValueChanged         += () => { Cache.Enable = Performance.Cache; };
                Performance.DpsUpdateTime.OnValueChanged += () =>
                {
                    CoroutineRunner.Coroutines.Concat(CoroutineRunnerParallel.Coroutines).FirstOrDefault(x => x.Name == "Calculate DPS")?.UpdateCondtion(new WaitTime(Performance.DpsUpdateTime));
                };
            }
            updateArea.AutoRestart(CoroutineRunner).Run();
            //Update entity list in another thread give more smoothness for ui but need more nullable check
            if (Performance?.ParallelEntityUpdate)
            {
                //Sometimes parallel maybe unstable need testing
                updateEntity.AutoRestart(CoroutineRunnerParallel).RunParallel();
            }
            else
            {
                updateEntity.AutoRestart(CoroutineRunner).Run();
            }
            sw.Restart();
            updateCoroutine.Run();
            checkTabs.Run();
            while (true)
            {
                if (!InGame)
                {
                    Thread.Sleep(50);
                }

                var startFrameTime = sw.Elapsed.TotalMilliseconds;

                for (int j = 0; j < CoroutineRunner.RunPerLoopIter; j++)
                {
                    if (CoroutineRunner.IsRunning)
                    {
                        fpsCoroutine++;
                        try
                        {
                            CoroutineRunner.Update();
                        }
                        catch (Exception e) { DebugPlugin.LogMsg($"Coroutine error: {e.Message}", 1); }
                    }
                }

                if (IsForeGroundLast != IsForeGroundCache)
                {
                    IsForeGroundLast = IsForeGroundCache;
                    eIsForegroundChanged(IsForeGroundCache);
                }
                if (sw.Elapsed.TotalMilliseconds >= nextRenderTick && InGame && IsForeGroundCache && !IsLoading)
                {
                    Render.SafeInvoke();
                    nextRenderTick += skipTicksRender;
                    fpsRender++;
                    RenderCount++;
                    DebugInformation["DeltaRender"] = (float)(sw.Elapsed.TotalMilliseconds - startFrameTime);
                }


                if (sw.ElapsedMilliseconds >= tickEverySecond)
                {
                    DebugInformation["FpsLoop"]        = fpsLoop;
                    DebugInformation["FpsRender"]      = fpsRender;
                    DebugInformation["FpsCoroutine"]   = fpsCoroutine;
                    DebugInformation["Looplimit"]      = loopLimit;
                    DebugInformation["ElapsedSeconds"] = sw.Elapsed.Seconds;
                    DebugInformation["FpsRenderCount"] = RenderCount;
                    fpsLoop          = 0;
                    fpsRender        = 0;
                    fpsCoroutine     = 0;
                    tickEverySecond += 1000;
                    if (nextRenderTick - sw.ElapsedMilliseconds > deltaError || nextRenderTick - sw.ElapsedMilliseconds < deltaError)
                    {
                        nextRenderTick = sw.ElapsedMilliseconds;
                    }
                    //Autorestart coroutines in main thread
                    foreach (var autorestartCoroutine in CoroutineRunner.AutorestartCoroutines)
                    {
                        if (!CoroutineRunner.HasName(autorestartCoroutine.Name))
                        {
                            autorestartCoroutine.GetCopy().Run();
                        }
                    }
                    //Autorestart coroutines in another thread
                    foreach (var autorestartCoroutine in CoroutineRunnerParallel.AutorestartCoroutines)
                    {
                        if (!CoroutineRunnerParallel.HasName(autorestartCoroutine.Name))
                        {
                            autorestartCoroutine.GetCopy().RunParallel();
                        }
                    }
                    Game.RefreshTheGameState();
                }
                fpsLoop++;
                DebugInformation["ElapsedMilliseconds"] = sw.ElapsedMilliseconds;
                DebugInformation["DeltaTimeMs"]         = (float)(sw.Elapsed.TotalMilliseconds - startFrameTime);


                if (fpsLoop >= loopLimit)
                {
                    Thread.Sleep(1);
                }
            }
        }