• Visit Rebornbuddy
  • ExilebuddyBeta Developers Testing/Feedback Thread

    Discussion in 'Archives' started by pushedx, May 22, 2014.

    Thread Status:
    Not open for further replies.
    1. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      ExilebuddyBeta #814 has just been built. This version contains updates for 1.1.4.1 as well as some improvements based on trying to port the old bot to the new framework. Beta is still only for developers, but progress is continuing at a steady pace on the new bot.

      Unfortunately, the old/new bot implementation cannot be included for users to tinker with. We still aim to provide some examples of various components for bot writers, but the bot we provide has to remain closed source, and modified through hooks/events for the time being.

      From a dev standpoint, the biggest changes made were in relation to passing NetworkObjects around while in a coroutine. Basically, you can't do that. You need to pass ids around and re-lookup the object. This is because a coroutine will execute over multiple frames, and the objects have a lifetime of 1 frame. A lot of the old bot logic has issues with this, so it'll be changing to implement this design.

      Spells got several updates as well. While there are no examples of using it, a SpellHelper class was added for managing skill names and available castable skills for the new routine logic. This was done to help address the issue of users having skill gems equipped to level, but no desire to use them. In addition, in the case of a chest breaking skill, it should not be used for normal logic, but still has to be present. Routines will be getting a new interface and a real structure, but more information will come from that once it's closer to being done.

      You can use the Visual Studio object explorer to browse through the new stuff as always. This update took a lot longer than normal because of the changes from going from the old setup to the new setup. The old bot does not work well yet in the new setup, but the purpose of porting it was to find and fix any issues with the new setup using working code. Several issues were found and fixed, so it was very worthwhile.

      Lastly, please do not beta test the ExilebuddyBot/Routine and report issues. It is broken and is just short term code for testing other aspects of the new setup!
       
    2. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      ExilebuddyBeta #819 has just been built.

      This is a large update to Beta that contains a lot of new and exciting stuff to mess with. Keep in mind that it is not finished yet. Please read the change log for more information. The actual bot we provide, ExilebuddyBot, is not completed yet, nor is the new routine, ExilebuddyRoutine, so if you wish to have a fully functional bot, please use Release instead.

      The current status of Beta is as follows: ExilebuddyBot does not contain town logic or any area transitioning, quest, corrupted areas, shrine, or waypoint based logic. It has all been removed to be re-added as new reusable modules. In addition, the old tools were removed, so the item filter editor has to be used from Release. What the bot does have is: chicken, resurrecting, flask, aura, door, combat, loot, chest, and the old explore logic. In other words, if you place it in an area out side of town, it will grind that area until exploration is completed. The bot does not have any pois to execute in town, so it'll just sit around until you stop it and move it somewhere else.

      The purpose of that setup is to test the new bot design and some improvements made to movement and skill casting. The routine logic is not finished yet, so the bot will only use the first skill it can, and only cast others if it cannot cast one due to mana issues most of the time. This logic will of course be changed, but for now, that's the simplicity of the routine.

      The settings gui for the bot contains some new options, but is still under construction. Everything it contains is usable and integrated into the bot though.

      Now for the more exciting stuff. The bot design is now fully modular. The new design allows users to change almost any aspect of the bot logic, without having to re-implement the entire bot themselves or modify the core code. In addition, new logic can be added seamlessly into the bot.

      For example, the bot will register a default set of pois, which right now include the base functionality listed above. This is done via IPoi interfaces and registered through the PoiManager class. We have our basic logic in place to make the bot work as it has. For example, our CombatPoi implementation will look something like this:
      You need to register and have one post to see spoilers!
      This is our basic "if we have combat targets, execute the CR logic for combat" we have used since the bot was first made. Now, if you wanted to change the conditions for which combat took place, you could just make your own new IPoi named "combat", and register it before our default one is used, or replace the current one via PoiManager. This would allow you to change when/how combat takes place at the bot level (and naturally, is a more advanced thing to do). All of our pois are setup in a similar way, CanExecute has some basic logic checks, then the actual logic is handled like before.

      By registering new pois, users can now add more logic to the bot to make it do things it couldn't before. For example, a common request is using chance orbs to chance items as you find them, and drop them if they are no good. Extending the bot to do this using the new design is very easy, as all that has to be done is a new IPoi being made and registered, and that's it. The bot will evaluate the Pois in order of registration, so the only real work the user has to do is the actual logic to perform the task and taking care of any execution issues to avoid conflicts (e.g., don't run if there are monsters nearby so you don't die).

      This is just some basic info about the changes and the new design. Much more detailed threads will be made later going over the new flexibility and ease of dev that is possible with this stuff. Beta is progressing very nicely, and is getting closer to containing all the base functionality Release does. The biggest thing left to do is update the new ExilebuddyRoutine to allow for a more simple and hopefully easy to use layout so users can start testing. From there, we'll be able to get back to adding new features and improve various quality of life aspects of the bot.
       
    3. babosasa

      babosasa New Member

      Joined:
      Jun 22, 2012
      Messages:
      417
      Likes Received:
      0
      Trophy Points:
      0
      can't wait for this, any ETA on this totally revamped bot?
       
    4. toNyx

      toNyx Well-Known Member

      Joined:
      Oct 29, 2011
      Messages:
      3,770
      Likes Received:
      35
      Trophy Points:
      48
      I ... fakin'... love... you :)

      The fact we can add External POIs coded by ourselves is gonna be sooo fun, people will be able to run the default Bot/Routine without having the pain to find it removed by the next update... <3 and no more hardcore plugins needed, just bunch of code adding this feature into a POI so the bot will handle it. dayum, gotta love this bot.
       
    5. iargue

      iargue Member

      Joined:
      Mar 20, 2012
      Messages:
      125
      Likes Received:
      2
      Trophy Points:
      18
      I have been following the ExileBot development closely since it first started out, and I would love to be able to contribute community driven content. I'm glad you focusing on perfecting the API at this point, but there are a few things I would like to ask about.

      1)I see there is a python console with ironpython applied (Though maybe not functional?). Would we be able to write our plugins/routines/poi's in python? I've written in python for over 10 years now, but c# is one of the few languages I haven't used. As such, I would currently need to learn both the api for the bot and learn how to use c# to program. If I could write it in python, I would just need to learn the API and I could quickly and easily dish out plugins and even more complicated scripts.

      2)If python usage isn't possible/too much work and would delay the bot, I could take the time to learn c#. The fastest way to get up to speed at that point would be if you had a example for
      a)Traveling to a certain area, killing a certain mob (for a quest) and then returning to town and interacting with the quest giver. (Or even doing the first starting quest after waking up). Giving this would allow me to write out a complete questing system for the bot, reducing the work load on you a lot.
      b)Listing the stash, removing an item, and selling it (This is probably already out there. Just point me too it)

      3)Add in the ability to quickly log any variable independent of any script. This would be important for debugging, as if you are watching your script move around the map and do things, and suddenly it does something wrong, you will want to instantly be able to see a variable to know why it did what it did and fix it. (Its important to do this during runtime, as situations change rapidly and are hard to recreate)

      I would absolutely love to be able to create scripts for the bot and improve it to do a lot of helpful things (Questing, boss hunting, maps, chaos recipes, automatic crafting, etc). Can't wait for the api documentation to be finished.
       
    6. iargue

      iargue Member

      Joined:
      Mar 20, 2012
      Messages:
      125
      Likes Received:
      2
      Trophy Points:
      18
      Okay, some updates.

      I decided to just bite the bullet and learn C# as I go along (Its not too different from java anyways). Its been slightly painful but manageable.

      I've managed to write a Bot that checks the stash, and finds a full chaos recipe from selected tabs and withdraws it. I don't think I can reach the selling point yet though, as I don't see in the API any Coroutine for doing anything other then talking to an NPC (I see logic for trade windows and everything, but I don't see anything for opening a trade windows or anything). Once that is added, This script will just need a bit of tlc to clean it up, add a bunch of settings, and make it loop through more then one recipe and its good to go.

      However, I do want to report a bug. The "Open File" option of the Dev tab doesn't seem to do anything. I load up the bot, select inventoryBot.cs as the file and click run file, but it does nothing at all and so I am forced to restart the bot every time I want to practice development with it.
       
    7. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      The Python console was added to Release ages ago, but it was never used and doesn't even seem to work. I've added the code to use it to the default ExamplePlugin project for the next Beta, but I'll have to go through the bindings that are being used and figure out why it's currently broken. The concept is the same as the current CodeDOM setup I've added, you just setup the scripting context and execute code. The reason why CodeDOM is used for the Dev tab, is because it's for writing/testing code that can be used 1:1 in C#, which with a C# driven API, is pretty useful opposed to restarting the program each time you need to test something.

      As for writing in Python, you'd have to use a certain amount of C# to setup doing things in python first, and then you could pretty much do whatever you wanted in python, or any other language that you can run from C#. The key thing is that you're just calling into Python logic from C#, and that's about it. I'm not sure how much work would be involved for actually doing it, but you should be able to actually do it without the new setup getting in your way. There will most likely be some overhead that might cause various things to break, depending on threading and whatnot, but those issues would just have to be worked around as they came up.

      In terms of us adding more support for Python driven development, I do not see that happening anytime soon. The focus is on C#, but if users want to use other things, they are welcome to try, but we can only do so much to add compatibility.

      The Exilebuddy Guides Section will contain some basic stuff soonish to help devs get started and transition into using Beta.

      That is up to the actual implementation of the bot/routine/plugin. The closest thing you can do to automating it is using Reflection, but a better bet would be to take advantage of the new GUI and code around doing it in the first place.

      Once the dialog window is open for the vendor NPC the steps are:

      1. Find the "Sell" option:
      Code:
      var option = LokiPoe.Gui.Npc.DialogOptions.FirstOrDefault(o => o.DialogText == "Sell Items");
      if (option == null)
      // Handle error
      
      2. Select that dialog option and wait some for the server to process it:
      Code:
      LokiPoe.Gui.Npc.SelectDialogOption(option.DialogId);
      
      await Coroutine.Sleep(Utility.LatencySafeValue(1000));
      
      3. Check to make sure the window is opened:
      Code:
      if (!LokiPoe.Gui.IsTradeableWindowOpen)
       // Handle error
      
      At this point, you can now call the FastMoveToTradeWindow function of an inventory item to get it on the NPC trade window.

      When you're ready to accept the trade: LokiPoe.NpcInventory.AcceptTrade();

      That's about the basics of it, there are various other inventory API functions to check to see if you can fit an item and so on, but writing all that logic is just part of implementing it. We'll probably have a more simplified Sell Poi when time permits.

      Check the Log tab for what happened. Also, you don't run an entire bot through that Dev tab. You could, but you'd need to setup your code to execute coroutine logic and that tab is not really setup for complete tasks like that. See the guide on the Dev tab for some basic usages. Basically, our bot gui is the bot driver, and the setup the bots use is to load and compile the bot code once, then execute it. Our bot logic is not open source, so we can't have a default setup of having the bot load source and execute it.

      That type of design is possible though for users, but it's something that would most likely be implemented via a plugin, much like using Python or another language. Roslyn would be the best candidate for that, but at this point, a lot of other things have priority dev wise before doing things like that. So being able to develop and test without having to restart the entire bot by using runtime execute code is definitely on the todo list, but it's not something time can be spent on right now (from our side of things at least).
       
    8. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Beta #820 has just been built. This build, like the last, contains a bunch of updated logic for the bot we provide.

      Please keep in mind this is not a stable/general use build. It's beta!

      Here's a list of various things affecting the bot right now:
      • The explorer being used is the old version which does have some known bugs. It will be rewritten later on.
      • Corrupted areas not supported.
      • Area specific nuances are not added. For example, you can't get to the Archives from the Library because it requires interacting with a world object.
      • Boss areas do not have their local area transitions taken.
      • Various in town pois might have bugs from the porting process.
      • New routine to replace Exile is not implemented yet.
      • At times, frequent pathfinding can cause performance issues, which makes the bot look more choppy.
      • No quest, or new map support or things like that. The bot in beta is taking the Release one and updating it to be compatible with the new bot design.

      There might be more things, but the bot should be usable from a testing perspective if you want to start messing with things.
       
    9. iargue

      iargue Member

      Joined:
      Mar 20, 2012
      Messages:
      125
      Likes Received:
      2
      Trophy Points:
      18

      Thanks for the response. I'll spend the next few days working on the inventory bot then, and then provide it as example code for others until the beta is done.

      The next steps for it are to Automatically sell items that it has pulled out, and then adding more features and creating a settings options and tieing everything to that. I want to make it so it does Chaos Recipes, Map recipes, Sorts the inventory, and to identify and sell everything in x tab (Or everything in x tab that isn't x properties/type). That will help remove the tedious task of sorting out your stash after a botting session.

      After that, I have two things that I want to work on to help expand my api knowledge. 1)A bot that runs through lunaris temple and kills piety (Without quitting whens he goes away for a minute) and 2)A plugin that can autochance picked up items and keep or discard the item).

      One of the biggest thing that I want to learn is how to develop POI's and have the interact with both the core bot, and with other bots so was to add more functionality to existing features.

      Most of those things will require an example to be provided on how to do certain things, such as, how to create and apply a poi, how to path to a certain location and grind it, how to ignore units and find a specific boss. All of these I can probably figure out using the API and brute forcing my way through, but adding examples of how to do anything in that list would greatly speed up my development process (Example. It took me two hours to make it remove chaos recipe from stash. More then 40% of that time was figuring out how c# handles lists and dictionaries and everything) everything that you add it will reduce both my frustration and time to develop.

      Expect an example post of the inventoryBot at the end of the week.
       
    10. iargue

      iargue Member

      Joined:
      Mar 20, 2012
      Messages:
      125
      Likes Received:
      2
      Trophy Points:
      18
      I'm stuck trying to figure out how to pick an NPC to go to. I can use the Object's explorer to find an NPC id, but that can't be the best way to find the NPC, as they can be in any possible city and not just that one. Any help?
       
    11. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Yeap, examples are on the todo list. Priority wise, other things take priority right now. All of this stuff is brand new and some of it is still changing, so I'll sit down and write more examples once the bot we provide in beta is brought back up to where Release was about, so we can switch all development over to the new setup.

      Just keep in mind that development is a long and time consuming endeavour. Look at how long we've been working on the bot and having had to rewrite large parts of it again and again to keep up with how the game has changed. There's a lot of things that happen in this game that make development for it less than trivial in cases where people would expect otherwise. So in short, expect to spend a lot of time learning, writing, and rewriting stuff before you can get things just how you want them. Doing some things in this game is/will be a lot more rough than most other games. Unfortunately, that's just how this game is setup, and we have to work around it.

      To figure out what NPC to go to, you'd process the current area (you can use LokiPoe.LocalData.WorldAreaId or WorldAreaName), and then check against a hardcoded list of known NPC names/locations you can vendor at. There's no other way really, as you'd have to talk to each NPC and check their dialog responses otherwise.

      Utility.GuessWeaponsNpcLocation and Utility.GuessAccessoryNpcLocation exist to return the name/expected location for the respective vendor. You could use either of those, move to the area where they should be, and then try to find the Npc object and go from there. In Act 3, you have to unlock the accessories vendor Clarissa, so you have to take that into account if you can't find her where she's supposed to be.
       
    12. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Beta #821 was just built. It contains a few fixes, an updated ExampleBot for developers, and the new chat reading access that has been on the todo list.

      The ExampleBot shows how you can go about a Poi driven bot, relying on most of our already developed (but closed source) systems. You are by no means restricted to implementing your bot that way. Unlike with the current Release, there's not a whole bunch of behind the scenes stuff. If you don't want to use Pois, don't start/stop/tick the PoiManager. If you don't want to use the Exploration interface, don't start/stop/tick the ExplorationManager, so on and so forth. I wanted our new bot setup to allow developers to have more control over what is going on, so hopefully this design reflects that.

      Right now, I opted to implement a basic example explorer that will travel to a statically calculated location, based on the waypoint in an area. If the area doesn't have a waypoint, the explorer doesn't do anything and exploration is finished. It's just an example, but since our explorer needs to be rewritten, I can't spend a lot of time trying to make a more complete example explorer, that is up to you guys to mess with. The registered poi set is rather small, but it shows almost enough of the basis. I don't have a chest/item poi yet, but one will get added soon. No in town stuff is shown, just some out of town things. We'll have some concise examples of doing various things later for users to refer to.

      Other than that, adding new logic to the ExampleBot is just a matter of creating a poi that has the logic to determine when it can execute and then the actual logic to execute. That's pretty much how ExilebuddyBot is now setup. I did come across an issue where our pois (used in ExilebuddyBot) make use of ExilebuddyBotSettings, which if you are making your own bot, you'd not set those settings, so some of that logic cannot be reused as-is currently. This issue will have to be resolved somehow in the near future, so for now, the ExampleBot has its own set of Pois and does not reuse any form ExilebuddyBot.
       
    13. Urgent2009

      Urgent2009 Member

      Joined:
      Mar 10, 2014
      Messages:
      182
      Likes Received:
      9
      Trophy Points:
      18
      I haven't been able to check any of the new code and I don't understand if we need to come up with an exploration logic or not. Is there already an existing one? Or this is just so that it gets the job done until it is re-written?
       
    14. iargue

      iargue Member

      Joined:
      Mar 20, 2012
      Messages:
      125
      Likes Received:
      2
      Trophy Points:
      18
      There needs to be a much better method of interacting with items across inventories.

      For example, when withdrawing an item, you can't use name because this will remove all items with the same name. When dealing with unidentified items, this is a lot. BaseAddress works very well, but it won't work if you want to remove that item from the inventory again and do anything with it, because baseaddress changes, and hashcode changes, and the only thing that remains the same are things that could be duplicated among other objects.

      Right now, I am getting past this by storing both the base address and the name, and then after the item has been removed from stash, using name to identify the item. This limits the range of duplicity to the inventory only, but will still cause issues in rare cases.
       
    15. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Look at the code in Bots\ExampleBot, specifically ExampleExplorer.cs. I've included a basic example of trying to explore towards a fixed point determined at runtime. If you want custom exploration logic to make your bot explore a different way than how we do it, you'd need to implement that into an explorer and set the instance. That way, you can now replace our exploration logic with your own, as opposed to before, where it was hard coded into the bot.

      What you are talking about specifically, is a result of how this game works, and is just one example of many things that gets tedious and annoying. There is no unique identifier for items. There is no way to associate the item you withdraw from one inventory with the item that is placed into the destination inventory. The game works in a way where the items are destroyed and re-created, and memory usually changes quite often.

      What you can do though, is to do association by item location (which is what we end up doing for a few things). Basically, you find a place in inventory where the item would fit, you'd pick up the item to the cursor, than place the item into that specified spot. That way, you know the item you are trying to work with should now be in the desired location, or still on the cursor inventory because it failed to place.
       
    16. Urgent2009

      Urgent2009 Member

      Joined:
      Mar 10, 2014
      Messages:
      182
      Likes Received:
      9
      Trophy Points:
      18
      Wow this excites me so much, I can't wait to get back to botting. I'll give a week for another release or two tho.
       
    17. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Beta #823 was just built. This version adds a little more logic to our bot and some API stuff for the upcoming default CR implementation.

      The current status of Beta is as follows:
      • Some performance issues during explore that need to be addressed. The bot is still usable but FPS drops down to around 10 for the duration of the issu
      • Exploration logic is not updated yet. Due to new changes to help avoid the bot from getting stuck, some items/chests might be temporarily ignored, and it's possible for them to be totally ignored as a result.
      • Certain problems the old bot had, such as the bot cycling between explore/combat and getting stuck are not fixed yet. Idle timers are still going to be implemented and some other issues to try and combat that.
      • The current default CR has some testing logic more suitable for ranged characters rather than melee. The default CR we provide is not actually finished yet.
      • Area specific logic is not back in yet. This means the bot can't do quests, interact with certain world objects, take corrupted areas, etc...
      • The default set of tools such as Inventory Explorer, Item Filter Editor, Map Visualizer, Object Viewer have not been ported in yet. They will hopefully make their way back soon.

      Please remember Beta is not for general use yet, but it is in a usable state for testing things if you're interested. The biggest hurdle left is re-implementing Exile in a more user friendly way rather than just listing all skills and letting users move lines around, although if that turns out to be the most usable approach, we'll just stick with that.
       
    18. darkbluefirefly

      darkbluefirefly Community Developer

      Joined:
      Nov 8, 2013
      Messages:
      1,927
      Likes Received:
      18
      Trophy Points:
      38
      Gotta let all you know why issues that Pushedx are trying resolve are very complicated.
      It boils down to GGG and desigining the game. They had no idea how to develop(program) a game, made things as they went. Therefore their code is a mess, anyone you ask to reverse PoE, will tell you it's a nightmare. The game simply is not like the AAA titles that are developed by hundreds of people.

      The bot has to do certain things to make itself work
      1- Checking the frames currently at and doing said action based on the frame, since GGG designed the game to be heavily server controlled, Client will desync and do stupid shit, so the bot will basically do stupid shit too(not really but for argument sake it will). It tries to attack/move, server sends back saying no wrong location, etc.
      Not really good at explaining this, and I have to head home
      TL;DR - PoE very bad programmed, shit hard to do because of this, bot works so good. Hence why there are not many PoE bots around.. This working one, and the other shitty one which I shall not name, but we all know and have tried.
       
    19. pushedx

      pushedx Moderator Moderator Buddy Core Dev

      Joined:
      Sep 24, 2013
      Messages:
      4,252
      Likes Received:
      290
      Trophy Points:
      83
      Beta #824 was just built.

      In this version, some new SotV functionality was added! The bot now has default logic for identifying, rerolling, and skipping individual strongboxes. There is a new global setting called IdentifyStrongBoxes that must be set to true for the bot to allow the IDing logic to execute. The new logic is implemented through a new interface, IHandleDangerousChest. ExilebuddyRoutine contains a very simple example of the logic implementation. The bot doesn't have updated setting to allow different currency items to not be stashed, but that will be done as well. The system is in place for it, the old code just needs to be replaced with it now.

      In addition, the bot will now open a strongbox and try to move away from it as soon as it can to avoid some of the trapped ones. However, this is not always possible, which you'll see if you play the game by hand, due to various things such as latency, desync, and just the design of some of the chests. There's not much more that can be done, due to the way the game works, but this solution should be a much bigger improvement over the old code which never moved.

      The performance issues in the TspExplorer has been found, but not fixed yet. The solution is to rewrite it, but that's been planned, so I'm just letting you guys know why at times FPS hits a solid 10 during exploration but it smooth everywhere else. If you use ExampleBot, you'll notice the issue doesn't happen, because the exploration logic for ExampleBot is a lot more simple with no calculations. TspExplorer does a ton of calculations each tick, and that is building up to be really inefficient in this new design.

      You can expect more feature updates and better implementation of the stuff we never had in Release as time goes on! Beta is getting closer to replaying Release, but it's still not quite ready yet. We're always receptive of feedback or requests, so if there's something that's been needed and hasn't been mentioned, please feel free to suggest it.
       
    20. krone6

      krone6 Member

      Joined:
      Jun 11, 2012
      Messages:
      441
      Likes Received:
      0
      Trophy Points:
      16
      When this is released what will the GUI look like? Will it be massively cleaned up so users like me can edit a lot of the bot without opening files and sorting through code? Can we do things like avoid a certain strongbox because it has a specific mod we can't handle all through gui?

      Keep up the good work.
       
    Thread Status:
    Not open for further replies.

    Share This Page