/// <summary> /// Initializes a new bot. /// /// Call Start(), Pause(), Resume(), Dispose() to control the bots engine. /// /// More stuff of the bot can be reached via its "Bot" property. /// </summary> /// <param name="config">The bot configuration.</param> /// <param name="logfilePath">Logfile folder path, not a file path. Leave DEFAULT to put it into bots profile folder. Set to string.Empty to disable logging.</param> /// <param name="initialLogLevel">The initial LogLevel of the bots logger.</param> public AmeisenBot(AmeisenBotConfig config, string logfilePath = "DEFAULT", LogLevel initialLogLevel = LogLevel.Verbose) { Config = config ?? throw new ArgumentException("config cannot be null", nameof(config)); if (string.IsNullOrWhiteSpace(config.Path)) { throw new ArgumentException("config.Path cannot be empty, make sure you set it after loading the config", nameof(config)); } if (!File.Exists(config.Path)) { throw new ArgumentException("config.Path does not exist", nameof(config)); } ProfileFolder = Path.GetDirectoryName(config.Path); AccountName = Path.GetFileName(ProfileFolder); if (logfilePath == "DEFAULT") { logfilePath = Path.Combine(ProfileFolder, "log/"); } if (!string.IsNullOrWhiteSpace(logfilePath) && Directory.Exists(logfilePath)) { AmeisenLogger.I.ChangeLogFolder(logfilePath); AmeisenLogger.I.ActiveLogLevel = initialLogLevel; AmeisenLogger.I.Start(); } AmeisenLogger.I.Log("AmeisenBot", $"AmeisenBot ({Assembly.GetExecutingAssembly().GetName().Version}) starting", LogLevel.Master); AmeisenLogger.I.Log("AmeisenBot", $"AccountName: {AccountName}", LogLevel.Master); AmeisenLogger.I.Log("AmeisenBot", $"BotDataPath: {ProfileFolder}", LogLevel.Verbose); ExecutionMsStopwatch = new(); string dataFolder = Path.Combine(ProfileFolder, "data"); if (!Directory.Exists(dataFolder)) { Directory.CreateDirectory(dataFolder); } // start initializing the wow interface Bot = new(); Bot.Memory = new XMemory(); // load the wow specific interface based on file version (build number) Bot.Wow = FileVersionInfo.GetVersionInfo(Config.PathToWowExe).FilePrivatePart switch { 12340 => new WowInterface335a(Bot.Memory), _ => throw new ArgumentException("Unsupported wow version", nameof(Config)), }; Bot.Storage = new(dataFolder, new List <string>() { // strings to strip from class names "AmeisenBotX.Core.Engines.Combat.Classes.", "AmeisenBotX.Core.Engines.Tactic." }); Bot.IdleActions = new(Config, new List <IIdleAction>() { new AuctionHouseIdleAction(Bot), new CheckMailsIdleAction(Bot), new FishingIdleAction(Bot), new LookAroundIdleAction(Bot), new LookAtGroupIdleAction(Bot), new RandomEmoteIdleAction(Bot), new SitByCampfireIdleAction(Bot), new SitToChairIdleAction(Bot, Config.MinFollowDistance), }); Logic = new AmeisenBotLogic(Config, Bot); Bot.Chat = new DefaultChatManager(Config, ProfileFolder); Bot.Tactic = new DefaultTacticEngine(Bot); Bot.Wow.OnStaticPopup += OnStaticPopup; Bot.Wow.OnBattlegroundStatus += OnBattlegroundStatusChanged; AmeisenLogger.I.Log("AmeisenBot", $"Using OffsetList: {Bot.Wow.Offsets.GetType().Name}", LogLevel.Master); Bot.Character = new DefaultCharacterManager(Bot.Wow, Bot.Memory); string dbPath = Path.Combine(ProfileFolder, "db.json"); AmeisenLogger.I.Log("AmeisenBot", $"Loading DB from: {dbPath}", LogLevel.Master); Bot.Db = LocalAmeisenBotDb.FromJson(dbPath, Bot.Wow, Bot.Memory); PoiCacheEvent = new TimegatedEvent(TimeSpan.FromSeconds(2)); Bot.Objects.OnObjectUpdateComplete += OnObjectUpdateComplete; Bot.CombatLog = new DefaultCombatlogParser(); // setup all instances that use the whole Bot class last Bot.Dungeon = new DefaultDungeonEngine(Bot, Config); Bot.Jobs = new DefaultJobEngine(Bot, Config); Bot.Quest = new DefaultQuestEngine(Bot); Bot.Grinding = new DefaultGrindEngine(Bot, Config); Bot.Pvp = new DefaultPvpEngine(Bot, Config); Bot.Threat = new ThreatManager(Bot, Config); Bot.Test = new DefaultTestEngine(Bot, Config); Bot.PathfindingHandler = new AmeisenNavigationHandler(Config.NavmeshServerIp, Config.NameshServerPort); Bot.Movement = new DefaultMovementEngine(Bot, Config); // wow interface setup done AmeisenLogger.I.Log("AmeisenBot", "Finished setting up Bot", LogLevel.Verbose); AmeisenLogger.I.Log("AmeisenBot", "Loading CombatClasses", LogLevel.Verbose); InitCombatClasses(); AmeisenLogger.I.Log("AmeisenBot", "Loading BattlegroundEngines", LogLevel.Verbose); InitBattlegroundEngines(); AmeisenLogger.I.Log("AmeisenBot", "Loading JobProfiles", LogLevel.Verbose); InitJobProfiles(); AmeisenLogger.I.Log("AmeisenBot", "Loading QuestProfiles", LogLevel.Verbose); InitQuestProfiles(); AmeisenLogger.I.Log("AmeisenBot", "Loading GrindingProfiles", LogLevel.Verbose); InitGrindingProfiles(); AmeisenLogger.I.Log("AmeisenBot", "Loading Profiles", LogLevel.Verbose); LoadProfiles(); Bot.Storage.LoadAll(); if (Config.RconEnabled) { AmeisenLogger.I.Log("AmeisenBot", "Setting up RconClient", LogLevel.Verbose); RconEvent = new(TimeSpan.FromMilliseconds(Config.RconInterval)); SetupRconClient(); } }
public AmeisenBot(string botDataPath, string accountName, AmeisenBotConfig config, IntPtr mainWindowHandle) { Config = config; AccountName = accountName; BotDataPath = botDataPath; MainWindowHandle = mainWindowHandle; ExecutionMsStopwatch = new(); if (!Directory.Exists(BotDataPath)) { Directory.CreateDirectory(BotDataPath); } SetupLogging(botDataPath, accountName); AmeisenLogger.I.Log("AmeisenBot", $"AmeisenBot ({Assembly.GetExecutingAssembly().GetName().Version}) starting", LogLevel.Master); AmeisenLogger.I.Log("AmeisenBot", $"AccountName: {accountName}", LogLevel.Master); AmeisenLogger.I.Log("AmeisenBot", $"BotDataPath: {botDataPath}", LogLevel.Verbose); WowInterface = new(); WowInterface.Globals = new(); WowInterface.OffsetList = new OffsetList335a(); WowInterface.XMemory = new(); WowInterface.Db = LocalAmeisenBotDb.FromJson(WowInterface, Path.Combine(BotDataPath, AccountName, "db.json")); WowInterface.Personality = new(); WowInterface.ChatManager = new(Config, Path.Combine(BotDataPath, AccountName)); WowInterface.CombatLogParser = new(WowInterface); WowInterface.HookManager = new HookManager(WowInterface, Config); WowInterface.ObjectManager = new ObjectManager(WowInterface, Config); WowInterface.CharacterManager = new CharacterManager(Config, WowInterface); WowInterface.EventHookManager = new(WowInterface); WowInterface.JobEngine = new(WowInterface, Config); WowInterface.DungeonEngine = new DungeonEngine(WowInterface); WowInterface.TacticEngine = new(); WowInterface.PathfindingHandler = new NavmeshServerPathfindingHandler(Config.NavmeshServerIp, Config.NameshServerPort); WowInterface.MovementSettings = Config.MovementSettings; WowInterface.MovementEngine = new AMovementEngine(WowInterface, Config); StateMachine = new(BotDataPath, Config, WowInterface); StateMachine.GetState <StateStartWow>().OnWoWStarted += AmeisenBot_OnWoWStarted; WowInterface.QuestEngine = new(WowInterface, Config, StateMachine); WowInterface.GrindingEngine = new(WowInterface, Config, StateMachine); RconScreenshotEvent = new(TimeSpan.FromMilliseconds(Config.RconScreenshotInterval)); AmeisenLogger.I.Log("AmeisenBot", $"Using OffsetList: {WowInterface.OffsetList.GetType()}", LogLevel.Master); if (Config.RconEnabled) { WowInterface.ObjectManager.OnObjectUpdateComplete += ObjectManager_OnObjectUpdateComplete; } InitCombatClasses(); InitBattlegroundEngines(); InitJobProfiles(); InitQuestProfiles(); InitGrindingProfiles(); LoadProfiles(); }