• Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Help with Code freezing my game client

    Discussion in 'Community Developer Forum' started by Wheredidigo, Jun 16, 2015.

    1. Wheredidigo

      Wheredidigo Community Developer

      Joined:
      Dec 15, 2013
      Messages:
      417
      Likes Received:
      8
      Trophy Points:
      18
      Here is the code that freezes my game client when it gets to it:

      Code:
      using System.Collections.Generic;
      using System.Linq;
      using System.Security.Cryptography.X509Certificates;
      using System.Threading.Tasks;
      using Clio.Utilities;
      using DestinyPlugin.Utilities;
      using ff14bot;
      using ff14bot.BotBases;
      using ff14bot.Helpers;
      using ff14bot.Managers;
      using ff14bot.Navigation;
      using ff14bot.Objects;
      using NeoGaia.ConnectionHandler;
      
      namespace DestinyPlugin.Logic
      {
          internal class Patrol : LogicBase
          {
              #region BaseClass Implementation
      
              protected override bool NeedToStart
              {
                  get
                  {
                      return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" &&
                             !FatesAreAvailable() &&
                             PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null;
                  }
              }
      
              protected override async Task<bool> Start()
              {
                  Logger.Log("No Fates within the current settings are available. Starting to Patrol now.");
                  var target = FindTarget();
                  
                  if (Poi.Current.Type != PoiType.Kill)
                  {
                      Poi.Clear("Clearing Poi so we can find and kill a new target.");
                      Poi.Current = new Poi(target, PoiType.Kill);
                  }
                  if (Poi.Current.BattleCharacter != null)
                  {
                      if (Poi.Current.BattleCharacter.ObjectId != target.ObjectId)
                      {
                          Poi.Current = new Poi(target, PoiType.Kill);
                      }
                  }
                  while (Core.Me.Distance(target.Location) > RoutineManager.Current.PullRange + target.CombatReach + Core.Me.CombatReach)
                  {
                      Navigator.MoveTo(target.Location);
                      await CarefulSleep.Sleep(500);
                  }
      
                  if (Core.Me.Distance(target.Location) < 15f)
                  {
                      target.Target();
                  }
                  return true;
              }
      
              #endregion
      
              #region Helpers
      
              private static bool FatesAreAvailable()
              {
                  var activeFates =
                      FateManager.ActiveFates.Where(
                          x =>
                              x.Level >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) &&
                              x.Level <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) &&
                              !FatebotSettings.Instance.BlackListedFates.Contains(x.Name)
                              ).ToList();
                  var monsterSlayingFates = new List<FateData>();
                  var bossFates = new List<FateData>();
                  var escortFates = new List<FateData>();
      
                  if (Settings.Instance.MonsterSlayingEnabled)
                  {
                      monsterSlayingFates = activeFates.Where(x => x.IsValid && x.Icon == FateIconType.Battle).ToList();
                  }
                  if (Settings.Instance.BossEnabled)
                  {
                      bossFates =
                          activeFates.Where(
                              x =>
                                  x.IsValid && x.Icon == FateIconType.Boss &&
                                  x.Progress >= Settings.Instance.BossPercentRequired).ToList();
                  }
                  if (Settings.Instance.EscortEnabled)
                  {
                      escortFates =
                          activeFates.Where(
                              x => x.IsValid && (x.Icon == FateIconType.ProtectNPC || x.Icon == FateIconType.ProtectNPC2))
                              .ToList();
                  }
      
                  var availableFates = monsterSlayingFates.Union(bossFates.Union(escortFates));
      
                  return availableFates.Any();
              }
      
              private static BattleCharacter FindTarget()
              {
                  return GameObjectManager.GetObjectsOfType<BattleCharacter>()
                      .Where(x => !Settings.Instance.BlackListMobNames.Contains(x.EnglishName)
                                  && x.CanAttack
                                  && !x.IsDead
                                  && x.IsTargetable
                                  && x.IsVisible
                                  && !x.TappedByOther
                                  && x.FateId == 0
                                  && x.ClassLevel >= (Core.Me.ClassLevel - Settings.Instance.MinLevel)
                                  && x.ClassLevel <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel)
                                  && x.MaxHealth < (Core.Player.MaxHealth*5))
                      .OrderBy(x => Core.Me.Distance(x.Location))
                      .FirstOrDefault();
              }
      
              private static bool PatrolTargetAvailable
              {
                  get
                  {
                      var target = FindTarget();
                      return target != null;
                  }
              }
      
              #endregion
          }
      }
      
      Any help figuring out why it's freezing my client would be greatly appreciated.
       
    2. Cloud30000

      Cloud30000 New Member

      Joined:
      May 9, 2015
      Messages:
      298
      Likes Received:
      7
      Trophy Points:
      0
      I thought

      Code:
                      return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" &&
                             !FatesAreAvailable() &&
                             PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null;
      needs to be

      Code:
                      return Core.Me.IsAlive && Settings.Instance.Patrol && (BotManager.Current.EnglishName == "Fate Bot") &&
                             !FatesAreAvailable() &&
                             PatrolTargetAvailable && !Core.Me.InCombat && (Core.Me.CurrentTarget == null);
      to contain the comparison operators in the same statement with the logical operators.

      EDIT: Never mind, the compiler can parse and order them automatically these days.
       
      Last edited: Jun 16, 2015
    3. Wheredidigo

      Wheredidigo Community Developer

      Joined:
      Dec 15, 2013
      Messages:
      417
      Likes Received:
      8
      Trophy Points:
      18
      So, I just removed the movement code and am just letting FateBot handle moving to the new Poi....

      This seems to be working:

      Code:
      using System.Collections.Generic;
      using System.Linq;
      using System.Security.Cryptography.X509Certificates;
      using System.Threading.Tasks;
      using Clio.Utilities;
      using DestinyPlugin.Utilities;
      using ff14bot;
      using ff14bot.BotBases;
      using ff14bot.Helpers;
      using ff14bot.Managers;
      using ff14bot.Navigation;
      using ff14bot.Objects;
      using NeoGaia.ConnectionHandler;
      
      namespace DestinyPlugin.Logic
      {
          internal class Patrol : LogicBase
          {
              #region BaseClass Implementation
      
              protected override bool NeedToStart
              {
                  get
                  {
                      return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" &&
                             !FatesAreAvailable() &&
                             PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null;
                  }
              }
      
              protected override async Task<bool> Start()
              {
                  Logger.Log("No Fates within the current settings are available. Starting to Patrol now.");
                  var target = FindTarget();
                  await CarefulSleep.Sleep(100);
                  if (Poi.Current.Type != PoiType.Kill)
                  {
                      Poi.Clear("Clearing Poi so we can find and kill a new target.");
                      Poi.Current = new Poi(target, PoiType.Kill);
                  }
      
                  if (Poi.Current.BattleCharacter != null)
                  {
                      if (Poi.Current.BattleCharacter.ObjectId != target.ObjectId)
                      {
                          Poi.Current = new Poi(target, PoiType.Kill);
                      }
                  }
                  
                  if (Core.Me.Distance(target.Location) < 15f)
                  {
                      target.Target();
                  }
                  else
                  {
                      return false;
                  }
                  return true;
              }
      
              #endregion
      
              #region Helpers
      
              private static bool FatesAreAvailable()
              {
                  var activeFates =
                      FateManager.ActiveFates.Where(
                          x =>
                              x.Level >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) &&
                              x.Level <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) &&
                              !FatebotSettings.Instance.BlackListedFates.Contains(x.Name)
                              ).ToList();
                  var monsterSlayingFates = new List<FateData>();
                  var bossFates = new List<FateData>();
                  var escortFates = new List<FateData>();
      
                  if (Settings.Instance.MonsterSlayingEnabled)
                  {
                      monsterSlayingFates = activeFates.Where(x => x.IsValid && x.Icon == FateIconType.Battle).ToList();
                  }
                  if (Settings.Instance.BossEnabled)
                  {
                      bossFates =
                          activeFates.Where(
                              x =>
                                  x.IsValid && x.Icon == FateIconType.Boss &&
                                  x.Progress >= Settings.Instance.BossPercentRequired).ToList();
                  }
                  if (Settings.Instance.EscortEnabled)
                  {
                      escortFates =
                          activeFates.Where(
                              x => x.IsValid && (x.Icon == FateIconType.ProtectNPC || x.Icon == FateIconType.ProtectNPC2))
                              .ToList();
                  }
      
                  var availableFates = monsterSlayingFates.Union(bossFates.Union(escortFates));
      
                  return availableFates.Any();
              }
      
              private static BattleCharacter FindTarget()
              {
                  return GameObjectManager.GetObjectsOfType<BattleCharacter>()
                      .Where(x => !Settings.Instance.BlackListMobNames.Contains(x.EnglishName)
                                  && x.CanAttack
                                  && !x.IsDead
                                  && x.IsTargetable
                                  && x.IsVisible
                                  && !x.TappedByOther
                                  && x.FateId == 0
                                  && x.ClassLevel >= (Core.Me.ClassLevel - Settings.Instance.MinLevel)
                                  && x.ClassLevel <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel)
                                  && x.MaxHealth < (Core.Player.MaxHealth*5))
                      .OrderBy(x => Core.Me.Distance(x.Location))
                      .FirstOrDefault();
              }
      
              private static bool PatrolTargetAvailable
              {
                  get
                  {
                      var target = FindTarget();
                      return target != null;
                  }
              }
      
              #endregion
          }
      }
      
       
    4. Cloud30000

      Cloud30000 New Member

      Joined:
      May 9, 2015
      Messages:
      298
      Likes Received:
      7
      Trophy Points:
      0
      If you remove the loop that pauses the function while moving to the target, doesn't that now cause it to stop targeting any mobs that are outside the '15' range? Or will the Fatebot bypass that portion and target them anyway due to the PoiType.Kill command?
       
    5. Wheredidigo

      Wheredidigo Community Developer

      Joined:
      Dec 15, 2013
      Messages:
      417
      Likes Received:
      8
      Trophy Points:
      18
      Basically, right now, on the first tick, I will find a target and set it as my Poi. If I'm also within the 15 yalm range, then I'll target the mob, and that will cause the Patrol Logic to stop being pulsed because the decorator won't be true anymore because of the Core.Me.CurrentTarget == null portion of the NeedToStart boolean. If I'm more than 15 yalm away, then the Start method will keep getting run on each tick, and because it will already have a PoiType.Kill, it will bypass those checks and go right to the range check. If it's not within the 15 yalm range, it will just return false which tells the CoRoutine that it didn't finish successfully and it needs to keep it at this status.

      Setting the Poi will make FateBot handle the movement to the mob, and once I'm in range to target it, FateBot just handles the rest.
       
    6. Mirabis

      Mirabis Community Developer

      Joined:
      Jun 14, 2010
      Messages:
      4,475
      Likes Received:
      86
      Trophy Points:
      48
      Code:
          while (Core.Me.Distance(target.Location) > RoutineManager.Current.PullRange + target.CombatReach + Core.Me.CombatReach)
                  {
                      Navigator.MoveTo(target.Location);
                      await CarefulSleep.Sleep(500);
                  }
      
      Seems troublesome, and u should handle it as u already did above ( return tick when out of range).
       
    7. Wheredidigo

      Wheredidigo Community Developer

      Joined:
      Dec 15, 2013
      Messages:
      417
      Likes Received:
      8
      Trophy Points:
      18
      What are you doing poking around the RB forums!! =)

      Thanks for the input. You're correct in that part being bad. Once I removed that code, my client stopped freezing.

      Glad to see you over in RB's neck of the woods. I know the 6 month ban hurt a lot of WoW player's, but it's brought a lot of new life to RB!
       
    8. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      5,343
      Likes Received:
      383
      Trophy Points:
      83
      await CarefulSleep.Sleep(500);
      What ever this is its probably bad.

      If your using a while loop your pretty much have to have a coroutine.yield in it as the last statement.

      Edit:

      Yea. Whatever this "CarefulSleep" is needs to replaced.

      If you need to sleep for a specifc amount of time then you should be using

      await Coroutine.Sleep(1000);

      If you want to sleep until a condition becomes true/false then you should be using

      await Coroutine.Wait(Timeout.Infinite, () => HousingMyChocobo.IsOpen);

      or

      await Coroutine.Wait(5000, () => HousingMyChocobo.IsOpen);

      If you are doing work inside a while loop:

      while(dosomething)
      {
      dostuff();
      await Coroutine.Yield();
      }
       
    9. Cloud30000

      Cloud30000 New Member

      Joined:
      May 9, 2015
      Messages:
      298
      Likes Received:
      7
      Trophy Points:
      0
      In the official Destiny V2 plugin, CarefulSleep is a function which calls Coroutine.Yield until the supplied millisecond count has expired:
      Code:
              private static async Task<bool> CarefulSleep(uint ms)
              {
                  var stopwatch = new Stopwatch();
                  stopwatch.Start();
      
                  while (stopwatch.ElapsedMilliseconds < ms && CanTeleport)
                  {
                      await Coroutine.Yield();
                  }
                  stopwatch.Stop();
      
                  return CanTeleport;
              }
      I'm not sure what has changed in the new unreleased Destiny code, but that function does not cause any crashing issues and seems to currently work with Destiny.
       
    10. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      5,343
      Likes Received:
      383
      Trophy Points:
      83
      Yea....thats pretty bad. Absolutely no reason for that function.
       
    11. Wheredidigo

      Wheredidigo Community Developer

      Joined:
      Dec 15, 2013
      Messages:
      417
      Likes Received:
      8
      Trophy Points:
      18
      The CarefulSleep method works beautifully and does exactly what I want it to do. Mastahg is correct that we don't need that method and that there are built in ways to do it which he has provided examples of.

      Regardless, I've fixed the issue I was having and thank everyone for their input on the topic. Feel free to lock this thread now as there's no more responses needed.
       

    Share This Page