Jump to content

Droidz

Administrators
  • Posts

    12514
  • Joined

  • Last visited

Everything posted by Droidz

  1. Hi, Now WRobot should work in the dungeons, but no official Donjon bot, you can use Grinder bot (you can get problem to retrieve corpse, don't works on all donjon yet).
  2. Hello, Not WoD profiles right now, you can use "Automaton", or you can try to create your own profile (it is very easy and quickly). And not crash problem signaled, please create new post with log and more details.
  3. After WoWPlayer unit = getTankList().Where(o => o.IsAlive && o.IsValid && !TraceLine.TraceLineGo(o.Position)).OrderBy(o => o.GetDistance).FirstOrDefault(); add if (unit == null || !unit.IsValid) return false; your fonction "public bool IsTank(WoWPlayer unit)" is not good, try this: bool IsTank(string name) { var lua = new[] { "partyTank = \"\";", "for groupindex = 1,MAX_PARTY_MEMBERS do", " if (UnitInParty(\"party\" .. groupindex)) then", " local role = UnitGroupRolesAssigned(\"party\" .. groupindex);", " if role == \"TANK\" then", " local name, realm = UnitName(\"party\" .. groupindex);", " if name == \"" + name + "\" then", " partyTank = \"yes\";", " return;", " end", " end", " end", "end", }; return Lua.LuaDoString(lua, "partyTank") == "yes"; }
  4. If you can try it: using System; using System.IO; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using robotManager; using robotManager.FiniteStateMachine; using robotManager.Helpful; using wManager.Wow.Class; using wManager.Wow.Enums; using wManager.Wow.Helpers; using wManager.Wow.ObjectManager; using Timer = robotManager.Helpful.Timer; public class Main : ICustomClass { private DruidResto _druid; public float Range { get { return 39.0f; } } public void Initialize() { _druid = new DruidResto(); _druid.Pulse(); } public void Dispose() { _druid.Stop(); } public void ShowConfiguration() { MessageBox.Show("No settings for this FightClass."); } class DruidResto { // Property: private bool _isLaunched; public bool IsLaunched { get { return _isLaunched; } set { _isLaunched = value; } } // Spells: private Spell _regrowth; private Spell _wildgrowth; private Spell _healingtouch; private Spell _rejuvenation; private Spell _tranquility; private Spell _swiftmend; private Spell _wildmushroom; private Spell _genesis; private Spell _typhoon; private Spell _incapacitatingroar; private Spell _rebirth; private Spell _naturesvigil; private Spell _naturesSwiftness; private Spell _lifebloom; private Spell _clearcasting; private Spell _ironbark; private Spell _barkskin; private Spell _forceofnature; public DruidResto() { _regrowth = new Spell("Regrowth"); _wildgrowth = new Spell("Wild Growth"); _healingtouch = new Spell("Healing Touch"); _rejuvenation = new Spell("Rejuvenation"); _tranquility = new Spell("Tranquility"); _swiftmend = new Spell("Swiftmend"); _wildmushroom = new Spell("Wild Mushroom"); _genesis = new Spell("Genesis"); _typhoon = new Spell("Typhoon"); _incapacitatingroar = new Spell("Incapacitating Roar"); _rebirth = new Spell("Rebirth"); _naturesvigil = new Spell("Nature's Vigil"); _naturesSwiftness = new Spell("Nature's Swiftness"); _lifebloom = new Spell("Lifebloom"); _clearcasting = new Spell("Clearcasting"); _ironbark = new Spell("Iron Bark"); _barkskin = new Spell("Barkskin"); _forceofnature = new Spell("Force of Nature"); } public void Pulse() { _isLaunched = true; var thread = new Thread(RoutineThread) { Name = "Restoration Druid FightClass" }; thread.Start(); } public void Stop() { _isLaunched = false; Logging.WriteFight("Stop 'Restoration Druid'"); } void RoutineThread() { Logging.WriteFight("'Restoration Druid' Started"); while (_isLaunched) { Routine(); Thread.Sleep(10); // Temps d'attante pour éviter d'utiliser trop le processeurs } Logging.WriteFight("'Restoration Druid' Stopped"); } void Routine() { if (!Conditions.InGameAndConnectedAndAlive) return; if (Lifebloom()) return; if (WildMushroom()) return; } IEnumerable<WoWUnit> GetPartyTargets() { var partyMembers = Party.GetPartyHomeAndInstance(); var ret = new List<WoWUnit>(); foreach (var m in partyMembers) { if (m.IsValid && m.IsAlive && m.InCombat && m.Target.IsNotZero()) { var targetUnit = new WoWUnit(ObjectManager.GetObjectByGuid(m.Target).GetBaseAddress); if (targetUnit.IsValid && targetUnit.IsAlive) { ret.Add(targetUnit); } } } return ret.Distinct(); } private List<WoWPlayer> GetPartyMembers(int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true) { return GetPartyMembers(ObjectManager.Me.Position, maxHealthPercent, maxDistance, orderByHealth); } private List<WoWPlayer> GetPartyMembers(Vector3 positionCenter, int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true) { var partyMembers = Party.GetPartyHomeAndInstance(); var ret = new List<WoWPlayer>(); foreach (var m in partyMembers) { if (m.IsValid && m.IsAlive && m.HealthPercent < maxHealthPercent && m.Position.DistanceTo(positionCenter) <= maxDistance) { ret.Add(m); } } if (orderByHealth) ret = new List<WoWPlayer>(ret.OrderBy(p => p.HealthPercent)); return ret; } string GetTankPlayerName() { var lua = new[] { "partyTank = \"\";", "for groupindex = 1,MAX_PARTY_MEMBERS do", " if (UnitInParty(\"party\" .. groupindex)) then", " local role = UnitGroupRolesAssigned(\"party\" .. groupindex);", " if role == \"TANK\" then", " local name, realm = UnitName(\"party\" .. groupindex);", " partyTank = name;", " return;", " end", " end", "end", }; return Lua.LuaDoString(lua, "partyTank"); } WoWPlayer GetTankPlayer() { var p = new WoWPlayer(0); var playerName = GetTankPlayerName(); if (!string.IsNullOrWhiteSpace(playerName)) { playerName = playerName.ToLower().Trim(); var party = GetPartyMembers().OrderBy(o => o.GetDistance); foreach (var woWPlayer in party) { if (woWPlayer.Name.ToLower() == playerName) { p = new WoWPlayer(woWPlayer.GetBaseAddress); break; } } } if (string.IsNullOrWhiteSpace(playerName)) { p = new WoWPlayer(ObjectManager.Me.GetBaseAddress); } return p; } bool BaseHealSpell(Spell spell, int maxHealthPercent, float maxDistance) { if (!spell.KnownSpell) return false; if (!spell.IsSpellUsable) return false; var partyMembers = GetPartyMembers(); foreach (var partyMember in partyMembers) { if (!TraceLine.TraceLineGo(partyMember.Position)) // TraceLine permet de vérifier un obstacle entre deux position (true si obstacle) { Interact.InteractGameObject(partyMember.GetBaseAddress, true); // sélectionne la cible in game //MovementManager.Face(partyMember); // Faire face à la cible spell.Launch(); return true; } } return false; } bool Lifebloom() { if (!_lifebloom.KnownSpell) return false; if (!_lifebloom.IsSpellUsable) return false; var partyMember = GetTankPlayer(); if (partyMember.IsValid && partyMember.GetDistance <= 40 && partyMember.IsAlive && partyMember.HealthPercent > 0 && !partyMember.HaveBuff("Lifebloom") && !TraceLine.TraceLineGo(partyMember.Position)) { Interact.InteractGameObject(partyMember.GetBaseAddress, true); // sélectionne la cible in game //MovementManager.Face(partyMembers); // Faire face à la cible _lifebloom.Launch(); // Lancer le sort return true; } return false; } private Timer _mushroomTime = new Timer(-1); private uint _wildMushroomID = 145205; bool WildMushroom() { if (!_mushroomTime.IsReady) // If timer finish (29 sec) { Logging.WriteDebug("WildMushroom > !_mushroomTime.IsReady"); return false; } if (!_wildmushroom.KnownSpell) { Logging.WriteDebug("WildMushroom > !_wildmushroom.KnownSpell"); return false; } if (!_wildmushroom.IsSpellUsable) { Logging.WriteDebug("WildMushroom > !_wildmushroom.IsSpellUsable"); return false; } var partyMember = GetTankPlayer(); if (partyMember.IsValid && // Check if an tank player has found partyMember.IsAlive && // Check if is alive partyMember.GetDistance <= 40 && // check distance !TraceLine.TraceLineGo(partyMember.Position)) // lign of sight { Interact.InteractGameObject(partyMember.GetBaseAddress, true); //select target SpellManager.CastSpellByIDAndPosition(_wildMushroomID, partyMember.Position); // you can also use "_wildmushroom.Id" to get spell id _mushroomTime = new Timer(29 * 1000); // 29 sec return true; } Logging.WriteDebug( "WildMushroom > partyMember.IsValid=" + partyMember.IsValid + " partyMember.IsAlive=" + partyMember.IsAlive + " partyMember.GetDistance=" + (partyMember.GetDistance) + " TraceLine.TraceLineGo(partyMember.Position)=" + TraceLine.TraceLineGo(partyMember.Position)); return false; } } } ps: I have added debug info in method "WildMushroom()" (Logging.WriteDebug(...)) to help you to found problem, remove it when this works.
  5. Droidz

    Gatether

    Bonjour, Actuellement il n'y à pas d'option, la seule solution est d'enregistrer un chemin avec des points proche les uns des autres. Mais je vais améliorer le retour au chemin du profil dans les prochaines mises à jour.
  6. Droidz

    WOD

    Bonjour. Pour ce qui est des classes de combat (Fightclasses) je ne pense pas qu'il y est de problème le jour de la sortie. Pour les profils du bot Grinder c'est relativement facile et rapide à faire (au pire il y a le bot "Automaton"), je pense qu'il devrait y en avoir rapidement des profils disponibles. Pour les profils de quêtes, ce sera beaucoup plus long (ça demande beaucoup plus de travails).
  7. Please send me your code/fightclass if you want best reply. I have written this for help an member to create an heal fightclass (not tested, it is sample code): using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Windows.Forms; using robotManager.Helpful; using wManager.Wow.Class; using wManager.Wow.Enums; using wManager.Wow.Helpers; using wManager.Wow.ObjectManager; public class Main : ICustomClass { private HolyPaladin _holyPaladin; public float Range { get { return 29.0f; } } public void Initialize() { _holyPaladin = new HolyPaladin(); _holyPaladin.Pulse(); } public void Dispose() { _holyPaladin.Stop(); } public void ShowConfiguration() { MessageBox.Show("No settings for this FightClass."); } } class HolyPaladin { // Property: private bool _isLaunched; public bool IsLaunched { get { return _isLaunched; } set { _isLaunched = value; } } // Spells: private Spell _judgment; private Spell _flashOfLight; private Spell _lightOfDawn; private Spell _avengingWrath; private Spell _handOfProtection; private Spell _divineShield; private Spell _layOnHands; private Spell _holyShock; private Spell _holyRadiance; public HolyPaladin() { // Init spells: _judgment = new Spell("Judgment"); _flashOfLight = new Spell("Flash of Light"); _lightOfDawn = new Spell("Light of Dawn"); _avengingWrath = new Spell("Avenging Wrath"); _handOfProtection = new Spell("Hand of Protection"); _divineShield = new Spell("Divine Shield"); _layOnHands = new Spell("Lay On Hands"); _holyShock = new Spell("Holy Shock"); _holyRadiance = new Spell("Holy Radiance"); Logging.WriteFight("'Holy Paladin' by AudreyH loaded"); } public void Pulse() { _isLaunched = true; var thread = new Thread(RoutineThread) { Name = "HolyPaladin_FightClass" }; thread.Start(); } public void Stop() { _isLaunched = false; Logging.WriteFight("Stop 'Holy Paladin'"); } void RoutineThread() { Logging.WriteFight("'Holy Paladin' Started"); while (_isLaunched) { Routine(); Thread.Sleep(10); // Temps d'attante pour éviter d'utiliser trop le processeurs } Logging.WriteFight("'Holy Paladin' Stopped"); } void Routine() { if (!Conditions.InGameAndConnectedAndAlive) return; // Ranger par ordre de priorité if (Judgment()) return; if (HolyRadiance()) return; if (FlashOfLight()) return; if (LightOfDawn()) return; if (AvengingWrath()) return; if (HandOfProtection()) return; if (DivineShield()) return; if (LayOnHands()) return; if (HolyShock()) return; } // Usefuls methods List<WoWUnit> GetPartyTargets() { var partyMembers = Party.GetPartyHomeAndInstance(); var ret = new List<WoWUnit>(); foreach (var m in partyMembers) { if (m.IsValid && m.IsAlive && m.InCombat && m.Target.IsNotZero()) { if (ret.All(u => u.Guid != m.Target)) // Evite doublon dans la liste retournée { var targetUnit = new WoWUnit(ObjectManager.GetObjectByGuid(m.Target).GetBaseAddress); if (targetUnit.IsValid && targetUnit.IsAlive) { ret.Add(targetUnit); } } } } return ret; } private List<WoWPlayer> GetPartyMembers(int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true) { return GetPartyMembers(ObjectManager.Me.Position, maxHealthPercent, maxDistance, orderByHealth); } private List<WoWPlayer> GetPartyMembers(Vector3 positionCenter, int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true) { var partyMembers = Party.GetPartyHomeAndInstance(); var ret = new List<WoWPlayer>(); foreach (var m in partyMembers) { if (m.IsValid && m.IsAlive && m.HealthPercent < maxHealthPercent && m.Position.DistanceTo(positionCenter) <= maxDistance) { ret.Add(m); } } if (orderByHealth) ret = new List<WoWPlayer>(ret.OrderBy(p => p.HealthPercent)); return ret; } string GetTankPlayerName() { var lua = new[] { "partyTank = \"\";", "for groupindex = 1,MAX_PARTY_MEMBERS do", " if (UnitInParty(\"party\" .. groupindex)) then", " local role = UnitGroupRolesAssigned(\"party\" .. groupindex);", " if role == \"TANK\" then", " local name, realm = UnitName(\"party\" .. groupindex);", " partyTank = name;", " return;", " end", " end", "end", }; return Lua.LuaDoString(lua, "partyTank"); } WoWPlayer GetTankPlayer() { var p = new WoWPlayer(0); var playerName = GetTankPlayerName(); if (!string.IsNullOrWhiteSpace(playerName)) { playerName = playerName.ToLower().Trim(); var party = GetPartyMembers(); foreach (var woWPlayer in party) { if (woWPlayer.Name.ToLower() == playerName) { p = new WoWPlayer(woWPlayer.GetBaseAddress); break; } } } return p; } // Spells methods bool Judgment() { if (!_judgment.KnownSpell) return false; if (!_judgment.IsSpellUsable) return false; var partyTargets = GetPartyTargets(); // Recupère les cibles des joueurs du groupe. foreach (var target in partyTargets) // On recherche dans la liste { if (target.IsValid && target.IsAlive) // Verif si target valid et en vie { if (target.GetDistance < _judgment.MaxRange) // Verif si bonne distance { if (!TraceLine.TraceLineGo(target.Position)) // TraceLine permet de vérifier un obstacle entre deux position (true si obstacle) { if (UnitCanAttack.CanAttack(target.GetBaseAddress)) // On peut attaquer la cible { Interact.InteractGameObject(target.GetBaseAddress, true); // sélectionne la cible in game MovementManager.Face(target); // Faire face à la cible _judgment.Launch(); // Lancer le sort return true; } } } } } return false; } bool BaseHealSpell(Spell spell, int maxHealthPercent, float maxDistance) { if (!spell.KnownSpell) return false; if (!spell.IsSpellUsable) return false; var partyMembers = GetPartyMembers(maxHealthPercent, maxDistance); foreach (var partyMember in partyMembers) { if (!TraceLine.TraceLineGo(partyMember.Position)) // TraceLine permet de vérifier un obstacle entre deux position (true si obstacle) { Interact.InteractGameObject(partyMember.GetBaseAddress, true); // sélectionne la cible in game MovementManager.Face(partyMember); // Faire face à la cible spell.Launch(); // Lancer le sort return true; } } return false; } bool FlashOfLight() { return BaseHealSpell(_flashOfLight, 90, 40); } bool LightOfDawn() { if (!_lightOfDawn.KnownSpell) return false; if (!_lightOfDawn.IsSpellUsable) return false; if (ObjectManager.Me.GetPowerByPowerType(PowerType.HolyPower) < 3) return false; var partyMembers = GetPartyMembers(90, 30); if (partyMembers.Count >= 3) // Si minimum 3 alliés dans les 30 mètres avec moins de 90% de vie { _lightOfDawn.Launch(); // Lancer le sort return true; } return false; } bool AvengingWrath() { if (!_avengingWrath.KnownSpell) return false; if (!_avengingWrath.IsSpellUsable) return false; var partyTargets = GetPartyTargets(); // Recupère les cibles des joueurs du groupe. if (partyTargets.Count > 0 || ObjectManager.Me.InCombat) // Si un des joueurs ou moi en combat { _avengingWrath.Launch(); // Lancer le sort return true; } return false; } bool HandOfProtection() { if (!_handOfProtection.KnownSpell) return false; if (!_handOfProtection.IsSpellUsable) return false; if (ObjectManager.Me.InCombat && ObjectManager.Me.HealthPercent <= 20) // Si en combat et moins de 20% de vie { _handOfProtection.Launch(false, true, false, true); // Lancer le sort OnSelf return true; } return false; } bool DivineShield() { if (!_divineShield.KnownSpell) return false; if (!_divineShield.IsSpellUsable) return false; if (ObjectManager.Me.InCombat) // Si en combat { _divineShield.Launch(); // Lancer le sort return true; } return false; } bool LayOnHands() { if (!_layOnHands.KnownSpell) return false; if (!_layOnHands.IsSpellUsable) return false; if (ObjectManager.Me.HealthPercent <= 20)// Si moins de 20% de vie { _layOnHands.Launch(false, true, false, true); // Lancer le sort OnSelf return true; } return false; } bool HolyShock() { if (ObjectManager.Me.InCombat) return BaseHealSpell(_holyShock, 95, 40); return false; } bool HolyRadiance() { if (!_holyRadiance.KnownSpell) return false; if (!_holyRadiance.IsSpellUsable) return false; var partyMembers = GetPartyMembers(90, 40); // On recupere les membres du groupe avec moins de 90% de vie à 40 metres var bestPlayer = new WoWPlayer(0); // Le meilleur joueur pour recevoir le sort int bestHealthMissing = 0; // Score (plus le score est haut mieux c'est, ce score et le nombre de pourcentages de vie qui manque aux joueurs qui ce trouve dans les 10 metres du joueur bestPlayer) foreach (var partyMember in partyMembers) // On va rechercher le meilleur joueur { if (partyMember.IsValid && partyMember.IsAlive && !TraceLine.TraceLineGo(partyMember.Position)) { var partyMembersNearPartyPlayer = GetPartyMembers(partyMember.Position, 95, 10); // La on recherche les joueurs proches de partyMember qui ce trouve à 10 metres (porté du sort) (retourne également partyMember dans le résultat) if (partyMembersNearPartyPlayer.Count > 2) // Si ils sont minimum 2 joueurs dans les 10 metres { int healthMissing = 0; foreach (var p in partyMembersNearPartyPlayer) { if (p.IsValid && p.IsAlive) { healthMissing = healthMissing + (100 - (int)p.HealthPercent); } } if (healthMissing > bestHealthMissing) { // Si il manque plus de vie ici alors on le désigne comme le meilleur choix bestPlayer = new WoWPlayer(partyMember.GetBaseAddress); bestHealthMissing = healthMissing; } } } } // Si bestPlayer trouvé if (bestHealthMissing > 0 && bestPlayer.IsValid) { Interact.InteractGameObject(bestPlayer.GetBaseAddress, true); // sélectionne la cible in game MovementManager.Face(bestPlayer); // Faire face à la cible _holyRadiance.Launch(); // Lancer le sort return true; } return false; } }
  8. Hello, I am not sure to understand exactly what you want, but use List<Object> is not good way. If you want create list that containts players and npcs use this (List<WowUnit>): public static List<WoWUnit> GetElitesNpcAndHostilesPlayers() { List<WoWUnit> listNpcResult = new List<WoWUnit>(); List<WoWUnit> allNpc = ObjectManager.GetObjectWoWUnit(); foreach (var npc in allNpc) { if (npc.IsValid && npc.IsAlive && npc.IsElite && npc.Reaction <= Reaction.Unfriendly) listNpcResult.Add(npc); } List<WoWPlayer> allPlayers = ObjectManager.GetObjectWoWPlayer(); foreach (var player in allPlayers) { if (player.IsValid && player.IsAlive && player.PlayerFaction != ObjectManager.Me.PlayerFaction) listNpcResult.Add(player); } return listNpcResult; } If you want create an list with only wow players use this (List<WoWPlayer>): public static List<WoWPlayer> GetFriendlyPlayersAndMe() { List<WoWPlayer> listPlayersResult = new List<WoWPlayer>(); List<WoWPlayer> allPlayers = ObjectManager.GetObjectWoWPlayer(); foreach (var player in allPlayers) { if (player.IsValid && player.IsAlive && player.PlayerFaction == ObjectManager.Me.PlayerFaction) listPlayersResult.Add(player); } listPlayersResult.Add(ObjectManager.Me); // Add your character return listPlayersResult; } WowUnit class is the base class of WowPlayer ( WowObject < WowUnit < WowPlayer ). Do not hesitate if you have others questions.
  9. Hello, Make all steps of this page (and if installed, reinstall framework, vc++ and slimdx) and activate option "Use lua to move" in General Settings advanced .
  10. Droidz

    getting stuck

    Can you send me the profile please
  11. Hello, I get same problem that you if I select country Canada. I have signaled problem at IPBoard. Thank you for report.
  12. Hello, I changed the prices: http://wrobot.eu/page/articles.html/_/news/price-and-trial-time-change-r70, it is normal, for a one session license key, it is 19.99€ for lifetime.
  13. Hello, In the Gatherer "Product Settings" deactivate option "Using flying mount all time". In "Advanced General Settings" tab "Mount..." increment the option "Mount Distance". And you cannot farm mine/herb without dismount (except druid if I'm not mistaken). Tell me if this resolved your problem.
  14. You have problem on your installation (System.ComponentModel.Win32Exception (0x80004005): Invalid window handle) Make all steps of this page if installed, reinstall framework, vc++ and slimdx) and activate option "Use lua to move" in General Settings advanced . Tell me when is done, if your problem is not resolved please send me again the log of new bugged session.
  15. Droidz

    3 day test subscription

    Hello, I have added free days of subscription at your account (http://wrobot.eu/index.php?app=nexus&module=clients&section=purchases ). He has already a free trial version, but make a 3 days trial version can be a best way to test WRobot than free trial of 15 minutes by session (I'll think about it).
  16. Hello, If you have position where you are stuck. You can disable option "Avoid wall" in advanced general settings tab "Others".
  17. Hello, Blacklist zones it is the good way, you can use tab "Map" or "3D radar" to check if the blacklisted zones are good sizes and positions. (check also in advanced general settings tab looting... if option "Detect nodes stuck" is activated). What bot do you use (Gatherer, grinder)?
  18. Hello, Do you have try to activate option "Start fighting with Elite" in advanced general settings?
  19. Hello, I have updated your current licence key to a lifetime licence key for free (you have already buy a lot of monthly renewals, thank you for the interest you have shown at WRobot).
  20. Droidz

    Error System.Char[]

    Problem is now resolved. Update WRobot for fix it.
  21. Droidz

    Error System.Char[]

    Hello, Can you share full log file please. This error causing bugs? Thank you
  22. Hello, I have changed price and trial time. Now the time limit for trial version is at 15 minutes (30 min before). For the price: WRobot one session: 5.99€ 4.50€ Monthly 15.00€ every 6 months 19.99€ 24.98€ lifetime WRobot unlimited session by ip : 29.99€ Annually 39.99€ lifetime Best regards, MmoRobot team.
  23. Hello, I have changed price and trial time. Now the time limit for trial version is at 15 minutes (30 min before). For the price: WRobot one session: 5.99€ 4.50€ Monthly 15.00€ every 6 months 19.99€ 24.98€ lifetime WRobot unlimited session by ip : 29.99€ Annually 39.99€ lifetime Best regards, MmoRobot team.
  24. Hello, The last Wow patch (6.0.3 19116) is now supported by WRobot . Best regards, Droidz.
×
×
  • Create New...