├── include.sh ├── .editorconfig ├── .github ├── workflows │ └── core-build.yml └── ISSUE_TEMPLATE │ ├── feature_request.yml │ └── bug_report.yml ├── src ├── ah_bot_loader.cpp ├── AuctionHouseBotCommon.cpp ├── AuctionHouseBotScript.cpp ├── AuctionHouseBotWorldScript.h ├── AuctionHouseBotMailScript.h ├── AuctionHouseBotMailScript.cpp ├── AuctionHouseBotAuctionHouseScript.h ├── AuctionHouseBot.h ├── AuctionHouseBotCommon.h ├── AuctionHouseBotWorldScript.cpp ├── AuctionHouseBotAuctionHouseScript.cpp ├── AuctionHouseBotConfig.h ├── cs_ah_bot.cpp └── AuctionHouseBot.cpp ├── .gitignore ├── pull_request_template.md ├── .gitattributes ├── data └── sql │ └── db-world │ ├── z_filter_disabled_and_trash.sql │ └── mod_auctionhousebot.sql ├── README.md └── conf └── mod_ahbot.conf.dist /include.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | tab_width = 4 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | max_line_length = 80 9 | -------------------------------------------------------------------------------- /.github/workflows/core-build.yml: -------------------------------------------------------------------------------- 1 | name: core-build 2 | on: 3 | push: 4 | branches: 5 | - 'master' 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | uses: azerothcore/reusable-workflows/.github/workflows/core_build_modules.yml@main 11 | with: 12 | module_repo: ${{ github.event.repository.name }} 13 | -------------------------------------------------------------------------------- /src/ah_bot_loader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | * Copyright (C) 2021+ WarheadCore 4 | */ 5 | 6 | // From SC 7 | void AddAHBotCommandScripts(); 8 | void AddAHBotScripts(); 9 | 10 | // Add all 11 | void Addmod_ah_botScripts() 12 | { 13 | AddAHBotCommandScripts(); 14 | AddAHBotScripts(); 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | 3 | # 4 | #Generic 5 | # 6 | 7 | .directory 8 | .mailmap 9 | *.orig 10 | *.rej 11 | *~ 12 | .hg/ 13 | *.kdev* 14 | .DS_Store 15 | CMakeLists.txt.user 16 | *.bak 17 | *.patch 18 | *.diff 19 | *.REMOTE.* 20 | *.BACKUP.* 21 | *.BASE.* 22 | *.LOCAL.* 23 | 24 | # 25 | # IDE & other softwares 26 | # 27 | /.settings/ 28 | /.externalToolBuilders/* 29 | # exclude in all levels 30 | nbproject/ 31 | .sync.ffs_db 32 | *.kate-swp 33 | 34 | # 35 | # Eclipse 36 | # 37 | *.pydevproject 38 | .metadata 39 | .gradle 40 | tmp/ 41 | *.tmp 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .settings/ 46 | .loadpath 47 | .project 48 | .cproject 49 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Changes Proposed: 4 | - 5 | - 6 | 7 | ## Issues Addressed: 8 | 9 | - Closes 10 | 11 | ## SOURCE: 12 | 13 | 14 | ## Tests Performed: 15 | 16 | - 17 | - 18 | 19 | 20 | ## How to Test the Changes: 21 | 22 | 23 | 1. 24 | 2. 25 | 3. 26 | -------------------------------------------------------------------------------- /src/AuctionHouseBotCommon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #include "AuctionHouseBot.h" 6 | #include "AuctionHouseBotCommon.h" 7 | #include "AuctionHouseBotConfig.h" 8 | 9 | // 10 | // Configuration used globally by all the bots instances 11 | // 12 | 13 | AHBConfig* gAllianceConfig = new AHBConfig(2); 14 | AHBConfig* gHordeConfig = new AHBConfig(6); 15 | AHBConfig* gNeutralConfig = new AHBConfig(7); 16 | 17 | // 18 | // Active bots 19 | // 20 | 21 | std::set gBotsId; 22 | std::set gBots; 23 | -------------------------------------------------------------------------------- /src/AuctionHouseBotScript.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #include "AuctionHouseBot.h" 6 | #include "AuctionHouseBotAuctionHouseScript.h" 7 | #include "AuctionHouseBotMailScript.h" 8 | #include "AuctionHouseBotWorldScript.h" 9 | 10 | // ============================================================================= 11 | // This provides the effective startup of the module by istanciating the scripts 12 | // ============================================================================= 13 | 14 | void AddAHBotScripts() 15 | { 16 | new AHBot_WorldScript(); 17 | new AHBot_AuctionHouseScript(); 18 | new AHBot_MailScript(); 19 | } 20 | -------------------------------------------------------------------------------- /src/AuctionHouseBotWorldScript.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #ifndef AUCTION_HOUSE_BOT_WORLD_SCRIPT_H 6 | #define AUCTION_HOUSE_BOT_WORLD_SCRIPT_H 7 | 8 | #include "ScriptMgr.h" 9 | 10 | // ============================================================================= 11 | // Interaction with the world core mechanisms 12 | // ============================================================================= 13 | 14 | class AHBot_WorldScript : public WorldScript 15 | { 16 | private: 17 | void DeleteBots(); 18 | void PopulateBots(); 19 | 20 | public: 21 | AHBot_WorldScript(); 22 | 23 | void OnBeforeConfigLoad(bool reload) override; 24 | void OnStartup() override; 25 | }; 26 | 27 | #endif /* AUCTION_HOUSE_BOT_WORLD_SCRIPT_H */ 28 | -------------------------------------------------------------------------------- /src/AuctionHouseBotMailScript.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #ifndef AUCTION_HOUSE_BOT_MAIL_SCRIPT_H 6 | #define AUCTION_HOUSE_BOT_MAIL_SCRIPT_H 7 | 8 | #include "ScriptMgr.h" 9 | #include "Mail.h" 10 | 11 | // ============================================================================= 12 | // Interaction with the mailing systems 13 | // ============================================================================= 14 | 15 | class AHBot_MailScript : public MailScript 16 | { 17 | public: 18 | AHBot_MailScript(); 19 | 20 | void OnBeforeMailDraftSendMailTo(MailDraft* mailDraft, MailReceiver const& receiver, MailSender const& sender, MailCheckMask& checked, uint32& deliver_delay, uint32& custom_expiration, bool& deleteMailItemsFromDB, bool& sendMail) override; 21 | }; 22 | 23 | #endif /* AUCTION_HOUSE_BOT_MAIL_SCRIPT_H */ 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## AUTO-DETECT 2 | ## Handle line endings automatically for files detected as 3 | ## text and leave all files detected as binary untouched. 4 | ## This will handle all files NOT defined below. 5 | * text=auto eol=lf 6 | 7 | # Text 8 | *.conf 9 | *.conf.dist 10 | *.txt 11 | *.md 12 | *.cmake 13 | 14 | # Bash 15 | *.sh text 16 | 17 | # Lua if lua module? 18 | *.lua 19 | 20 | # SQL 21 | *.sql 22 | 23 | # C++ 24 | *.c text 25 | *.cc text 26 | *.cxx text 27 | *.cpp text 28 | *.c++ text 29 | *.hpp text 30 | *.h text 31 | *.h++ text 32 | *.hh text 33 | 34 | 35 | ## For documentation 36 | 37 | # Documents 38 | *.doc diff=astextplain 39 | *.DOC diff=astextplain 40 | *.docx diff=astextplain 41 | *.DOCX diff=astextplain 42 | *.dot diff=astextplain 43 | *.DOT diff=astextplain 44 | *.pdf diff=astextplain 45 | *.PDF diff=astextplain 46 | *.rtf diff=astextplain 47 | *.RTF diff=astextplain 48 | 49 | 50 | # Graphics 51 | *.png binary 52 | *.jpg binary 53 | *.jpeg binary 54 | *.gif binary 55 | *.tif binary 56 | *.tiff binary 57 | *.ico binary 58 | # SVG treated as an asset (binary) by default. If you want to treat it as text, 59 | # comment-out the following line and uncomment the line after. 60 | *.svg binary 61 | #*.svg text 62 | *.eps binary 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | title: "Feature: " 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thank you for taking your time to fill out a feature request. Remember to fill out all fields including the title above. 9 | An issue that is not properly filled out will be closed. 10 | - type: textarea 11 | id: description 12 | attributes: 13 | label: Describe your feature request or suggestion in detail 14 | description: | 15 | A clear and concise description of what you want to happen. 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: solution 20 | attributes: 21 | label: Describe a possible solution to your feature or suggestion in detail 22 | description: | 23 | A clear and concise description of any alternative solutions or features you've considered. 24 | validations: 25 | required: false 26 | - type: textarea 27 | id: additional 28 | attributes: 29 | label: Additional context 30 | description: | 31 | Add any other context or screenshots about the feature request here. 32 | validations: 33 | required: false 34 | -------------------------------------------------------------------------------- /src/AuctionHouseBotMailScript.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #include "AuctionHouseBot.h" 6 | #include "AuctionHouseBotCommon.h" 7 | #include "AuctionHouseBotMailScript.h" 8 | 9 | AHBot_MailScript::AHBot_MailScript() : MailScript("AHBot_MailScript", { 10 | MAILHOOK_ON_BEFORE_MAIL_DRAFT_SEND_MAIL_TO 11 | }) 12 | { 13 | 14 | } 15 | 16 | void AHBot_MailScript::OnBeforeMailDraftSendMailTo( 17 | MailDraft*, /* mailDraft */ 18 | MailReceiver const& receiver, 19 | MailSender const& sender, 20 | MailCheckMask&, /* checked */ 21 | uint32&, /* deliver_delay */ 22 | uint32&, /* custom_expiration */ 23 | bool& deleteMailItemsFromDB, 24 | bool& sendMail) 25 | { 26 | // 27 | // If the mail is for the bot, then remove it and delete the items bought 28 | // 29 | 30 | if (gBotsId.find(receiver.GetPlayerGUIDLow()) != gBotsId.end()) 31 | { 32 | if (sender.GetMailMessageType() == MAIL_AUCTION) 33 | { 34 | deleteMailItemsFromDB = true; 35 | } 36 | 37 | sendMail = false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AuctionHouseBotAuctionHouseScript.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #ifndef AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H 6 | #define AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H 7 | 8 | #include "Player.h" 9 | #include "ScriptMgr.h" 10 | 11 | // ============================================================================= 12 | // Interaction with the auction house core mechanisms 13 | // ============================================================================= 14 | 15 | class AHBot_AuctionHouseScript : public AuctionHouseScript 16 | { 17 | public: 18 | AHBot_AuctionHouseScript(); 19 | 20 | void OnBeforeAuctionHouseMgrSendAuctionSuccessfulMail(AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* owner, uint32& owner_accId, uint32& profit, bool& sendNotification, bool& updateAchievementCriteria, bool& sendMail) override; 21 | void OnBeforeAuctionHouseMgrSendAuctionExpiredMail (AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* owner, uint32& owner_accId, bool& sendNotification, bool& sendMail) override; 22 | void OnBeforeAuctionHouseMgrSendAuctionOutbiddedMail (AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* oldBidder, uint32& oldBidder_accId, Player* newBidder, uint32& newPrice, bool& sendNotification, bool& sendMail) override; 23 | 24 | void OnAuctionAdd (AuctionHouseObject* ah, AuctionEntry* auction) override; 25 | void OnAuctionRemove (AuctionHouseObject* ah, AuctionEntry* auction) override; 26 | void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* auction) override; 27 | void OnAuctionExpire (AuctionHouseObject* ah, AuctionEntry* auction) override; 28 | 29 | void OnBeforeAuctionHouseMgrUpdate() override; 30 | }; 31 | 32 | #endif /* AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H */ 33 | -------------------------------------------------------------------------------- /data/sql/db-world/z_filter_disabled_and_trash.sql: -------------------------------------------------------------------------------- 1 | 2 | INSERT IGNORE INTO mod_auctionhousebot_disabled_items (item) 3 | SELECT entry 4 | FROM item_template 5 | WHERE ( 6 | NAME LIKE '%tablet%' OR 7 | NAME LIKE '%sulfuron%' OR 8 | NAME LIKE '%nightcrawlers%' OR 9 | NAME LIKE '%throwing dagger%' OR 10 | NAME LIKE '%shot pouch%' OR 11 | NAME LIKE '%brimstone%' OR 12 | NAME LIKE '%small pouch%' OR 13 | NAME LIKE '%dye%' OR 14 | NAME LIKE '%ironwood seed%' OR 15 | NAME LIKE '%stranglethorn seed%' OR 16 | NAME LIKE '%simple wood%' OR 17 | NAME LIKE '%bleach%' OR 18 | NAME LIKE '%flour%' OR 19 | NAME LIKE '%brew%' OR 20 | NAME LIKE '%parchment%' OR 21 | NAME LIKE '%light quiver%' OR 22 | NAME LIKE '%honey%' OR 23 | NAME LIKE '%/%' OR 24 | NAME LIKE '%creeping anguish%' OR 25 | NAME LIKE '%felcloth bag%' OR 26 | NAME LIKE '%elementium ore%' OR 27 | NAME LIKE '%unused%' OR 28 | NAME LIKE '%lava core%' OR 29 | NAME LIKE '%fiery core%' OR 30 | NAME LIKE '%sulfuron ingot%' OR 31 | NAME LIKE '%sak%' OR 32 | NAME LIKE '%gigantique%' OR 33 | NAME LIKE '%portable hole%' OR 34 | NAME LIKE '%deptecated%' OR 35 | NAME LIKE '%durability%' OR 36 | NAME LIKE '%big sack%' OR 37 | NAME LIKE '%decoded%' OR 38 | NAME LIKE '%knowledge:%' OR 39 | NAME LIKE '%manual%' OR 40 | NAME LIKE '%gnome head%' OR 41 | NAME LIKE '%critter enlarger%' OR 42 | NAME LIKE '%box of%' OR 43 | NAME LIKE '%summoning%' OR 44 | NAME LIKE '%turtle egg%' OR 45 | NAME LIKE '%heavy crate%' OR 46 | NAME LIKE '%assasin throwing axe%' OR 47 | NAME LIKE '%sack of gems%' OR 48 | NAME LIKE '%plans: darkspear%' OR 49 | NAME LIKE '%of swords%' OR 50 | NAME LIKE '%gnomish alarm%' OR 51 | NAME LIKE '%world enlarger%' OR 52 | NAME LIKE '%tome%' OR 53 | NAME LIKE '%ornate spyglass%' OR 54 | NAME LIKE '%test%' OR 55 | NAME LIKE '%darkmoon prize%' OR 56 | NAME LIKE '%codex%' OR 57 | NAME LIKE '%grimoire%' OR 58 | NAME LIKE '%deprecated%' OR 59 | NAME LIKE '%book%' OR 60 | NAME LIKE '%libram%' OR 61 | NAME LIKE '%guide%' 62 | ) 63 | OR NAME COLLATE utf8mb4_bin LIKE '%OLD%' 64 | OR UPPER(NAME) LIKE '%NPC%' 65 | OR UPPER(NAME) LIKE '%QA%' 66 | OR (CLASS = 0 AND SUBCLASS = 5 AND REQUIREDLEVEL < 40); 67 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a bug report to help us improve. 3 | title: "Bug: " 4 | body: 5 | - type: textarea 6 | id: current 7 | attributes: 8 | label: Current Behaviour 9 | description: | 10 | Description of the problem or issue here. 11 | Include entries of affected creatures / items / quests / spells etc. 12 | If this is a crash, post the crashlog (upload to https://gist.github.com/) and include the link here. 13 | Never upload files! Use GIST for text and YouTube for videos! 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: expected 18 | attributes: 19 | label: Expected Behaviour 20 | description: | 21 | Tell us what should happen instead. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: reproduce 26 | attributes: 27 | label: Steps to reproduce the problem 28 | description: | 29 | What does someone else need to do to encounter the same bug? 30 | placeholder: | 31 | 1. Step 1 32 | 2. Step 2 33 | 3. Step 3 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: extra 38 | attributes: 39 | label: Extra Notes 40 | description: | 41 | Do you have any extra notes that can help solve the issue that does not fit any other field? 42 | placeholder: | 43 | None 44 | validations: 45 | required: false 46 | - type: textarea 47 | id: commit 48 | attributes: 49 | label: AC rev. hash/commit 50 | description: | 51 | Copy the result of the `.server debug` command (if you need to run it from the client get a prat addon) 52 | validations: 53 | required: true 54 | - type: input 55 | id: os 56 | attributes: 57 | label: Operating system 58 | description: | 59 | The Operating System the Server is running on. 60 | i.e. Windows 11 x64, Debian 10 x64, macOS 12, Ubuntu 20.04 61 | validations: 62 | required: true 63 | - type: textarea 64 | id: custom 65 | attributes: 66 | label: Custom changes or Modules 67 | description: | 68 | List which custom changes or modules you have applied, i.e. Eluna module, etc. 69 | placeholder: | 70 | None 71 | validations: 72 | required: false 73 | -------------------------------------------------------------------------------- /src/AuctionHouseBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2010 Trinity 3 | * Copyright (C) 2005-2009 MaNGOS 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef AUCTION_HOUSE_BOT_H 21 | #define AUCTION_HOUSE_BOT_H 22 | 23 | #include "Common.h" 24 | #include "ObjectGuid.h" 25 | #include "AuctionHouseMgr.h" 26 | 27 | #include "AuctionHouseBotCommon.h" 28 | #include "AuctionHouseBotConfig.h" 29 | 30 | struct AuctionEntry; 31 | class Player; 32 | class WorldSession; 33 | 34 | #define AUCTION_HOUSE_BOT_LOOP_BREAKER 32 35 | 36 | class AuctionHouseBot 37 | { 38 | private: 39 | uint32 _account; 40 | uint32 _id; 41 | 42 | AHBConfig* _allianceConfig; 43 | AHBConfig* _hordeConfig; 44 | AHBConfig* _neutralConfig; 45 | 46 | time_t _lastrun_a_sec; 47 | time_t _lastrun_h_sec; 48 | time_t _lastrun_n_sec; 49 | 50 | // 51 | // Main operations 52 | // 53 | void Sell(Player *AHBplayer, AHBConfig *config); 54 | void Buy (Player *AHBplayer, AHBConfig *config, WorldSession *session); 55 | 56 | // 57 | // Utilities 58 | // 59 | 60 | inline uint32 minValue(uint32 a, uint32 b) { return a <= b ? a : b; }; 61 | 62 | uint32 getNofAuctions(AHBConfig* config, AuctionHouseObject* auctionHouse, ObjectGuid guid); 63 | uint32 getStackCount(AHBConfig* config, uint32 max); 64 | uint32 getElapsedTime(uint32 timeClass); 65 | uint32 getElement(std::set set, int index, uint32 botId, uint32 maxDup, AuctionHouseObject* auctionHouse); 66 | 67 | public: 68 | AuctionHouseBot(uint32 account, uint32 id); 69 | ~AuctionHouseBot(); 70 | 71 | void Initialize(AHBConfig* allianceConfig, AHBConfig* hordeConfig, AHBConfig* neutralConfig); 72 | void Update(); 73 | 74 | void Commands(AHBotCommand command, uint32 ahMapID, uint32 col, char* args); 75 | 76 | ObjectGuid::LowType GetAHBplayerGUID() { return _id; }; 77 | }; 78 | 79 | #endif // AUCTION_HOUSE_BOT_H 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) AzerothCore 2 | ## Mod-AHBOT 3 | - Latest build status with azerothcore: [![Build Status](https://github.com/azerothcore/mod-ah-bot/workflows/core-build/badge.svg?branch=master&event=push)](https://github.com/azerothcore/mod-ah-bot) 4 | 5 | 6 | ## Important notes 7 | 8 | You have to use at least AzerothCore commit [9adba48](https://github.com/azerothcore/azerothcore-wotlk/commit/9adba482c236f1087d66a672e97a99f763ba74b3). 9 | 10 | If you use an old version of this module please update the table structure using this SQL statement: 11 | 12 | ```sql 13 | ALTER TABLE `auctionhousebot` RENAME TO `mod_auctionhousebot`; 14 | ``` 15 | 16 | ## Description 17 | 18 | An auction house bot for the best core: AzerothCore. 19 | This mod works by selling and bidding auctions in the factions auction house. It can be instructed to do both the operations independently. 20 | 21 | ## Installation 22 | 23 | ``` 24 | 1. Simply place the module under the `modules` directory of your AzerothCore source. 25 | 1. Import the SQL manually to the right Database (auth, world or characters). 26 | 1. Re-run cmake and launch a clean build of AzerothCore. 27 | ``` 28 | 29 | ## Usage 30 | 31 | Edit the module configuration and add a player account ID and a character ID. 32 | This character will sell and buy items in the auction house so give him a good name. 33 | If you only specify the account ID, all the characters created within that account will be involved in selling and bidding on the markets. 34 | 35 | Specify what operation must be performed (`EnableSeller`, `EnableBuyer` or both). 36 | 37 | Notes: 38 | - The account used does not need any security level and can be a player account. 39 | - The character used by the ahbot is not meant to be used ingame. If you use it to browse the auction house, you might have issues like "Searching for items..." displaying forever. 40 | 41 | ## Edit module configuration (optional) 42 | 43 | If you need to change the module configuration, go to your server configuration folder (where your `worldserver` or `worldserver.exe` is) in `modules` you will have to copy and rename (the copy) the file `mod_ahbot.conf.dist` to `mod_ahbot.conf` and edit it. This will change the overall behavior of the bot. 44 | 45 | If you need to change a more specific value (for example the quotas of item sold), you will need to update values int the `mod_auctionhousebot` table or use the command line. 46 | 47 | The default quotas of all the auction houses for trade goods are: 48 | - Gray = 0 49 | - White = 27 50 | - Green = 12 51 | - Blue = 10 52 | - Purple = 1 53 | - Orange = 0 54 | - Yellow = 0 55 | 56 | The default quotas of all the auction houses for non trade goods items are: 57 | - Gray = 0 58 | - White = 10 59 | - Green = 30 60 | - Blue = 8 61 | - Purple = 2 62 | - Orange = 0 63 | - Yellow = 0 64 | 65 | The sum of the percentage for these categories must always be 100, or otherwise the defaults values will be used and the modifications will not be accepted. 66 | 67 | ## Credits 68 | 69 | - Ayase: ported the bot to AzerothCore 70 | - Other contributors (check the contributors list) 71 | -------------------------------------------------------------------------------- /src/AuctionHouseBotCommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2010 Trinity 3 | * Copyright (C) 2005-2009 MaNGOS 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef AUCTION_HOUSE_BOT_COMMON_H 21 | #define AUCTION_HOUSE_BOT_COMMON_H 22 | 23 | #include 24 | 25 | #include "Common.h" 26 | 27 | class AuctionHouseBot; 28 | 29 | // 30 | // Item quality 31 | // 32 | 33 | #define AHB_GREY ITEM_QUALITY_POOR 34 | #define AHB_WHITE ITEM_QUALITY_NORMAL 35 | #define AHB_GREEN ITEM_QUALITY_UNCOMMON 36 | #define AHB_BLUE ITEM_QUALITY_RARE 37 | #define AHB_PURPLE ITEM_QUALITY_EPIC 38 | #define AHB_ORANGE ITEM_QUALITY_LEGENDARY 39 | #define AHB_YELLOW ITEM_QUALITY_ARTIFACT 40 | #define AHB_MAX_QUALITY ITEM_QUALITY_ARTIFACT 41 | 42 | #define AHB_CLASS_WARRIOR 1 43 | #define AHB_CLASS_PALADIN 2 44 | #define AHB_CLASS_HUNTER 4 45 | #define AHB_CLASS_ROGUE 8 46 | #define AHB_CLASS_PRIEST 16 47 | #define AHB_CLASS_DK 32 48 | #define AHB_CLASS_SHAMAN 64 49 | #define AHB_CLASS_MAGE 128 50 | #define AHB_CLASS_WARLOCK 256 51 | #define AHB_CLASS_UNUSED 512 52 | #define AHB_CLASS_DRUID 1024 53 | 54 | // 55 | // Items classification 56 | // 57 | 58 | #define AHB_GREY_TG 0 59 | #define AHB_WHITE_TG 1 60 | #define AHB_GREEN_TG 2 61 | #define AHB_BLUE_TG 3 62 | #define AHB_PURPLE_TG 4 63 | #define AHB_ORANGE_TG 5 64 | #define AHB_YELLOW_TG 6 65 | 66 | #define AHB_GREY_I 7 67 | #define AHB_WHITE_I 8 68 | #define AHB_GREEN_I 9 69 | #define AHB_BLUE_I 10 70 | #define AHB_PURPLE_I 11 71 | #define AHB_ORANGE_I 12 72 | #define AHB_YELLOW_I 13 73 | 74 | #define AHB_ITEM_TYPE_OFFSET 7 75 | 76 | // 77 | // Chat GM commands 78 | // 79 | 80 | enum class AHBotCommand : uint32 81 | { 82 | buyer, 83 | seller, 84 | useMarketPrice, 85 | 86 | ahexpire, 87 | minitems, 88 | maxitems, 89 | percentages, 90 | minprice, 91 | maxprice, 92 | minbidprice, 93 | maxbidprice, 94 | maxstack, 95 | buyerprice, 96 | bidinterval, 97 | bidsperinterval 98 | }; 99 | 100 | // 101 | // Globals 102 | // 103 | 104 | extern std::set gBotsId; // Active bots players ids 105 | extern std::set gBots; // Active bots 106 | 107 | #endif // AUCTION_HOUSE_BOT_COMMON_H 108 | -------------------------------------------------------------------------------- /src/AuctionHouseBotWorldScript.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #include "Config.h" 6 | #include "Log.h" 7 | 8 | #include "AuctionHouseBot.h" 9 | #include "AuctionHouseBotCommon.h" 10 | #include "AuctionHouseBotWorldScript.h" 11 | 12 | // ============================================================================= 13 | // Initialization of the bot during the world startup 14 | // ============================================================================= 15 | 16 | AHBot_WorldScript::AHBot_WorldScript() : WorldScript("AHBot_WorldScript", { 17 | WORLDHOOK_ON_BEFORE_CONFIG_LOAD, 18 | WORLDHOOK_ON_STARTUP 19 | }) 20 | { 21 | 22 | } 23 | 24 | void AHBot_WorldScript::OnBeforeConfigLoad(bool reload) 25 | { 26 | // 27 | // Retrieve how many bots shall be operating on the auction market 28 | // 29 | 30 | bool debug = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG" , false); 31 | uint32 account = sConfigMgr->GetOption("AuctionHouseBot.Account", 0); 32 | uint32 player = sConfigMgr->GetOption("AuctionHouseBot.GUID" , 0); 33 | 34 | // 35 | // All the bots bound to the provided account will be used for auctioning, if GUID is zero. 36 | // Otherwise only the specified character is used. 37 | // 38 | 39 | if (account == 0 && player == 0) 40 | { 41 | LOG_ERROR("server.loading", "AHBot: Account id and player id missing from configuration; is that the right file?"); 42 | return; 43 | } 44 | else 45 | { 46 | QueryResult result = CharacterDatabase.Query("SELECT guid FROM characters WHERE account = {}", account); 47 | 48 | if (result) 49 | { 50 | gBotsId.clear(); 51 | 52 | do 53 | { 54 | Field* fields = result->Fetch(); 55 | uint32 botId = fields[0].Get(); 56 | 57 | if (player == 0) 58 | { 59 | if (debug) 60 | { 61 | LOG_INFO("server.loading", "AHBot: New bot to start, account={} character={}", account, botId); 62 | } 63 | 64 | gBotsId.insert(botId); 65 | } 66 | else 67 | { 68 | if (player == botId) 69 | { 70 | if (debug) 71 | { 72 | LOG_INFO("server.loading", "AHBot: Starting only one bot, account={} character={}", account, botId); 73 | } 74 | 75 | gBotsId.insert(botId); 76 | break; 77 | } 78 | } 79 | 80 | } while (result->NextRow()); 81 | } 82 | else 83 | { 84 | LOG_ERROR("server.loading", "AHBot: Could not query the database for characters of account {}", account); 85 | return; 86 | } 87 | } 88 | 89 | if (gBotsId.size() == 0) 90 | { 91 | LOG_ERROR("server.loading", "AHBot: no characters registered for account {}", account); 92 | return; 93 | } 94 | 95 | // 96 | // Start the bots only if the operation is a reload, otherwise let the OnStartup do the job 97 | // 98 | 99 | if (reload) 100 | { 101 | if (debug) 102 | { 103 | LOG_INFO("module", "AHBot: Reloading the bots"); 104 | } 105 | 106 | // 107 | // Clear the bots array; this way they wont be used anymore during the initialization stage. 108 | // 109 | 110 | DeleteBots(); 111 | 112 | // 113 | // Reload the configuration for the auction houses 114 | // 115 | 116 | gAllianceConfig->Initialize(gBotsId); 117 | gHordeConfig->Initialize (gBotsId); 118 | gNeutralConfig->Initialize (gBotsId); 119 | 120 | // 121 | // Start again the bots 122 | // 123 | 124 | PopulateBots(); 125 | } 126 | } 127 | 128 | void AHBot_WorldScript::OnStartup() 129 | { 130 | LOG_INFO("server.loading", "Initialize AuctionHouseBot..."); 131 | 132 | // 133 | // Initialize the configuration (done only once at startup) 134 | // 135 | 136 | gAllianceConfig->Initialize(gBotsId); 137 | gHordeConfig->Initialize (gBotsId); 138 | gNeutralConfig->Initialize (gBotsId); 139 | 140 | // 141 | // Starts the bots 142 | // 143 | 144 | PopulateBots(); 145 | } 146 | 147 | void AHBot_WorldScript::DeleteBots() 148 | { 149 | // 150 | // Save the old bots references. 151 | // 152 | 153 | std::set oldBots; 154 | 155 | for (AuctionHouseBot* bot: gBots) 156 | { 157 | oldBots.insert(bot); 158 | } 159 | 160 | // 161 | // Clear the bot list 162 | // 163 | 164 | gBots.clear(); 165 | 166 | // 167 | // Free the resources used up by the old bots 168 | // 169 | 170 | for (AuctionHouseBot* bot: oldBots) 171 | { 172 | delete bot; 173 | } 174 | } 175 | 176 | 177 | void AHBot_WorldScript::PopulateBots() 178 | { 179 | uint32 account = sConfigMgr->GetOption("AuctionHouseBot.Account", 0); 180 | 181 | // 182 | // Insert the bot in the list used for auction house iterations 183 | // 184 | 185 | gBots.clear(); 186 | 187 | for (uint32 id: gBotsId) 188 | { 189 | AuctionHouseBot* bot = new AuctionHouseBot(account, id); 190 | bot->Initialize(gAllianceConfig, gHordeConfig, gNeutralConfig); 191 | 192 | gBots.insert(bot); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/AuctionHouseBotAuctionHouseScript.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE 3 | */ 4 | 5 | #include "AuctionHouseMgr.h" 6 | #include "GameTime.h" 7 | 8 | #include "AuctionHouseBot.h" 9 | #include "AuctionHouseBotCommon.h" 10 | #include "AuctionHouseBotAuctionHouseScript.h" 11 | 12 | AHBot_AuctionHouseScript::AHBot_AuctionHouseScript() : AuctionHouseScript("AHBot_AuctionHouseScript", { 13 | AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_SUCCESSFUL_MAIL, 14 | AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_EXPIRED_MAIL, 15 | AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_OUTBIDDED_MAIL, 16 | AUCTIONHOUSEHOOK_ON_AUCTION_ADD, 17 | AUCTIONHOUSEHOOK_ON_AUCTION_REMOVE, 18 | AUCTIONHOUSEHOOK_ON_AUCTION_SUCCESSFUL, 19 | AUCTIONHOUSEHOOK_ON_AUCTION_EXPIRE, 20 | AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_UPDATE 21 | }) 22 | { 23 | 24 | } 25 | 26 | void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionSuccessfulMail( 27 | AuctionHouseMgr*, /*auctionHouseMgr*/ 28 | AuctionEntry*, /*auction*/ 29 | Player* owner, 30 | uint32&, /*owner_accId*/ 31 | uint32&, /*profit*/ 32 | bool& sendNotification, 33 | bool& updateAchievementCriteria, 34 | bool& /*sendMail*/) 35 | { 36 | if (owner && gBotsId.find(owner->GetGUID().GetCounter()) != gBotsId.end()) 37 | { 38 | sendNotification = false; 39 | updateAchievementCriteria = false; 40 | } 41 | } 42 | 43 | void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionExpiredMail( 44 | AuctionHouseMgr*, /* auctionHouseMgr */ 45 | AuctionEntry*, /* auction */ 46 | Player* owner, 47 | uint32&, /* owner_accId */ 48 | bool& sendNotification, 49 | bool& /* sendMail */) 50 | { 51 | if (owner && gBotsId.find(owner->GetGUID().GetCounter()) != gBotsId.end()) 52 | { 53 | sendNotification = false; 54 | } 55 | } 56 | 57 | void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionOutbiddedMail( 58 | AuctionHouseMgr*, /* auctionHouseMgr */ 59 | AuctionEntry* auction, 60 | Player* oldBidder, 61 | uint32&, /* oldBidder_accId */ 62 | Player* newBidder, 63 | uint32& newPrice, 64 | bool&, /* sendNotification */ 65 | bool& /* sendMail */) 66 | { 67 | if (oldBidder && !newBidder) 68 | { 69 | if (gBotsId.size() > 0) 70 | { 71 | // 72 | // Use a random bot id 73 | // 74 | 75 | uint32 randBot = urand(0, gBotsId.size() - 1); 76 | std::set::iterator it = gBotsId.begin(); 77 | std::advance(it, randBot); 78 | 79 | oldBidder->GetSession()->SendAuctionBidderNotification( 80 | (uint32)auction->GetHouseId(), 81 | auction->Id, 82 | ObjectGuid::Create(*it), 83 | newPrice, 84 | auction->GetAuctionOutBid(), 85 | auction->item_template); 86 | } 87 | } 88 | } 89 | 90 | void AHBot_AuctionHouseScript::OnAuctionAdd(AuctionHouseObject* /*ah*/, AuctionEntry* auction) 91 | { 92 | // 93 | // The the configuration for the auction house 94 | // 95 | 96 | AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); 97 | AHBConfig* config = gNeutralConfig; 98 | 99 | if (ahEntry) 100 | { 101 | if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) 102 | { 103 | config = gAllianceConfig; 104 | } 105 | else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) 106 | { 107 | config = gHordeConfig; 108 | } 109 | } 110 | 111 | // 112 | // Consider only those auctions handled by the bots 113 | // 114 | 115 | if (config->ConsiderOnlyBotAuctions) 116 | { 117 | if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) 118 | { 119 | return; 120 | } 121 | } 122 | 123 | // 124 | // Verify if we can operate on the item 125 | // 126 | 127 | Item* pItem = sAuctionMgr->GetAItem(auction->item_guid); 128 | 129 | if (!pItem) 130 | { 131 | if (config->DebugOut) 132 | { 133 | LOG_ERROR("module", "AHBot: Item {} for entryiD={} doesn't exist, perhaps bought already?", auction->item_guid.ToString(), auction->Id); 134 | } 135 | 136 | return; 137 | } 138 | 139 | // 140 | // Keeps updated the amount of items in the auction 141 | // 142 | 143 | ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); 144 | 145 | config->IncItemCounts(prototype->Class, prototype->Quality); 146 | 147 | if (config->DebugOut) 148 | { 149 | LOG_INFO("module", "AHBot: Auction Added ah={}, auctionId={}, totalAHItems = {}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); 150 | } 151 | } 152 | 153 | // this is called after the auction has been removed from the DB 154 | void AHBot_AuctionHouseScript::OnAuctionRemove(AuctionHouseObject* /*ah*/, AuctionEntry* auction) 155 | { 156 | // 157 | // Get the configuration for the auction house 158 | // 159 | AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); 160 | AHBConfig* config = gNeutralConfig; 161 | 162 | if (ahEntry) 163 | { 164 | if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) 165 | { 166 | config = gAllianceConfig; 167 | } 168 | else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) 169 | { 170 | config = gHordeConfig; 171 | } 172 | } 173 | 174 | // Consider only those auctions handled by the bots 175 | if (config->ConsiderOnlyBotAuctions) 176 | { 177 | if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) 178 | { 179 | return; 180 | } 181 | } 182 | 183 | // only get the prototype as actual item has already been removed from server AH in this callback 184 | ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); 185 | 186 | if (prototype) 187 | { 188 | config->DecItemCounts(prototype->Class, prototype->Quality); 189 | if (config->DebugOut) 190 | { 191 | LOG_INFO("module", "AHBot: Auction removed ah={}, auctionId={}, Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); 192 | } 193 | } 194 | else 195 | { 196 | // should never happen 197 | if (config->DebugOut) 198 | { 199 | LOG_ERROR("module", "AHBot: Item was removed but no prototype was found"); 200 | } 201 | } 202 | } 203 | 204 | void AHBot_AuctionHouseScript::OnAuctionSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* auction) 205 | { 206 | // 207 | // Get the configuration for the auction house 208 | // 209 | 210 | AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); 211 | AHBConfig* config = gNeutralConfig; 212 | 213 | if (ahEntry) 214 | { 215 | if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) 216 | { 217 | config = gAllianceConfig; 218 | } 219 | else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) 220 | { 221 | config = gHordeConfig; 222 | } 223 | } 224 | 225 | // 226 | // If the auction has been won, it means that it has been accepted by the market. 227 | // Use the buyout as a reference since the price for the bid is downgraded during selling. 228 | // 229 | 230 | if (config->DebugOut) 231 | { 232 | LOG_INFO("module", "AHBot: Auction successful ah={}, auctionId={}, Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); 233 | } 234 | 235 | config->UpdateItemStats(auction->item_template, auction->itemCount, auction->buyout); 236 | 237 | } 238 | 239 | void AHBot_AuctionHouseScript::OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* auction) 240 | { 241 | // 242 | // Get the configuration for the auction house 243 | // 244 | 245 | if (!auction) 246 | { 247 | LOG_ERROR("module", "AHBot: AHBot_AuctionHouseScript::OnAuctionExpire invalid AuctionEntry"); 248 | } 249 | 250 | AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); 251 | AHBConfig* config = gNeutralConfig; 252 | 253 | if (ahEntry) 254 | { 255 | if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) 256 | { 257 | config = gAllianceConfig; 258 | } 259 | else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) 260 | { 261 | config = gHordeConfig; 262 | } 263 | } 264 | 265 | // 266 | // If the auction expired, then it means that the bid was unwanted by the market. 267 | // Bid price is usually less or equal to the buyout, so this likely will bring the price down. 268 | // 269 | 270 | config->UpdateItemStats(auction->item_template, auction->itemCount, auction->bid); 271 | 272 | if (config->DebugOut) 273 | { 274 | LOG_INFO("module", "AHBot: Auction Expired ah={}, auctionId={} Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); 275 | } 276 | } 277 | 278 | void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrUpdate() 279 | { 280 | // 281 | // For every registered bot, perform an update 282 | // 283 | 284 | for (AuctionHouseBot* bot: gBots) 285 | { 286 | bot->Update(); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /src/AuctionHouseBotConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2010 Trinity 3 | * Copyright (C) 2005-2009 MaNGOS 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef AUCTION_HOUSE_BOT_CONFIG_H 21 | #define AUCTION_HOUSE_BOT_CONFIG_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "ObjectMgr.h" 28 | 29 | class AHBConfig 30 | { 31 | private: 32 | uint32 AHID; // Id 33 | uint32 AHFID; // Faction id 34 | 35 | uint32 minItems; 36 | uint32 maxItems; 37 | 38 | uint32 percentGreyTradeGoods; 39 | uint32 percentWhiteTradeGoods; 40 | uint32 percentGreenTradeGoods; 41 | uint32 percentBlueTradeGoods; 42 | uint32 percentPurpleTradeGoods; 43 | uint32 percentOrangeTradeGoods; 44 | uint32 percentYellowTradeGoods; 45 | 46 | uint32 percentGreyItems; 47 | uint32 percentWhiteItems; 48 | uint32 percentGreenItems; 49 | uint32 percentBlueItems; 50 | uint32 percentPurpleItems; 51 | uint32 percentOrangeItems; 52 | uint32 percentYellowItems; 53 | 54 | uint32 minPriceGrey; 55 | uint32 maxPriceGrey; 56 | uint32 minBidPriceGrey; 57 | uint32 maxBidPriceGrey; 58 | uint32 maxStackGrey; 59 | 60 | uint32 minPriceWhite; 61 | uint32 maxPriceWhite; 62 | uint32 minBidPriceWhite; 63 | uint32 maxBidPriceWhite; 64 | uint32 maxStackWhite; 65 | 66 | uint32 minPriceGreen; 67 | uint32 maxPriceGreen; 68 | uint32 minBidPriceGreen; 69 | uint32 maxBidPriceGreen; 70 | uint32 maxStackGreen; 71 | 72 | uint32 minPriceBlue; 73 | uint32 maxPriceBlue; 74 | uint32 minBidPriceBlue; 75 | uint32 maxBidPriceBlue; 76 | uint32 maxStackBlue; 77 | 78 | uint32 minPricePurple; 79 | uint32 maxPricePurple; 80 | uint32 minBidPricePurple; 81 | uint32 maxBidPricePurple; 82 | uint32 maxStackPurple; 83 | 84 | uint32 minPriceOrange; 85 | uint32 maxPriceOrange; 86 | uint32 minBidPriceOrange; 87 | uint32 maxBidPriceOrange; 88 | uint32 maxStackOrange; 89 | 90 | uint32 minPriceYellow; 91 | uint32 maxPriceYellow; 92 | uint32 minBidPriceYellow; 93 | uint32 maxBidPriceYellow; 94 | uint32 maxStackYellow; 95 | 96 | uint32 buyerPriceGrey; 97 | uint32 buyerPriceWhite; 98 | uint32 buyerPriceGreen; 99 | uint32 buyerPriceBlue; 100 | uint32 buyerPricePurple; 101 | uint32 buyerPriceOrange; 102 | uint32 buyerPriceYellow; 103 | uint32 buyerBiddingInterval; 104 | uint32 buyerBidsPerInterval; 105 | 106 | // 107 | // Amount of items to be sold in absolute values 108 | // 109 | 110 | uint32 greytgp; 111 | uint32 whitetgp; 112 | uint32 greentgp; 113 | uint32 bluetgp; 114 | uint32 purpletgp; 115 | uint32 orangetgp; 116 | uint32 yellowtgp; 117 | 118 | uint32 greyip; 119 | uint32 whiteip; 120 | uint32 greenip; 121 | uint32 blueip; 122 | uint32 purpleip; 123 | uint32 orangeip; 124 | uint32 yellowip; 125 | 126 | // 127 | // Situation of the auction house 128 | // 129 | 130 | uint32 greyTGoods; 131 | uint32 whiteTGoods; 132 | uint32 greenTGoods; 133 | uint32 blueTGoods; 134 | uint32 purpleTGoods; 135 | uint32 orangeTGoods; 136 | uint32 yellowTGoods; 137 | 138 | uint32 greyItems; 139 | uint32 whiteItems; 140 | uint32 greenItems; 141 | uint32 blueItems; 142 | uint32 purpleItems; 143 | uint32 orangeItems; 144 | uint32 yellowItems; 145 | 146 | // 147 | // Per-item statistics 148 | // 149 | 150 | std::map itemsCount; 151 | std::map itemsSum; 152 | std::map itemsPrice; 153 | 154 | void InitializeFromFile(); 155 | void InitializeFromSql(std::set botsIds); 156 | 157 | std::set getCommaSeparatedIntegers(std::string text); 158 | 159 | void DecItemCounts(uint32 ahbotItemType); 160 | void IncItemCounts(uint32 ahbotItemType); 161 | 162 | public: 163 | // 164 | // Debugging 165 | // 166 | 167 | bool DebugOut; 168 | bool DebugOutConfig; 169 | bool DebugOutFilters; 170 | bool DebugOutBuyer; 171 | bool DebugOutSeller; 172 | 173 | // 174 | // Tracing 175 | // 176 | 177 | bool TraceSeller; 178 | bool TraceBuyer; 179 | 180 | // 181 | // Setup 182 | // 183 | 184 | bool AHBSeller; 185 | bool AHBBuyer; 186 | bool UseBuyPriceForBuyer; 187 | bool UseBuyPriceForSeller; 188 | bool SellAtMarketPrice; 189 | uint32 MarketResetThreshold; 190 | bool ConsiderOnlyBotAuctions; 191 | uint32 ItemsPerCycle; 192 | 193 | // 194 | // Filters 195 | // 196 | 197 | bool Vendor_Items; 198 | bool Loot_Items; 199 | bool Other_Items; 200 | bool Vendor_TGs; 201 | bool Loot_TGs; 202 | bool Other_TGs; 203 | bool Profession_Items; 204 | 205 | bool No_Bind; 206 | bool Bind_When_Picked_Up; 207 | bool Bind_When_Equipped; 208 | bool Bind_When_Use; 209 | bool Bind_Quest_Item; 210 | 211 | uint32 DuplicatesCount; 212 | uint32 ElapsingTimeClass; 213 | 214 | bool DivisibleStacks; 215 | bool DisablePermEnchant; 216 | bool DisableConjured; 217 | bool DisableGems; 218 | bool DisableMoney; 219 | bool DisableMoneyLoot; 220 | bool DisableLootable; 221 | bool DisableKeys; 222 | bool DisableDuration; 223 | bool DisableBOP_Or_Quest_NoReqLevel; 224 | 225 | bool DisableWarriorItems; 226 | bool DisablePaladinItems; 227 | bool DisableHunterItems; 228 | bool DisableRogueItems; 229 | bool DisablePriestItems; 230 | bool DisableDKItems; 231 | bool DisableShamanItems; 232 | bool DisableMageItems; 233 | bool DisableWarlockItems; 234 | bool DisableUnusedClassItems; 235 | bool DisableDruidItems; 236 | 237 | uint32 DisableItemsBelowLevel; 238 | uint32 DisableItemsAboveLevel; 239 | 240 | uint32 DisableTGsBelowLevel; 241 | uint32 DisableTGsAboveLevel; 242 | 243 | uint32 DisableItemsBelowGUID; 244 | uint32 DisableItemsAboveGUID; 245 | 246 | uint32 DisableTGsBelowGUID; 247 | uint32 DisableTGsAboveGUID; 248 | 249 | uint32 DisableItemsBelowReqLevel; 250 | uint32 DisableItemsAboveReqLevel; 251 | 252 | uint32 DisableTGsBelowReqLevel; 253 | uint32 DisableTGsAboveReqLevel; 254 | 255 | uint32 DisableItemsBelowReqSkillRank; 256 | uint32 DisableItemsAboveReqSkillRank; 257 | 258 | uint32 DisableTGsBelowReqSkillRank; 259 | uint32 DisableTGsAboveReqSkillRank; 260 | 261 | // 262 | // Items validity for selling purposes 263 | // 264 | 265 | std::set NpcItems; 266 | std::set LootItems; 267 | std::set DisableItemStore; 268 | std::set SellerWhiteList; 269 | 270 | // 271 | // Bins for trade goods. 272 | // 273 | 274 | std::set GreyTradeGoodsBin; 275 | std::set WhiteTradeGoodsBin; 276 | std::set GreenTradeGoodsBin; 277 | std::set BlueTradeGoodsBin; 278 | std::set PurpleTradeGoodsBin; 279 | std::set OrangeTradeGoodsBin; 280 | std::set YellowTradeGoodsBin; 281 | 282 | // 283 | // Bins for items 284 | // 285 | 286 | std::set GreyItemsBin; 287 | std::set WhiteItemsBin; 288 | std::set GreenItemsBin; 289 | std::set BlueItemsBin; 290 | std::set PurpleItemsBin; 291 | std::set OrangeItemsBin; 292 | std::set YellowItemsBin; 293 | 294 | // 295 | // Constructors/destructors 296 | // 297 | 298 | AHBConfig(uint32 ahid, AHBConfig* conf); 299 | AHBConfig(uint32 ahid); 300 | AHBConfig(); 301 | ~AHBConfig(); 302 | 303 | // 304 | // Ruotines 305 | // 306 | 307 | void Initialize(std::set botsIds); 308 | void InitializeBins(); 309 | void Reset(); 310 | 311 | uint32 GetAHID(); 312 | uint32 GetAHFID(); 313 | 314 | void SetMinItems (uint32 value); 315 | uint32 GetMinItems (); 316 | 317 | void SetMaxItems (uint32 value); 318 | uint32 GetMaxItems (); 319 | 320 | void SetPercentages (uint32 greytg, uint32 whitetg, uint32 greentg, uint32 bluetg, uint32 purpletg, uint32 orangetg, uint32 yellowtg, 321 | uint32 greyi , uint32 whitei , uint32 greeni , uint32 bluei , uint32 purplei , uint32 orangei , uint32 yellowi); 322 | uint32 GetPercentages (uint32 color); 323 | 324 | void SetMinPrice (uint32 color, uint32 value); 325 | uint32 GetMinPrice (uint32 color); 326 | 327 | void SetMaxPrice (uint32 color, uint32 value); 328 | uint32 GetMaxPrice (uint32 color); 329 | 330 | void SetMinBidPrice (uint32 color, uint32 value); 331 | uint32 GetMinBidPrice (uint32 color); 332 | 333 | void SetMaxBidPrice (uint32 color, uint32 value); 334 | uint32 GetMaxBidPrice (uint32 color); 335 | 336 | void SetMaxStack (uint32 color, uint32 value); 337 | uint32 GetMaxStack (uint32 color); 338 | 339 | void SetBuyerPrice (uint32 color, uint32 value); 340 | uint32 GetBuyerPrice (uint32 color); 341 | 342 | void SetBiddingInterval(uint32 value); 343 | uint32 GetBiddingInterval(); 344 | 345 | void SetBidsPerInterval(uint32 value); 346 | uint32 GetBidsPerInterval(); 347 | 348 | void CalculatePercents (); 349 | // max number of items of type in AH based on maxItems 350 | uint32 GetMaximum (uint32 ahbotItemType); 351 | 352 | void DecItemCounts (uint32 Class, uint32 Quality); 353 | 354 | void IncItemCounts (uint32 Class, uint32 Quality); 355 | 356 | 357 | void ResetItemCounts (); 358 | uint32 TotalItemCounts (); 359 | 360 | uint32 GetItemCounts (uint32 color); 361 | 362 | void UpdateItemStats (uint32 id, uint32 stackSize, uint64 buyout); 363 | uint64 GetItemPrice (uint32 id); 364 | }; 365 | 366 | // 367 | // Globally defined configurations 368 | // 369 | 370 | extern AHBConfig* gAllianceConfig; 371 | extern AHBConfig* gHordeConfig; 372 | extern AHBConfig* gNeutralConfig; 373 | 374 | #endif // AUCTION_HOUSE_BOT_CONFIG_H 375 | -------------------------------------------------------------------------------- /conf/mod_ahbot.conf.dist: -------------------------------------------------------------------------------- 1 | [worldserver] 2 | 3 | ############################################################################### 4 | # AUCTION HOUSE BOT SETTINGS 5 | # 6 | # AuctionHouseBot.DEBUG 7 | # Enable/Disable Debugging output 8 | # Default 0 (disabled) 9 | # 10 | # AuctionHouseBot.DEBUG_CONFIG 11 | # Enable/Disable Debugging output from the configuration 12 | # Default 0 (disabled) 13 | # 14 | # AuctionHouseBot.DEBUG_FILTERS 15 | # Enable/Disable Debugging output from Filters 16 | # Default 0 (disabled) 17 | # 18 | # AuctionHouseBot.DEBUG_BUYER 19 | # Enable/Disable Debugging output from buyer 20 | # Default 0 (disabled) 21 | # 22 | # AuctionHouseBot.DEBUG_SELLER 23 | # Enable/Disable Debugging output from seller 24 | # Default 0 (disabled) 25 | # 26 | # AuctionHouseBot.TRACE_SELLER 27 | # Enable/Disable tracing for the sold items 28 | # Default 0 (disabled) 29 | # 30 | # AuctionHouseBot.TRACE_BUYER 31 | # Enable/Disable tracing for the bought items 32 | # Default 0 (disabled) 33 | # 34 | # AuctionHouseBot.EnableSeller 35 | # Enable/Disable the part of AHBot that puts items up for auction 36 | # Default 0 (disabled) 37 | # 38 | # AuctionHouseBot.EnableBuyer 39 | # Enable/Disable the part of AHBot that buys items from players 40 | # Default 0 (disabled) 41 | # 42 | # AuctionHouseBot.UseBuyPriceForSeller 43 | # Should the Seller use BuyPrice or SellPrice to determine Bid Prices 44 | # Default 0 (use SellPrice) 45 | # 46 | # AuctionHouseBot.UseBuyPriceForBuyer 47 | # Should the Buyer use BuyPrice or SellPrice to determine Bid Prices 48 | # Default 0 (use SellPrice) 49 | # 50 | # AuctionHouseBot.UseMarketPriceForSeller 51 | # Should the Seller use the market price for its auctions? 52 | # Default 0 (disabled) 53 | # 54 | # AuctionHouseBot.MarketResetThreshold 55 | # How many auctions of the same item are necessary before the plain priceis adopted. 56 | # Before reaching this threshold, the price increase/decrease according to an heuristic. 57 | # Set this variable to a lower value to have a fast reacting market price, 58 | # to an high value to smooth the oscillations in prices. 59 | # Default 25 60 | # 61 | # Auction House Bot character data 62 | # AuctionHouseBot.Account is the account number 63 | # (in realmd->account table) of the player you want to run 64 | # as the auction bot. 65 | # AuctionHouseBot.GUID is the GUID (in characters->characters table) 66 | # of the player you want to run as the auction bot. 67 | # Default: 0 (Auction House Bot disabled) 68 | # 69 | # AuctionHouseBot.ItemsPerCycle 70 | # Number of Items to Add/Remove from the AH during mass operations 71 | # Default 200 72 | # 73 | # AuctionHouseBot.ConsiderOnlyBotAuctions 74 | # Ignore player auctions and consider only bot ones when keeping track of the numer of auctions in place. 75 | # This allow to keep a background noise in the market even when lot of players are in. 76 | # If this is not set, players acutions are counted in the valid auctions and you will need to greatly increase the maxitems SQL values to 77 | # allow the bot to operate on the market. If this is set the players auctions will not be considered. 78 | # Default 0 (False) 79 | # 80 | # AuctionHouseBot.DuplicatesCount 81 | # The maximum amount of duplicates stacks present in the market sold by the bot. 82 | # If set to zero then no limits are set in place. 83 | # Default 0 84 | # 85 | # AuctionHouseBot.DivisibleStacks 86 | # Sell items in stack sizes which depends on the maximum amount per stack. 87 | # For example, an item with max stack size 20 will be sold in 5, 10 15 and 20 stacks, and not at random. 88 | # Default 0 (False) 89 | # 90 | # AuctionHouseBot.ElapsingTimeClass 91 | # The elapsing time for the sold items. There are three classes: 92 | # 0 = long, auctions last from 1 to 3 days 93 | # 1 = medium, auctions last from 1 to 24 hours 94 | # 2 = shorts, auctions last from 10 to 60 minutes 95 | # Default 1 96 | # 97 | ############################################################################### 98 | 99 | AuctionHouseBot.DEBUG = 0 100 | AuctionHouseBot.DEBUG_CONFIG = 0 101 | AuctionHouseBot.DEBUG_FILTERS = 0 102 | AuctionHouseBot.DEBUG_BUYER = 0 103 | AuctionHouseBot.DEBUG_SELLER = 0 104 | AuctionHouseBot.TRACE_SELLER = 0 105 | AuctionHouseBot.TRACE_BUYER = 0 106 | 107 | AuctionHouseBot.EnableSeller = 0 108 | AuctionHouseBot.EnableBuyer = 0 109 | AuctionHouseBot.UseBuyPriceForSeller = 0 110 | AuctionHouseBot.UseBuyPriceForBuyer = 0 111 | AuctionHouseBot.UseMarketPriceForSeller = 0 112 | AuctionHouseBot.MarketResetThreshold = 25 113 | AuctionHouseBot.Account = 0 114 | AuctionHouseBot.GUID = 0 115 | AuctionHouseBot.ItemsPerCycle = 200 116 | AuctionHouseBot.ConsiderOnlyBotAuctions = 0 117 | AuctionHouseBot.DuplicatesCount = 0 118 | AuctionHouseBot.DivisibleStacks = 0 119 | AuctionHouseBot.ElapsingTimeClass = 1 120 | 121 | ############################################################################### 122 | # AUCTION HOUSE BOT FILTERS PART 1 123 | # 124 | # AuctionHouseBot.VendorItems 125 | # Include items that can be bought from vendors. 126 | # Default 0 (False) 127 | # 128 | # AuctionHouseBot.VendorTradeGoods 129 | # Include Trade Goods that can be bought from vendors. 130 | # Default 0 (False) 131 | # 132 | # AuctionHouseBot.LootItems 133 | # Include items that can be looted or fished for. 134 | # Default 1 (True) 135 | # 136 | # AuctionHouseBot.LootTradeGoods 137 | # Include Trade Goods that can be looted or fished for. 138 | # Default 1 (True) 139 | # 140 | # AuctionHouseBot.OtherItems 141 | # Include misc. items. 142 | # Default 0 (False) 143 | # 144 | # AuctionHouseBot.OtherTradeGoods 145 | # Include misc. Trade Goods. 146 | # Default 0 (False) 147 | # 148 | # AuctionHouseBot.ProfessionItems 149 | # Include items that are necessary for professions 150 | # Default 0 (False) 151 | # 152 | # AuctionHouseBot.Bonding_types 153 | # Indicates which bonding types to allow seller to put up for auction 154 | # No_Bind 155 | # Default 1 (True) 156 | # Bind_When_Picked_Up 157 | # Default 0 (False) 158 | # Bind_When_Equipped 159 | # Default 1 (True) 160 | # Bind_When_Use 161 | # Default 1 (True) 162 | # Bind_Quest_Item 163 | # Default 0 (False) 164 | # 165 | # AuctionHouseBot.DisablePermEnchant 166 | # Disable Items with a Permanent Enchantment 167 | # Default 0 (False) 168 | # 169 | # AuctionHouseBot.DisableConjured 170 | # Disable Conjured Items 171 | # Default 0 (False) 172 | # 173 | # AuctionHouseBot.DisableGems 174 | # Disable Gems 175 | # Default 0 (False) 176 | # 177 | # AuctionHouseBot.DisableMoney 178 | # Disable Items that are used as money 179 | # Default 0 (False) 180 | # 181 | # AuctionHouseBot.DisableMoneyLoot 182 | # Disable Items that have Money as a loot 183 | # Default 0 (False) 184 | # 185 | # AuctionHouseBot.DisableLootable 186 | # Disable Items that have other items as loot 187 | # Default 0 (False) 188 | # 189 | # AuctionHouseBot.DisableKeys 190 | # Disable Items that are keys 191 | # Default 0 (False) 192 | # 193 | # AuctionHouseBot.DisableDuration 194 | # Disable Items with a duration 195 | # Default 0 (False) 196 | # 197 | # AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel 198 | # Disable items that are BOP or Quest Item 199 | # with a Required level that is less than the Item Level 200 | # (This prevents a level 10 with a level 60 weapon or armor) 201 | # (May need further refinement) 202 | # Default 0 (False) 203 | # 204 | ############################################################################### 205 | 206 | AuctionHouseBot.VendorItems = 0 207 | AuctionHouseBot.VendorTradeGoods = 0 208 | AuctionHouseBot.LootItems = 1 209 | AuctionHouseBot.LootTradeGoods = 1 210 | AuctionHouseBot.OtherItems = 0 211 | AuctionHouseBot.OtherTradeGoods = 0 212 | AuctionHouseBot.ProfessionItems = 0 213 | AuctionHouseBot.No_Bind = 1 214 | AuctionHouseBot.Bind_When_Picked_Up = 0 215 | AuctionHouseBot.Bind_When_Equipped = 1 216 | AuctionHouseBot.Bind_When_Use = 1 217 | AuctionHouseBot.Bind_Quest_Item = 0 218 | AuctionHouseBot.DisablePermEnchant = 0 219 | AuctionHouseBot.DisableConjured = 0 220 | AuctionHouseBot.DisableGems = 0 221 | AuctionHouseBot.DisableMoney = 0 222 | AuctionHouseBot.DisableMoneyLoot = 0 223 | AuctionHouseBot.DisableLootable = 0 224 | AuctionHouseBot.DisableKeys = 0 225 | AuctionHouseBot.DisableDuration = 0 226 | AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel = 0 227 | 228 | ############################################################################### 229 | # AUCTION HOUSE BOT FILTERS PART 2 230 | # 231 | # These Filters are boolean (0 or 1) and will disable items that are 232 | # specifically meant for the Class named. 233 | # (UnusedClass is Class 10, which was skipped for some reason) 234 | # Default 0 (allowed) 235 | # 236 | ############################################################################### 237 | 238 | AuctionHouseBot.DisableWarriorItems = 0 239 | AuctionHouseBot.DisablePaladinItems = 0 240 | AuctionHouseBot.DisableHunterItems = 0 241 | AuctionHouseBot.DisableRogueItems = 0 242 | AuctionHouseBot.DisablePriestItems = 0 243 | AuctionHouseBot.DisableDKItems = 0 244 | AuctionHouseBot.DisableShamanItems = 0 245 | AuctionHouseBot.DisableMageItems = 0 246 | AuctionHouseBot.DisableWarlockItems = 0 247 | AuctionHouseBot.DisableUnusedClassItems = 0 248 | AuctionHouseBot.DisableDruidItems = 0 249 | 250 | ############################################################################### 251 | # AUCTION HOUSE BOT FILTERS PART 3 252 | # 253 | # AuctionHouseBot.DisabledItems 254 | # Prevent Seller from listing specific item(s) 255 | # (not used anymore, see table "mod_auctionhousebot_disabled_items") 256 | # 257 | # AuctionHouseBot.DisableItemsBelowLevel 258 | # Prevent Seller from listing Items below this Level 259 | # Default 0 (Off) 260 | # 261 | # AuctionHouseBot.DisableItemsAboveLevel 262 | # Prevent Seller from listing Items above this Level 263 | # Default 0 (Off) 264 | # 265 | # AuctionHouseBot.DisableTGsBelowLevel 266 | # Prevent Seller from listing Trade Goods below this Level 267 | # Default 0 (Off) 268 | # 269 | # AuctionHouseBot.DisableTGsAboveLevel 270 | # Prevent Seller from listing Trade Goods above this Level 271 | # Default 0 (Off) 272 | # 273 | # AuctionHouseBot.DisableItemsBelowGUID 274 | # Prevent Seller from listing Items below this GUID 275 | # Default 0 (Off) 276 | # 277 | # AuctionHouseBot.DisableItemsAboveGUID 278 | # Prevent Seller from listing Items above this GUID 279 | # Default 0 (Off) 280 | # 281 | # AuctionHouseBot.DisableTGsBelowGUID 282 | # Prevent Seller from listing Trade Goods below this GUID 283 | # Default 0 (Off) 284 | # 285 | # AuctionHouseBot.DisableTGsAboveGUID 286 | # Prevent Seller from listing Trade Goods above this GUID 287 | # Default 0 (Off) 288 | # 289 | # AuctionHouseBot.DisableItemsBelowReqLevel 290 | # Prevent Seller from listing Items below this Required Level 291 | # Default 0 (Off) 292 | # 293 | # AuctionHouseBot.DisableItemsAboveReqLevel 294 | # Prevent Seller from listing Items above this Required Level 295 | # Default 0 (Off) 296 | # 297 | # AuctionHouseBot.DisableTGsBelowReqLevel 298 | # Prevent Seller from listing Trade Goods below this Required Level 299 | # Default 0 (Off) 300 | # 301 | # AuctionHouseBot.DisableTGsAboveReqLevel 302 | # Prevent Seller from listing Trade Goods above this Required Level 303 | # Default 0 (Off) 304 | # 305 | # AuctionHouseBot.DisableItemsBelowReqSkillRank 306 | # Prevent Seller from listing Items below this Required Skill Rank 307 | # Default 0 (Off) 308 | # 309 | # AuctionHouseBot.DisableItemsAboveReqSkillRank 310 | # Prevent Seller from listing Items above this Required Skill Rank 311 | # Default 0 (Off) 312 | # 313 | # AuctionHouseBot.DisableTGsBelowReqSkillRank 314 | # Prevent Seller from listing Trade Goods below this Required Skill Rank 315 | # Default 0 (Off) 316 | # 317 | # AuctionHouseBot.DisableTGsAboveReqSkillRank 318 | # Prevent Seller from listing Trade Goods above this Required Skill Rank 319 | # Default 0 (Off) 320 | # 321 | ############################################################################### 322 | 323 | AuctionHouseBot.DisableItemsBelowLevel = 0 324 | AuctionHouseBot.DisableItemsAboveLevel = 0 325 | AuctionHouseBot.DisableTGsBelowLevel = 0 326 | AuctionHouseBot.DisableTGsAboveLevel = 0 327 | AuctionHouseBot.DisableItemsBelowGUID = 0 328 | AuctionHouseBot.DisableItemsAboveGUID = 0 329 | AuctionHouseBot.DisableTGsBelowGUID = 0 330 | AuctionHouseBot.DisableTGsAboveGUID = 0 331 | AuctionHouseBot.DisableItemsBelowReqLevel = 0 332 | AuctionHouseBot.DisableItemsAboveReqLevel = 0 333 | AuctionHouseBot.DisableTGsBelowReqLevel = 0 334 | AuctionHouseBot.DisableTGsAboveReqLevel = 0 335 | AuctionHouseBot.DisableItemsBelowReqSkillRank = 0 336 | AuctionHouseBot.DisableItemsAboveReqSkillRank = 0 337 | AuctionHouseBot.DisableTGsBelowReqSkillRank = 0 338 | AuctionHouseBot.DisableTGsAboveReqSkillRank = 0 339 | 340 | ############################################################################### 341 | # AUCTION HOUSE BOT FILTERS PART 4 342 | # 343 | # AuctionHouseBot.SellerWhiteList 344 | # Bypass the values of the disabled items table and only allows selling of the selected items 345 | # Values here must be the item template id separated with a comma (eg "1, 2, 3") 346 | # Default "" (Empty) 347 | # 348 | ############################################################################### 349 | 350 | AuctionHouseBot.SellerWhiteList = "" 351 | -------------------------------------------------------------------------------- /src/cs_ah_bot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2012 TrinityCore 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program. If not, see . 16 | */ 17 | 18 | /* ScriptData 19 | Name: ah_bot_commandscript 20 | %Complete: 100 21 | Comment: All ah_bot related commands 22 | Category: commandscripts 23 | EndScriptData */ 24 | 25 | #include "ScriptMgr.h" 26 | #include "Chat.h" 27 | #include "AuctionHouseBot.h" 28 | #include "Config.h" 29 | 30 | #if AC_COMPILER == AC_COMPILER_GNU 31 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 32 | #endif 33 | 34 | using namespace Acore::ChatCommands; 35 | 36 | class ah_bot_commandscript : public CommandScript 37 | { 38 | private: 39 | static ItemQualities stringToItemQualities(const char* name, int length) 40 | { 41 | // 42 | // Translates a string into ItemQualities enum 43 | // 44 | 45 | if (strncmp(name, "grey", length) == 0) 46 | { 47 | return ITEM_QUALITY_POOR; 48 | } 49 | 50 | if (strncmp(name, "white", length) == 0) 51 | { 52 | return ITEM_QUALITY_NORMAL; 53 | } 54 | 55 | if (strncmp(name, "green", length) == 0) 56 | { 57 | return ITEM_QUALITY_UNCOMMON; 58 | } 59 | 60 | if (strncmp(name, "blue", length) == 0) 61 | { 62 | return ITEM_QUALITY_RARE; 63 | } 64 | 65 | if (strncmp(name, "purple", length) == 0) 66 | { 67 | return ITEM_QUALITY_EPIC; 68 | } 69 | 70 | if (strncmp(name, "orange", length) == 0) 71 | { 72 | return ITEM_QUALITY_LEGENDARY; 73 | } 74 | 75 | if (strncmp(name, "yellow", length) == 0) 76 | { 77 | return ITEM_QUALITY_ARTIFACT; 78 | } 79 | 80 | return static_cast(-1); // Invalid 81 | } 82 | 83 | public: 84 | ah_bot_commandscript() : CommandScript("ah_bot_commandscript") 85 | { 86 | 87 | } 88 | 89 | std::vector GetCommands() const override 90 | { 91 | static std::vector commandTable = 92 | { 93 | { "ahbotoptions", HandleAHBotOptionsCommand, SEC_GAMEMASTER, Console::Yes } 94 | }; 95 | 96 | return commandTable; 97 | } 98 | 99 | static bool HandleAHBotOptionsCommand(ChatHandler* handler, const char*args) 100 | { 101 | uint32 ahMapID = 0; 102 | char* opt = strtok((char*)args, " "); 103 | 104 | if (!opt) 105 | { 106 | handler->PSendSysMessage("Invalid syntax"); 107 | handler->PSendSysMessage("Try ahbotoptions help to see a list of options."); 108 | 109 | return false; 110 | } 111 | 112 | // 113 | // Commands which does not requires an AH 114 | // 115 | 116 | int l = strlen(opt); 117 | 118 | if (strncmp(opt, "buyer", l) == 0) 119 | { 120 | char* param1 = strtok(NULL, " "); 121 | 122 | if (!param1) 123 | { 124 | handler->PSendSysMessage("Syntax is: ahbotoptions buyer $state (0 off 1 on)"); 125 | return false; 126 | } 127 | 128 | for (AuctionHouseBot* bot: gBots) 129 | { 130 | bot->Commands(AHBotCommand::buyer, 0, 0, param1); 131 | } 132 | 133 | return true; 134 | } 135 | else if (strncmp(opt, "seller", l) == 0) 136 | { 137 | char* param1 = strtok(NULL, " "); 138 | 139 | if (!param1) 140 | { 141 | handler->PSendSysMessage("Syntax is: ahbotoptions seller $state (0 off 1 on)"); 142 | return false; 143 | } 144 | 145 | for (AuctionHouseBot* bot: gBots) 146 | { 147 | bot->Commands(AHBotCommand::seller, 0, 0, param1); 148 | } 149 | 150 | return true; 151 | } 152 | else if (strncmp(opt, "usemarketprice", l) == 0) 153 | { 154 | char* param1 = strtok(NULL, " "); 155 | 156 | if (!param1) 157 | { 158 | handler->PSendSysMessage("Syntax is: ahbotoptions useMarketPrice $state (0 off 1 on)"); 159 | return false; 160 | } 161 | 162 | for (AuctionHouseBot* bot : gBots) 163 | { 164 | bot->Commands(AHBotCommand::useMarketPrice, 0, 0, param1); 165 | } 166 | 167 | return true; 168 | } 169 | 170 | // 171 | // Retrieve the auction house type 172 | // 173 | 174 | char* ahMapIdStr = strtok(NULL, " "); 175 | 176 | if (ahMapIdStr) 177 | { 178 | ahMapID = uint32(strtoul(ahMapIdStr, NULL, 0)); 179 | 180 | switch (ahMapID) 181 | { 182 | case 2: 183 | case 6: 184 | case 7: 185 | break; 186 | default: 187 | opt = NULL; 188 | break; 189 | } 190 | } 191 | 192 | // 193 | // Syntax check 194 | // 195 | 196 | if (!opt) 197 | { 198 | handler->PSendSysMessage("Invalid syntax; the auction house id must be 2, 6 or 7"); 199 | return false; 200 | } 201 | 202 | // 203 | // Commands that do requires an AH id to be performed 204 | // 205 | 206 | if (strncmp(opt, "help", l) == 0) 207 | { 208 | handler->PSendSysMessage("AHBot commands:"); 209 | handler->PSendSysMessage("buyer - enable/disable buyer"); 210 | handler->PSendSysMessage("seller - enable/disabler seller"); 211 | handler->PSendSysMessage("usemarketprice - enable/disabler selling at market price"); 212 | handler->PSendSysMessage("ahexpire - remove all bot auctions"); 213 | handler->PSendSysMessage("minitems - set min auctions"); 214 | handler->PSendSysMessage("maxitems - set max auctions"); 215 | handler->PSendSysMessage("percentages - set selling percentages"); 216 | handler->PSendSysMessage("minprice - set min price"); 217 | handler->PSendSysMessage("maxprice - set max price"); 218 | handler->PSendSysMessage("minbidprice - set min bid price for buyer"); 219 | handler->PSendSysMessage("maxbidprice - set max bid price for buyer"); 220 | handler->PSendSysMessage("maxstack - set max stack"); 221 | handler->PSendSysMessage("buyerprice - set the buyer price policy"); 222 | handler->PSendSysMessage("bidinterval - set the bid interval for buyer"); 223 | handler->PSendSysMessage("bidsperinterval - set the bid amount for buyer"); 224 | 225 | return true; 226 | } 227 | else if (strncmp(opt, "ahexpire", l) == 0) 228 | { 229 | if (!ahMapIdStr) 230 | { 231 | handler->PSendSysMessage("Syntax is: ahbotoptions ahexpire $ahMapID (2, 6 or 7)"); 232 | return false; 233 | } 234 | 235 | for (AuctionHouseBot* bot: gBots) 236 | { 237 | bot->Commands(AHBotCommand::ahexpire, ahMapID, 0, NULL); 238 | } 239 | } 240 | else if (strncmp(opt, "minitems", l) == 0) 241 | { 242 | char* param1 = strtok(NULL, " "); 243 | 244 | if (!ahMapIdStr || !param1) 245 | { 246 | handler->PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems"); 247 | return false; 248 | } 249 | 250 | for (AuctionHouseBot* bot : gBots) 251 | { 252 | bot->Commands(AHBotCommand::minitems, ahMapID, 0, param1); 253 | } 254 | } 255 | else if (strncmp(opt, "maxitems", l) == 0) 256 | { 257 | char* param1 = strtok(NULL, " "); 258 | 259 | if (!ahMapIdStr || !param1) 260 | { 261 | handler->PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems"); 262 | return false; 263 | } 264 | 265 | for (AuctionHouseBot* bot: gBots) 266 | { 267 | bot->Commands(AHBotCommand::maxitems, ahMapID, 0, param1); 268 | } 269 | } 270 | else if (strncmp(opt, "percentages", l) == 0) 271 | { 272 | char* param1 = strtok(NULL, " "); 273 | char* param2 = strtok(NULL, " "); 274 | char* param3 = strtok(NULL, " "); 275 | char* param4 = strtok(NULL, " "); 276 | char* param5 = strtok(NULL, " "); 277 | char* param6 = strtok(NULL, " "); 278 | char* param7 = strtok(NULL, " "); 279 | char* param8 = strtok(NULL, " "); 280 | char* param9 = strtok(NULL, " "); 281 | char* param10 = strtok(NULL, " "); 282 | char* param11 = strtok(NULL, " "); 283 | char* param12 = strtok(NULL, " "); 284 | char* param13 = strtok(NULL, " "); 285 | char* param14 = strtok(NULL, " "); 286 | 287 | if (!ahMapIdStr || !param14) 288 | { 289 | handler->PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); 290 | handler->PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); 291 | handler->PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); 292 | handler->PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); 293 | 294 | return false; 295 | } 296 | 297 | uint32 greytg = uint32(strtoul(param1 , NULL, 0)); 298 | uint32 whitetg = uint32(strtoul(param2 , NULL, 0)); 299 | uint32 greentg = uint32(strtoul(param3 , NULL, 0)); 300 | uint32 bluetg = uint32(strtoul(param4 , NULL, 0)); 301 | uint32 purpletg = uint32(strtoul(param5 , NULL, 0)); 302 | uint32 orangetg = uint32(strtoul(param6 , NULL, 0)); 303 | uint32 yellowtg = uint32(strtoul(param7 , NULL, 0)); 304 | uint32 greyi = uint32(strtoul(param8 , NULL, 0)); 305 | uint32 whitei = uint32(strtoul(param9 , NULL, 0)); 306 | uint32 greeni = uint32(strtoul(param10, NULL, 0)); 307 | uint32 bluei = uint32(strtoul(param11, NULL, 0)); 308 | uint32 purplei = uint32(strtoul(param12, NULL, 0)); 309 | uint32 orangei = uint32(strtoul(param13, NULL, 0)); 310 | uint32 yellowi = uint32(strtoul(param14, NULL, 0)); 311 | 312 | uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; 313 | 314 | if (totalPercent == 0 || totalPercent != 100) 315 | { 316 | handler->PSendSysMessage("The total must add up to 100%%"); 317 | 318 | return false; 319 | } 320 | 321 | char param[100] = { 0 }; 322 | 323 | strcat(param, param1); 324 | strcat(param, " "); 325 | strcat(param, param2); 326 | strcat(param, " "); 327 | strcat(param, param3); 328 | strcat(param, " "); 329 | strcat(param, param4); 330 | strcat(param, " "); 331 | strcat(param, param5); 332 | strcat(param, " "); 333 | strcat(param, param6); 334 | strcat(param, " "); 335 | strcat(param, param7); 336 | strcat(param, " "); 337 | strcat(param, param8); 338 | strcat(param, " "); 339 | strcat(param, param9); 340 | strcat(param, " "); 341 | strcat(param, param10); 342 | strcat(param, " "); 343 | strcat(param, param11); 344 | strcat(param, " "); 345 | strcat(param, param12); 346 | strcat(param, " "); 347 | strcat(param, param13); 348 | strcat(param, " "); 349 | strcat(param, param14); 350 | 351 | for (AuctionHouseBot* bot: gBots) 352 | { 353 | bot->Commands(AHBotCommand::percentages, ahMapID, 0, param); 354 | } 355 | } 356 | else if (strncmp(opt, "minprice", l) == 0) 357 | { 358 | char* param1 = strtok(NULL, " "); 359 | char* param2 = strtok(NULL, " "); 360 | 361 | if (!ahMapIdStr || !param1 || !param2) 362 | { 363 | handler->PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 364 | return false; 365 | } 366 | 367 | auto quality = stringToItemQualities(param1, l); 368 | 369 | if (quality != static_cast(-1)) 370 | { 371 | for (AuctionHouseBot* bot: gBots) 372 | { 373 | bot->Commands(AHBotCommand::minprice, ahMapID, quality, param2); 374 | } 375 | } 376 | else 377 | { 378 | handler->PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 379 | return false; 380 | } 381 | } 382 | else if (strncmp(opt, "maxprice", l) == 0) 383 | { 384 | char* param1 = strtok(NULL, " "); 385 | char* param2 = strtok(NULL, " "); 386 | 387 | if (!ahMapIdStr || !param1 || !param2) 388 | { 389 | handler->PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 390 | return false; 391 | } 392 | 393 | auto quality = stringToItemQualities(param1, l); 394 | 395 | if (quality != static_cast(-1)) 396 | { 397 | for (AuctionHouseBot* bot: gBots) 398 | { 399 | bot->Commands(AHBotCommand::maxprice, ahMapID, quality, param2); 400 | } 401 | } 402 | else 403 | { 404 | handler->PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 405 | return false; 406 | } 407 | } 408 | else if (strncmp(opt, "minbidprice", l) == 0) 409 | { 410 | char* param1 = strtok(NULL, " "); 411 | char* param2 = strtok(NULL, " "); 412 | 413 | if (!ahMapIdStr || !param2 || !param2) 414 | { 415 | handler->PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 416 | return false; 417 | } 418 | 419 | uint32 minBidPrice = uint32(strtoul(param2, NULL, 0)); 420 | 421 | if (minBidPrice < 1 || minBidPrice > 100) 422 | { 423 | handler->PSendSysMessage("The min bid price multiplier must be between 1 and 100"); 424 | return false; 425 | } 426 | 427 | auto quality = stringToItemQualities(param1, l); 428 | 429 | if (quality != static_cast(-1)) 430 | { 431 | for (AuctionHouseBot* bot: gBots) 432 | { 433 | bot->Commands(AHBotCommand::minbidprice, ahMapID, quality, param2); 434 | } 435 | } 436 | else 437 | { 438 | handler->PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 439 | return false; 440 | } 441 | } 442 | else if (strncmp(opt, "maxbidprice", l) == 0) 443 | { 444 | char* param1 = strtok(NULL, " "); 445 | char* param2 = strtok(NULL, " "); 446 | 447 | if (!ahMapIdStr || !param1 || !param2) 448 | { 449 | handler->PSendSysMessage("Syntax is: ahbotoptions maxbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 450 | return false; 451 | } 452 | 453 | uint32 maxBidPrice = uint32(strtoul(param2, NULL, 0)); 454 | 455 | if (maxBidPrice < 1 || maxBidPrice > 100) 456 | { 457 | handler->PSendSysMessage("The max bid price multiplier must be between 1 and 100"); 458 | return false; 459 | } 460 | 461 | auto quality = stringToItemQualities(param1, l); 462 | 463 | if (quality != static_cast(-1)) 464 | { 465 | for (AuctionHouseBot* bot: gBots) 466 | { 467 | bot->Commands(AHBotCommand::maxbidprice, ahMapID, quality, param2); 468 | } 469 | } 470 | else 471 | { 472 | handler->PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); 473 | return false; 474 | } 475 | } 476 | else if (strncmp(opt, "maxstack",l) == 0) 477 | { 478 | char* param1 = strtok(NULL, " "); 479 | char* param2 = strtok(NULL, " "); 480 | 481 | if (!ahMapIdStr || !param1 || !param2) 482 | { 483 | handler->PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); 484 | return false; 485 | } 486 | 487 | // uint32 maxStack = uint32(strtoul(param2, NULL, 0)); 488 | // if (maxStack < 0) 489 | // { 490 | // handler->PSendSysMessage("maxstack can't be a negative number."); 491 | // return false; 492 | // } 493 | 494 | auto quality = stringToItemQualities(param1, l); 495 | 496 | if (quality != static_cast(-1)) 497 | { 498 | for (AuctionHouseBot* bot: gBots) 499 | { 500 | bot->Commands(AHBotCommand::maxstack, ahMapID, quality, param2); 501 | } 502 | } 503 | else 504 | { 505 | handler->PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); 506 | return false; 507 | } 508 | } 509 | else if (strncmp(opt, "buyerprice", l) == 0) 510 | { 511 | char* param1 = strtok(NULL, " "); 512 | char* param2 = strtok(NULL, " "); 513 | 514 | if (!ahMapIdStr || !param1 || !param2) 515 | { 516 | handler->PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); 517 | return false; 518 | } 519 | 520 | auto quality = stringToItemQualities(param1, l); 521 | 522 | if (quality != static_cast(-1)) 523 | { 524 | for (AuctionHouseBot* bot: gBots) 525 | { 526 | bot->Commands(AHBotCommand::buyerprice, ahMapID, quality, param2); 527 | } 528 | } 529 | else 530 | { 531 | handler->PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); 532 | return false; 533 | } 534 | } 535 | else if (strncmp(opt, "bidinterval", l) == 0) 536 | { 537 | char* param1 = strtok(NULL, " "); 538 | 539 | if (!ahMapIdStr || !param1) 540 | { 541 | handler->PSendSysMessage("Syntax is: ahbotoptions bidinterval $ahMapID (2, 6 or 7) $interval(in minutes)"); 542 | return false; 543 | } 544 | 545 | for (AuctionHouseBot* bot: gBots) 546 | { 547 | bot->Commands(AHBotCommand::bidinterval, ahMapID, 0, param1); 548 | } 549 | } 550 | else if (strncmp(opt, "bidsperinterval", l) == 0) 551 | { 552 | char* param1 = strtok(NULL, " "); 553 | 554 | if (!ahMapIdStr || !param1) 555 | { 556 | handler->PSendSysMessage("Syntax is: ahbotoptions bidsperinterval $ahMapID (2, 6 or 7) $bids"); 557 | return false; 558 | } 559 | 560 | for (AuctionHouseBot* bot: gBots) 561 | { 562 | bot->Commands(AHBotCommand::bidsperinterval, ahMapID, 0, param1); 563 | } 564 | } 565 | else 566 | { 567 | handler->PSendSysMessage("Invalid syntax"); 568 | handler->PSendSysMessage("Try ahbotoptions help to see a list of options."); 569 | return false; 570 | } 571 | 572 | handler->PSendSysMessage("Done"); 573 | return true; 574 | } 575 | }; 576 | 577 | void AddAHBotCommandScripts() 578 | { 579 | new ah_bot_commandscript(); 580 | } 581 | -------------------------------------------------------------------------------- /data/sql/db-world/mod_auctionhousebot.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Main configuration for the auction houses 3 | -- 4 | 5 | DROP TABLE IF EXISTS `mod_auctionhousebot`; 6 | CREATE TABLE `mod_auctionhousebot` ( 7 | `auctionhouse` int(11) NOT NULL DEFAULT '0' COMMENT 'mapID of the auctionhouse.', 8 | `name` char(25) DEFAULT NULL COMMENT 'Text name of the auctionhouse.', 9 | `minitems` int(11) DEFAULT '0' COMMENT 'This is the minimum number of items you want to keep in the auction house. a 0 here will make it the same as the maximum.', 10 | `maxitems` int(11) DEFAULT '0' COMMENT 'This is the number of items you want to keep in the auction house.', 11 | `percentgreytradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Grey Trade Goods auction items', 12 | `percentwhitetradegoods` int(11) DEFAULT '27' COMMENT 'Sets the percentage of the White Trade Goods auction items', 13 | `percentgreentradegoods` int(11) DEFAULT '12' COMMENT 'Sets the percentage of the Green Trade Goods auction items', 14 | `percentbluetradegoods` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the Blue Trade Goods auction items', 15 | `percentpurpletradegoods` int(11) DEFAULT '1' COMMENT 'Sets the percentage of the Purple Trade Goods auction items', 16 | `percentorangetradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Orange Trade Goods auction items', 17 | `percentyellowtradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Yellow Trade Goods auction items', 18 | `percentgreyitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Grey auction items', 19 | `percentwhiteitems` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the non trade White auction items', 20 | `percentgreenitems` int(11) DEFAULT '30' COMMENT 'Sets the percentage of the non trade Green auction items', 21 | `percentblueitems` int(11) DEFAULT '8' COMMENT 'Sets the percentage of the non trade Blue auction items', 22 | `percentpurpleitems` int(11) DEFAULT '2' COMMENT 'Sets the percentage of the non trade Purple auction items', 23 | `percentorangeitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Orange auction items', 24 | `percentyellowitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Yellow auction items', 25 | `minpricegrey` int(11) DEFAULT '100' COMMENT 'Minimum price of Grey items (percentage).', 26 | `maxpricegrey` int(11) DEFAULT '150' COMMENT 'Maximum price of Grey items (percentage).', 27 | `minpricewhite` int(11) DEFAULT '150' COMMENT 'Minimum price of White items (percentage).', 28 | `maxpricewhite` int(11) DEFAULT '250' COMMENT 'Maximum price of White items (percentage).', 29 | `minpricegreen` int(11) DEFAULT '800' COMMENT 'Minimum price of Green items (percentage).', 30 | `maxpricegreen` int(11) DEFAULT '1400' COMMENT 'Maximum price of Green items (percentage).', 31 | `minpriceblue` int(11) DEFAULT '1250' COMMENT 'Minimum price of Blue items (percentage).', 32 | `maxpriceblue` int(11) DEFAULT '1750' COMMENT 'Maximum price of Blue items (percentage).', 33 | `minpricepurple` int(11) DEFAULT '2250' COMMENT 'Minimum price of Purple items (percentage).', 34 | `maxpricepurple` int(11) DEFAULT '4550' COMMENT 'Maximum price of Purple items (percentage).', 35 | `minpriceorange` int(11) DEFAULT '3250' COMMENT 'Minimum price of Orange items (percentage).', 36 | `maxpriceorange` int(11) DEFAULT '5550' COMMENT 'Maximum price of Orange items (percentage).', 37 | `minpriceyellow` int(11) DEFAULT '5250' COMMENT 'Minimum price of Yellow items (percentage).', 38 | `maxpriceyellow` int(11) DEFAULT '6550' COMMENT 'Maximum price of Yellow items (percentage).', 39 | `minbidpricegrey` int(11) DEFAULT '70' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 70', 40 | `maxbidpricegrey` int(11) DEFAULT '100' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 100', 41 | `minbidpricewhite` int(11) DEFAULT '70' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 70', 42 | `maxbidpricewhite` int(11) DEFAULT '100' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 100', 43 | `minbidpricegreen` int(11) DEFAULT '80' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 80', 44 | `maxbidpricegreen` int(11) DEFAULT '100' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 100', 45 | `minbidpriceblue` int(11) DEFAULT '75' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 75', 46 | `maxbidpriceblue` int(11) DEFAULT '100' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 100', 47 | `minbidpricepurple` int(11) DEFAULT '80' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 80', 48 | `maxbidpricepurple` int(11) DEFAULT '100' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 100', 49 | `minbidpriceorange` int(11) DEFAULT '80' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 80', 50 | `maxbidpriceorange` int(11) DEFAULT '100' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 100', 51 | `minbidpriceyellow` int(11) DEFAULT '80' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 80', 52 | `maxbidpriceyellow` int(11) DEFAULT '100' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 100', 53 | `maxstackgrey` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 54 | `maxstackwhite` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 55 | `maxstackgreen` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 56 | `maxstackblue` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 57 | `maxstackpurple` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 58 | `maxstackorange` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 59 | `maxstackyellow` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', 60 | `buyerpricegrey` int(11) DEFAULT '1' COMMENT 'Multiplier to vendorprice when buying grey items from auctionhouse', 61 | `buyerpricewhite` int(11) DEFAULT '3' COMMENT 'Multiplier to vendorprice when buying white items from auctionhouse', 62 | `buyerpricegreen` int(11) DEFAULT '5' COMMENT 'Multiplier to vendorprice when buying green items from auctionhouse', 63 | `buyerpriceblue` int(11) DEFAULT '12' COMMENT 'Multiplier to vendorprice when buying blue items from auctionhouse', 64 | `buyerpricepurple` int(11) DEFAULT '15' COMMENT 'Multiplier to vendorprice when buying purple items from auctionhouse', 65 | `buyerpriceorange` int(11) DEFAULT '20' COMMENT 'Multiplier to vendorprice when buying orange items from auctionhouse', 66 | `buyerpriceyellow` int(11) DEFAULT '22' COMMENT 'Multiplier to vendorprice when buying yellow items from auctionhouse', 67 | `buyerbiddinginterval` int(11) DEFAULT '1' COMMENT 'Interval how frequently AHB bids on each AH. Time in minutes', 68 | `buyerbidsperinterval` int(11) DEFAULT '1' COMMENT 'number of bids to put in per bidding interval', 69 | PRIMARY KEY (`auctionhouse`) 70 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 71 | 72 | -- 73 | -- AHBot auction houses default configuration values 74 | -- 75 | 76 | INSERT INTO `mod_auctionhousebot` (`auctionhouse`, `name`, `minitems`, `maxitems`, `percentgreytradegoods`, `percentwhitetradegoods`, `percentgreentradegoods`, `percentbluetradegoods`, `percentpurpletradegoods`, `percentorangetradegoods`, `percentyellowtradegoods`, `percentgreyitems`, `percentwhiteitems`, `percentgreenitems`, `percentblueitems`, `percentpurpleitems`, `percentorangeitems`, `percentyellowitems`, `minpricegrey`, `maxpricegrey`, `minpricewhite`, `maxpricewhite`, `minpricegreen`, `maxpricegreen`, `minpriceblue`, `maxpriceblue`, `minpricepurple`, `maxpricepurple`, `minpriceorange`, `maxpriceorange`, `minpriceyellow`, `maxpriceyellow`, `minbidpricegrey`, `maxbidpricegrey`, `minbidpricewhite`, `maxbidpricewhite`, `minbidpricegreen`, `maxbidpricegreen`, `minbidpriceblue`, `maxbidpriceblue`, `minbidpricepurple`, `maxbidpricepurple`, `minbidpriceorange`, `maxbidpriceorange`, `minbidpriceyellow`, `maxbidpriceyellow`, `maxstackgrey`, `maxstackwhite`, `maxstackgreen`, `maxstackblue`, `maxstackpurple`, `maxstackorange`, `maxstackyellow`, `buyerpricegrey`, `buyerpricewhite`, `buyerpricegreen`, `buyerpriceblue`, `buyerpricepurple`, `buyerpriceorange`, `buyerpriceyellow`, `buyerbiddinginterval`, `buyerbidsperinterval`) 77 | VALUES 78 | (2,'Alliance',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1), 79 | (6,'Horde',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1), 80 | (7,'Neutral',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1); 81 | 82 | -- 83 | -- Items blacklist 84 | -- 85 | 86 | DROP TABLE IF EXISTS `mod_auctionhousebot_disabled_items`; 87 | CREATE TABLE `mod_auctionhousebot_disabled_items` ( 88 | `item` mediumint(8) unsigned NOT NULL, 89 | PRIMARY KEY (`item`) 90 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 91 | 92 | -- 93 | -- Blacklist default values 94 | -- 95 | 96 | INSERT INTO `mod_auctionhousebot_disabled_items` 97 | VALUES 98 | (17), (3895), (1700), (862), (4196), (3934), (2275), (4213), (4988), (4989), (4990), (4110), (4111), (4116), (3463), (3068), 99 | (913), (2016), (3738), (1189), (3222), (2664), (2273), (4763), (2444), (1041), (1133), (1134), (2413), (2415), (2927), (2932), 100 | (2443), (1487), (1623), (3031), (3034), (3762), (3772), (4981), (2693), (2808), (1254), (2442), (3137), (4191), (4193), (931), 101 | (1114), (1450), (2136), (1352), (2441), (3884), (4200), (2588), (2922), (3005), (3122), (1193), (1057), (3107), (3135), (3144), 102 | (4273), (1113), (2288), (2556), (2921), (3004), (763), (1146), (1255), (2929), (4143), (2064), (3648), (1162), (1167), (2377), 103 | (2920), (3003), (4965), (2497), (2499), (2501), (2599), (3320), (964), (2496), (2498), (2503), (2946), (3131), (1389), (2500), 104 | (2502), (4959), (1166), (1386), (2133), (4930), (1029), (2055), (2128), (2481), (2484), (2487), (3260), (2482), (2483), (2485), 105 | (2486), (2947), (3111), (37), (996), (119), (138), (734), (876), (895), (896), (900), (956), (958), (960), (997), 106 | (1014), (1020), (1021), (1024), (1025), (1027), (1324), (1356), (1672), (1923), (1977), (2410), (2477), (2586), (2638), (2668), 107 | (2755), (2891), (3316), (3513), (3516), (3536), (3584), (3686), (3707), (3744), (4278), (4524), (4703), (4704), (4749), (4851), 108 | (4868), (192), (3958), (3978), (4014), (3952), (3981), (3991), (4011), (3957), (3979), (4012), (3959), (3982), (4010), (3954), 109 | (3983), (3988), (4009), (3953), (3984), (4013), (3956), (3977), (4008), (3955), (3980), (4015), (2931), (3776), (1914), (4858), 110 | (3713), (3777), (3063), (2918), (3046), (3052), (3062), (4912), (2995), (1028), (1192), (2692), (1298), (1363), (4688), (4774), 111 | (4773), (4761), (2305), (2306), (4471), (88), (91), (100), (128), (143), (156), (813), (1222), (1259), (1902), (1911), 112 | (2081), (2184), (2550), (2705), (2715), (2810), (3148), (3168), (3245), (3368), (3675), (3774), (5828), (9372), (8708), (8586), 113 | (9240), (9380), (9484), (9417), (10579), (9718), (7187), (10978), (9685), (9214), (9653), (7987), (7988), (7986), (7550), (7547), 114 | (7548), (7994), (7748), (7953), (9888), (5010), (7497), (7466), (5008), (8840), (5004), (5005), (7467), (7427), (7426), (7948), 115 | (7949), (7950), (7951), (7952), (6589), (6360), (6376), (10049), (5821), (5822), (7188), (6478), (10998), (6345), (5748), (5255), 116 | (5968), (8350), (10939), (6343), (9602), (10595), (8079), (8008), (9421), (8076), (8078), (10683), (8171), (8546), (10662), (10818), 117 | (8007), (5510), (8075), (8077), (10664), (8147), (8993), (5663), (5874), (5875), (8583), (8589), (8590), (8627), (8628), (8630), 118 | (8633), (9254), (10620), (5513), (5522), (6357), (8365), (8366), (5509), (6715), (5108), (5518), (6355), (5632), (5845), (6352), 119 | (6359), (6363), (6364), (6647), (6766), (5654), (5657), (5511), (5105), (6354), (6366), (6374), (6650), (8964), (5232), (5517), 120 | (5660), (5013), (5024), (5603), (5823), (6292), (6294), (6295), (6309), (6310), (6311), (6351), (6353), (6358), (6645), (6754), 121 | (7678), (5150), (6651), (5512), (6182), (6183), (6619), (6649), (5229), (6356), (5235), (5043), (5044), (5349), (5350), (6216), 122 | (6291), (6643), (6891), (7807), (7808), (6648), (5056), (5184), (5220), (5330), (5333), (5353), (5389), (5400), (5410), (5417), 123 | (5418), (5455), (5515), (5531), (5562), (5563), (5639), (5645), (5646), (5681), (5768), (5769), (5833), (5859), (5878), (6130), 124 | (6276), (6277), (6278), (6279), (6280), (6435), (6490), (6491), (6492), (6495), (6496), (6497), (6498), (6500), (6501), (6516), 125 | (6544), (6623), (6717), (6718), (6834), (6927), (6988), (7134), (7206), (7208), (7268), (7271), (7286), (7287), (7333), (7392), 126 | (7679), (7680), (7681), (7716), (7725), (7733), (7737), (7867), (7923), (7970), (8072), (8426), (9280), (9281), (9282), (9284), 127 | (9316), (9319), (9325), (9330), (9365), (9593), (9594), (9595), (9596), (9597), (10464), (10691), (10692), (10693), (10694), (5495), 128 | (5863), (6307), (7769), (7770), (7771), (8164), (8383), (8585), (9311), (9438), (9440), (9441), (9443), (10790), (5550), (5549), 129 | (5555), (8368), (8688), (6951), (5560), (7428), (7190), (5625), (6174), (7170), (5106), (8427), (5379), (5259), (5283), (5362), 130 | (5363), (5364), (5367), (5370), (5371), (5377), (5435), (5600), (6131), (6150), (6225), (6227), (6232), (6297), (6301), (6455), 131 | (7135), (8425), (9700), (9701), (10457), (10450), (10791), (11264), (12947), (15780), (14550), (12302), (12303), (12330), (12351), (12353), 132 | (12354), (13317), (13326), (13327), (13328), (13329), (15292), (15293), (12731), (12588), (12970), (13080), (13090), (13092), (13936), (13950), 133 | (14543), (13148), (13164), (13173), (15410), (15769), (11768), (12105), (11743), (14344), (11671), (11672), (14343), (12469), (11178), (11177), 134 | (13325), (11139), (11138), (11084), (12325), (12326), (12327), (13323), (13324), (12616), (12617), (12615), (12904), (12104), (12106), (12107), 135 | (13175), (13242), (13247), (12866), (11175), (12258), (11174), (11135), (11134), (11082), (13727), (13728), (13730), (13731), (13736), (13737), 136 | (13738), (13739), (13740), (13741), (13742), (13743), (13744), (13745), (13746), (13747), (13748), (13749), (13762), (13763), (13764), (13765), 137 | (13766), (13767), (13768), (13769), (13770), (13771), (13772), (13773), (13775), (13776), (13777), (13778), (13779), (13780), (13781), (13782), 138 | (13783), (13784), (13785), (13788), (13791), (13794), (13797), (13798), (13801), (13802), (13803), (13804), (13805), (13806), (13807), (13808), 139 | (13809), (13603), (15756), (13701), (14488), (11950), (11951), (11952), (13480), (13888), (13889), (13890), (13891), (13893), (13901), (13902), 140 | (13903), (13904), (13905), (13906), (13907), (13908), (13910), (13911), (13912), (13914), (13915), (13916), (13917), (13918), (14481), (13477), 141 | (14894), (15409), (15415), (15417), (15419), (15886), (13602), (13700), (11176), (13422), (13754), (13755), (13756), (13758), (13759), (13760), 142 | (13875), (13876), (13877), (13878), (13879), (13880), (13881), (13882), (13883), (13884), (13885), (13886), (13887), (11903), (14062), (15326), 143 | (15327), (11111), (13699), (11137), (11083), (12238), (12446), (12447), (12448), (12449), (14891), (14083), (11024), (11131), (11149), (11170), 144 | (11222), (11230), (11282), (11364), (11413), (11470), (11507), (11508), (11512), (11513), (11582), (11602), (11609), (11613), (11616), (11947), 145 | (11949), (11954), (12064), (12241), (12263), (12347), (12349), (12563), (12567), (12648), (12649), (12723), (12847), (12885), (13155), (13159), 146 | (13370), (13673), (13726), (13732), (13733), (13734), (13787), (13790), (13793), (13796), (14339), (14390), (14392), (14645), (15448), (15843), 147 | (15845), (11270), (11283), (11511), (11514), (12468), (15422), (15423), (12348), (12787), (12943), (12991), (13316), (13337), (13612), (14586), 148 | (18582), (18583), (18584), (17182), (17782), (18881), (17142), (17067), (17068), (18608), (18609), (18713), (18715), (17075), (18813), (17078), 149 | (17064), (18205), (17223), (18538), (18970), (18241), (18242), (18243), (18244), (18245), (18246), (18247), (18248), (18768), (17886), (17982), 150 | (16369), (16391), (16392), (16393), (16396), (16397), (16401), (16403), (16405), (16406), (16409), (16410), (16413), (16414), (16415), (16416), 151 | (16417), (16418), (16419), (16420), (16421), (16422), (16423), (16424), (16425), (16426), (16427), (16428), (16429), (16430), (16431), (16432), 152 | (16433), (16434), (16435), (16436), (16485), (16487), (16489), (16490), (16491), (16492), (16494), (16496), (16498), (16499), (16501), (16502), 153 | (16503), (16504), (16505), (16506), (16507), (16508), (16509), (16510), (16513), (16514), (16515), (16516), (16518), (16519), (16521), (16522), 154 | (16523), (16524), (16525), (16526), (16527), (16528), (16530), (16531), (17562), (17564), (17566), (17567), (17568), (17569), (17570), (17571), 155 | (17572), (17573), (17576), (17577), (17594), (17596), (17598), (17599), (17600), (17601), (17610), (17611), (17612), (17613), (17616), (17617), 156 | (16337), (17967), (17968), (16999), (17733), (16334), (16336), (16340), (18303), (18304), (18320), (18341), (18342), (16315), (16203), (17966), 157 | (16664), (16202), (17769), (16792), (16165), (17224), (17364), (16026), (16339), (16350), (16366), (16374), (16896), (17012), (18142), (16320), 158 | (16362), (16378), (16356), (16387), (16047), (16171), (16330), (16383), (18636), (16041), (16042), (16373), (16389), (18651), (16325), (16349), 159 | (16361), (16895), (17024), (16319), (16355), (16365), (16386), (16377), (16382), (16082), (16085), (16971), (16329), (16372), (16360), (16390), 160 | (17019), (16348), (16354), (16385), (16893), (16967), (16318), (16324), (16381), (16364), (16371), (16388), (17027), (16057), (16328), (16359), 161 | (16376), (16353), (16380), (16384), (16347), (16892), (16317), (16368), (16323), (16358), (16379), (16327), (16352), (16363), (16375), (16346), 162 | (18964), (16316), (16357), (16351), (16322), (16326), (16331), (16302), (17195), (17302), (17305), (17308), (18002), (16321), (16180), (16642), 163 | (16643), (16644), (16968), (16969), (16970), (16973), (17126), (17242), (17262), (17323), (17324), (17325), (17333), (17353), (17362), (17363), 164 | (17442), (17505), (17506), (17507), (17696), (17758), (17882), (17887), (18151), (18153), (18492), (18540), (18566), (18643), (18799), (18154), 165 | (18642), (20880), (19158), (20142), (20329), (21584), (21587), (21588), (21594), (21612), (21613), (21614), (21339), (20487), (20488), (21124), 166 | (21125), (21127), (21890), (19879), (19951), (19952), (19953), (19954), (19955), (19956), (19957), (19958), (19959), (20698), (20725), (20887), 167 | (19875), (20720), (20721), (20722), (19105), (19110), (20696), (20706), (20368), (21281), (21282), (21283), (21293), (21302), (19986), (20003), 168 | (20005), (20502), (20522), (20524), (21044), (20381), (21785), (21786), (21878), (21772), (21773), (20086), (20965), (19803), (19805), (19806), 169 | (19808), (20591), (20596), (20962), (20957), (20953), (20829), (20952), (20825), (20822), (20819), (19213), (19322), (20256), (20560), (21992), 170 | (21159), (21175), (19012), (19013), (19696), (20498), (20500), (20501), (19010), (19011), (19807), (20065), (21228), (21243), (21153), (19450), 171 | (20067), (21150), (21164), (19008), (19009), (21113), (19006), (19007), (19054), (19055), (21071), (21168), (21212), (21043), (20708), (21162), 172 | (19004), (19005), (20913), (20979), (20981), (19160), (19422), (19642), (19725), (19775), (19880), (19882), (20018), (20020), (20021), (20364), 173 | (20393), (20416), (20418), (20419), (20420), (20432), (20433), (20435), (20436), (20447), (20448), (20449), (20450), (20454), (20455), (20456), 174 | (20709), (20902), (20903), (20904), (20977), (20984), (21106), (21107), (21109), (21111), (21114), (21131), (21152), (21158), (21160), (21161), 175 | (21171), (21442), (21519), (21536), (21560), (21577), (21578), (21591), (21815), (21816), (21817), (21818), (21819), (21820), (21821), (21822), 176 | (21823), (21831), (21975), (21979), (21980), (21981), (19960), (21140), (19924), (20030), (21141), (22736), (22726), (22819), (22821), (22798), 177 | (22799), (22802), (22812), (22691), (22947), (22954), (22800), (22801), (22804), (22807), (22808), (22809), (22811), (22816), (22818), (22820), 178 | (22935), (22936), (22937), (22938), (22939), (22940), (22941), (22943), (22960), (22961), (22967), (22968), (22981), (22983), (22988), (22994), 179 | (22803), (22806), (22810), (22813), (22814), (22815), (22942), (22805), (22817), (22450), (22349), (22350), (22351), (22352), (22353), (22354), 180 | (22355), (22356), (22357), (22358), (22359), (22360), (22361), (22362), (22363), (22364), (22365), (22366), (22367), (22368), (22369), (22370), 181 | (22371), (22372), (22373), (22374), (22375), (22376), (22891), (22230), (22273), (22446), (22447), (22782), (22018), (22019), (22103), (22104), 182 | (22105), (22116), (22182), (22187), (22189), (22797), (22044), (22179), (22186), (22788), (22128), (22184), (22646), (22795), (22895), (22181), 183 | (22185), (22190), (22183), (22180), (22188), (22972), (22710), (22020), (22042), (22045), (22140), (22141), (22142), (22143), (22144), (22145), 184 | (22154), (22155), (22156), (22157), (22158), (22159), (22160), (22161), (22162), (22163), (22164), (22165), (22166), (22167), (22168), (22169), 185 | (22170), (22171), (22172), (22178), (22202), (22260), (22262), (22263), (22283), (22284), (22285), (22286), (22287), (22288), (22289), (22290), 186 | (22291), (22292), (22293), (22294), (22295), (22296), (22297), (22298), (22299), (22300), (22386), (22387), (22584), (22733), (22754), (22822), 187 | (22896), (22899), (22058), (22059), (22709), (23051), (25596), (24526), (24561), (24567), (27965), (24550), (24557), (24265), (23053), (23057), 188 | (23058), (23040), (23041), (23043), (23045), (23046), (23047), (23048), (23049), (23050), (23072), (23362), (23363), (23054), (23056), (23577), 189 | (23242), (23000), (23001), (23025), (23027), (23037), (23038), (23042), (23069), (23070), (23219), (23220), (23663), (23664), (23665), (23666), 190 | (23667), (23668), (23004), (23005), (23006), (23009), (23017), (23018), (23019), (23020), (23021), (23023), (23028), (23029), (23030), (23031), 191 | (23032), (23033), (23034), (23035), (23036), (23039), (23044), (23068), (23071), (23073), (23075), (23221), (23226), (23237), (23238), (23014), 192 | (23457), (23458), (23459), (23461), (23462), (23193), (23545), (23547), (23548), (23549), (23714), (23705), (23709), (23716), (23773), (24412), 193 | (25641), (24137), (25667), (23854), (23855), (24288), (27388), (27446), (24071), (23885), (23882), (23364), (23366), (27774), (27811), (27002), 194 | (27007), (26368), (26372), (26655), (26738), (26128), (26129), (26130), (26131), (26132), (26133), (26134), (26135), (26464), (26465), (26513), 195 | (26527), (26541), (26569), (26765), (26779), (25573), (25574), (25575), (25576), (25580), (25581), (25582), (26235), (26792), (25627), (27196), 196 | (27718), (27719), (27720), (26324), (25145), (25159), (25173), (25285), (26843), (26548), (26180), (26173), (26174), (26175), (27218), (23147), 197 | (23151), (23153), (23229), (23076), (23157), (26015), (26029), (26041), (23420), (23421), (23422), (23432), (23433), (23434), (23233), (23234), 198 | (23235), (27864), (26045), (27863), (24243), (23731), (23755), (23840), (24315), (25877), (23137), (23131), (23141), (23730), (23130), (23135), 199 | (23140), (23144), (23148), (23152), (23162), (23194), (23195), (23196), (23684), (23745), (25469), (25699), (25700), (27422), (27437), (27481), 200 | (27511), (27513), (23578), (25900), (23579), (23683), (23711), (23734), (23846), (23365), (23368), (24227), (24100), (23003), (23008), (23010), 201 | (23011), (23012), (23013), (23016), (23024), (23055), (23214), (23227), (23248), (23340), (23341), (23342), (23350), (23352), (23360), (23378), 202 | (23471), (23486), (23552), (23567), (23584), (23586), (23670), (23686), (23726), (23754), (23878), (23879), (23880), (24156), (24226), (24317), 203 | (24494), (24538), (24573), (25635), (25677), (25747), (25748), (25749), (25750), (25754), (25755), (25756), (25757), (25850), (27317), (27419), 204 | (27590), (23560), (23561), (23562), (23750), (23858), (23866), (23867), (23868), (25814), (27443), (25407), (24242), (27441), (24235), (24190), 205 | (24234), (24188), (23330), (23355), (23952), (23980), (24283), (24506), (24509), (25813), (24140), (28294), (28295), (28297), (28298), (28299), 206 | (28300), (28302), (28305), (28307), (28308), (28309), (28310), (28312), (28313), (28314), (28319), (28320), (28346), (28358), (28383), (28385), 207 | (28402), (28404), (28409), (28410), (28422), (28423), (28443), (28444), (28446), (28447), (28449), (28450), (28476), (28629), (28630), (28639), 208 | (28640), (28641), (28642), (28644), (28645), (28974), (28975), (28976), (28977), (28980), (28982), (28983), (28985), (28986), (28987), (28990), 209 | (28991), (28993), (28994), (28995), (28997), (28998), (28355), (28356), (28357), (28244), (28245), (28381), (28405), (28411), (28424), (28445), 210 | (28448), (28451), (28605), (28638), (28643), (28646), (28973), (28978), (28981), (28984), (28988), (28989), (28992), (28996), (28999), (28117), 211 | (28122), (28388), (28389), (28482), (28293), (28613), (28614), (28615), (28616), (28617), (28618), (28619), (28620), (28622), (28623), (28624), 212 | (28625), (28626), (28627), (28628), (28679), (28680), (28681), (28683), (28684), (28685), (28686), (28687), (28688), (28689), (28690), (28691), 213 | (28692), (28693), (28694), (28695), (28696), (28697), (28698), (28699), (28700), (28701), (28702), (28703), (28704), (28705), (28706), (28707), 214 | (28708), (28709), (28710), (28711), (28712), (28713), (28714), (28715), (28716), (28717), (28718), (28719), (28720), (28721), (28722), (28723), 215 | (28724), (28805), (28806), (28807), (28808), (28809), (28811), (28812), (28813), (28814), (28815), (28817), (28818), (28819), (28820), (28821), 216 | (28831), (28832), (28833), (28834), (28835), (28836), (28837), (28838), (28839), (28840), (28841), (28842), (28843), (28844), (28845), (28846), 217 | (28847), (28848), (28849), (28850), (28851), (28852), (28853), (28854), (28855), (28856), (28857), (28858), (28859), (28860), (28861), (28862), 218 | (28863), (28864), (28865), (28866), (28867), (28868), (28869), (28870), (28871), (28872), (28873), (28874), (28875), (28917), (28918), (28919), 219 | (28920), (28921), (28922), (28923), (28924), (28925), (28926), (28928), (28929), (28930), (28931), (28933), (28935), (28937), (28938), (28939), 220 | (28940), (28941), (28942), (28943), (28944), (28945), (28946), (28947), (28948), (28949), (28950), (28951), (28952), (28953), (28954), (28955), 221 | (28956), (28957), (28959), (28960), (28043), (28044), (28045), (28291), (28408), (28145), (28073), (28112), (28068), (28596), (28072), (28110), 222 | (28131), (28071), (28047), (28099), (28500), (28676), (28738), (28739), (28784), (28039), (28023), (28489), (28905), (30320), (29828), (31958), 223 | (31959), (31965), (31966), (31978), (31984), (31985), (31986), (30448), (29000), (29001), (29003), (29004), (29005), (30491), (31594), (31595), 224 | (31596), (31597), (29885), (29002), (29006), (31598), (31599), (29237), (30559), (29120), (29225), (31584), (31585), (31586), (31587), (31588), 225 | (31589), (31590), (31591), (31592), (31593), (31620), (31621), (31622), (31623), (31624), (31625), (31626), (31627), (31628), (31629), (31630), 226 | (31631), (31632), (31633), (31634), (31635), (31636), (31637), (31638), (31639), (31640), (31641), (31642), (31643), (31644), (31646), (31647), 227 | (31648), (31649), (31650), (31942), (31490), (31491), (31802), (31492), (31493), (31494), (31246), (29210), (30418), (30287), (30288), (30289), 228 | (31730), (30845), (29024), (30427), (30703), (30760), (29539), (29547), (29548), (29569), (30309), (30499), (29041), (29311), (29749), (29751), 229 | (29769), (29839), (29840), (29841), (29842), (29852), (29856), (29857), (29860), (29861), (29863), (29868), (29871), (29872), (29874), (29887), 230 | (29961), (29963), (30193), (30197), (30430), (30438), (30524), (30525), (30526), (30539), (30567), (30595), (30613), (30630), (30658), (30659), 231 | (30717), (31122), (31123), (31130), (31252), (31266), (31346), (31365), (31518), (31607), (31665), (31813), (31843), (31845), (31849), (29790), 232 | (29805), (30632), (30805), (31530), (29410), (29419), (29565), (29571), (29575), (29576), (29645), (29712), (30414), (31824), (32824), (32466), 233 | (32419), (32760), (32761), (32956), (32959), (32416), (32003), (32014), (32025), (32026), (32027), (32028), (32044), (32045), (32046), (32052), 234 | (32053), (32054), (32055), (32961), (32962), (32963), (32964), (32944), (32418), (32422), (32482), (32955), (32958), (32450), (32451), (32452), 235 | (32974), (32975), (32976), (32978), (32982), (32984), (32985), (32987), (32992), (32993), (32995), (32996), (32415), (32417), (32954), (32957), 236 | (32973), (32977), (32983), (32986), (32991), (32994), (32093), (32094), (32095), (32096), (32097), (32098), (32099), (32100), (32101), (32102), 237 | (32103), (32104), (32105), (32106), (32107), (32108), (32109), (32110), (32111), (32112), (32113), (32114), (32115), (32116), (32117), (32118), 238 | (32119), (32120), (32121), (32122), (32123), (32124), (32125), (32126), (32127), (32128), (32129), (32130), (32131), (32132), (32133), (32134), 239 | (32135), (32136), (32137), (32138), (32139), (32140), (32141), (32142), (32143), (32144), (32145), (32146), (32147), (32148), (32149), (32150), 240 | (32151), (32152), (32153), (32154), (32155), (32156), (32157), (32158), (32159), (32160), (32161), (32162), (32163), (32164), (32165), (32166), 241 | (32167), (32168), (32169), (32170), (32171), (32172), (32173), (32174), (32175), (32176), (32177), (32178), (32179), (32180), (32181), (32182), 242 | (32183), (32184), (32185), (32186), (32187), (32188), (32189), (32190), (32192), (32414), (32421), (32655), (32656), (32914), (32735), (32895), 243 | (32896), (32407), (32658), (32659), (32660), (32661), (32662), (32663), (32664), (32665), (32949), (32950), (32412), (32915), (32917), (32918), 244 | (32919), (32920), (32465), (32542), (32566), (32594), (32773), (32764), (32765), (32766), (32618), (32642), (32543), (32544), (32545), (32546), 245 | (32547), (32548), (32549), (32550), (32551), (32552), (32553), (32554), (32555), (32556), (32557), (32558), (32559), (32560), (32561), (32595), 246 | (32598), (32601), (32840), (32844), (32845), (32846), (32847), (32762), (32763), (32767), (32972), (32320), (32364), (32408), (32626), (32627), 247 | (32628), (32629), (32630), (32631), (32688), (32689), (32690), (32691), (32692), (32693), (32700), (32701), (32702), (32703), (32704), (32705), 248 | (32706), (32707), (32708), (32709), (32710), (32711), (32712), (32713), (32734), (32911), (32971), (32578), (32906), (32725), (32615), (32633), 249 | (32841), (33475), (34146), (34149), (34145), (34148), (34144), (34147), (34219), (34335), (34209), (34212), (33668), (33671), (33674), (33676), 250 | (33679), (33682), (33684), (33690), (33693), (33699), (33700), (33703), (33717), (33720), (33726), (33729), (33732), (33744), (33747), (33753), 251 | (33767), (33770), (33920), (33921), (33922), (33923), (33076), (33077), (33078), (33309), (33313), (33937), (33940), (33943), (33946), (33949), 252 | (33952), (34576), (34577), (34578), (34579), (34580), (33987), (33997), (33054), (33065), (33066), (33067), (33068), (33482), (33964), (33936), 253 | (33939), (33942), (33945), (33948), (33951), (33957), (33959), (34073), (34074), (34075), (34622), (34057), (33132), (33137), (33138), (33139), 254 | (33141), (33142), (33809), (34544), (33080), (33225), (33182), (33184), (34835), (33350), (34138), (34139), (33803), (34143), (34142), (34221), 255 | (33060), (33147), (34627), (34967), (34415), (34107), (33224), (33993), (34955), (33017), (33018), (33019), (33020), (33021), (33176), (33183), 256 | (33219), (33223), (34492), (34499), (34518), (34519), (33197), (34484), (34486), (33455), (34025), (34030), (33312), (34062), (34024), (34126), 257 | (34469), (34735), (34737), (34738), (34739), (34740), (34741), (34742), (34743), (34744), (34745), (34746), (34864), (34865), (34867), (34868), 258 | (33823), (33824), (34467), (34663), (33096), (33218), (33041), (33081), (33087), (33105), (33111), (33121), (33315), (33336), (33341), (33477), 259 | (33558), (33599), (33604), (33610), (33614), (33615), (33616), (33617), (33634), (33781), (33784), (33839), (33848), (33850), (33929), (34044), 260 | (34077), (34112), (34115), (34116), (34117), (34120), (34123), (34135), (34158), (34187), (34191), (34494), (34497), (34501), (34623), (34645), 261 | (34647), (34716), (34718), (34842), (33051), (33063), (33797), (34171), (33316), (34476), (33089), (34589), (34590), (34591), (34694), (34784), 262 | (34880), (34907), (36942), (35290), (35291), (35292), (35317), (35319), (35327), (35494), (35495), (35496), (35497), (35507), (35508), (35509), 263 | (35511), (35514), (35213), (35539), (35541), (35545), (35546), (35549), (35550), (35202), (35209), (35226), (35517), (35518), (35519), (35520), 264 | (35521), (35522), (35523), (35524), (35525), (35526), (35527), (35528), (35529), (35530), (35531), (35532), (35533), (35535), (35537), (35538), 265 | (35544), (35548), (35551), (35553), (35555), (35664), (35665), (35666), (36866), (36867), (35728), (35729), (35730), (35731), (35225), (36941), 266 | (36454), (36477), (36491), (36505), (36519), (36533), (36547), (36561), (36575), (36589), (36603), (36617), (36631), (36645), (36659), (36673), 267 | (36687), (36701), (36715), (35876), (36910), (36915), (35626), (36899), (36900), (36970), (36892), (36893), (36894), (36965), (36897), (36955), 268 | (36967), (36895), (36960), (36912), (36914), (36968), (36959), (36889), (36890), (36891), (36966), (36896), (36964), (35285), (35286), (35396), 269 | (35397), (35398), (35399), (35400), (35417), (35418), (35419), (35420), (35421), (35422), (35423), (35424), (35425), (35426), (35427), (35428), 270 | (35429), (35430), (35431), (35432), (35433), (35434), (35435), (35436), (35437), (35438), (35439), (35440), (35441), (35442), (35443), (35444), 271 | (35445), (35446), (35447), (35448), (35449), (35450), (35451), (35452), (35453), (35454), (35455), (35456), (35457), (35458), (35459), (35460), 272 | (35461), (35462), (35313), (35946), (35126), (35229), (35289), (35692), (35701), (35718), (35722), (35738), (35777), (35803), (35840), (35854), 273 | (36733), (36748), (36765), (36768), (36772), (36799), (36828), (36836), (36846), (36848), (35512), (35792), (35806), (36862), (36863), (35757), 274 | (36794), (36795), (36829), (36830), (38691), (37739), (37740), (37611), (37127), (37128), (37597), (38287), (38288), (38289), (38290), (38282), 275 | (38307), (38377), (38378), (38265), (37598), (37719), (38576), (38484), (38309), (38310), (38311), (38312), (38313), (38314), (37174), (37175), 276 | (37176), (37196), (37197), (37243), (37244), (37245), (37290), (37364), (37365), (37366), (37410), (37587), (37590), (37624), (37625), (37646), 277 | (37647), (37648), (37649), (37671), (37672), (37673), (37697), (37698), (37699), (37799), (37800), (37801), (37856), (37857), (37858), (37109), 278 | (38442), (38443), (38444), (38445), (38387), (38388), (38389), (38390), (38572), (38468), (38243), (38244), (38245), (38246), (38247), (38248), 279 | (38471), (38480), (38481), (38469), (37430), (37311), (37313), (38292), (38538), (38658), (38683), (37164), (37827), (37893), (37894), (37895), 280 | (37896), (37897), (37297), (37298), (38301), (38578), (38916), (37955), (37967), (37976), (38052), (38140), (38204), (38383), (38524), (38525), 281 | (38527), (37210), (37225), (37273), (37278), (37279), (37281), (37284), (37285), (37286), (37295), (37296), (37315), (37316), (37317), (37318), 282 | (37321), (37323), (37324), (37385), (37386), (37400), (37420), (37433), (37444), (37448), (37450), (37451), (37453), (37454), (37455), (37457), 283 | (37466), (37468), (37469), (37470), (37472), (37473), (37474), (37477), (37485), (37510), (37511), (37534), (37536), (37544), (38164), (38254), 284 | (38255), (38256), (37343), (37345), (37346), (37338), (37326), (37329), (37335), (37336), (37337), (37710), (37312), (37163), (37154), (37126), 285 | (37348), (38640), (38970), (38994), (38996), (38983), (37706), (38958), (37452), (38270), (38271), (38272), (38561), (38597), (38643), (38625), 286 | (38957), (38567), (37161), (37157), (37158), (37489), (37898), (37900), (37901), (37902), (37903), (37904), (37905), (37906), (37907), (37908), 287 | (37909), (37100), (37250), (37303), (37372), (37501), (37815), (37837), (37859), (37860), (37925), (38089), (38186), (38233), (38266), (38324), 288 | (38380), (38382), (38483), (38498), (38512), (38577), (38600), (38606), (38619), (38621), (38622), (38623), (38624), (38629), (38630), (38631), 289 | (37063), (37089), (37090), (37148), (37301), (37711), (37742), (37878), (38333), (38587), (38644), (38687), (38448), (37839), (38497), (38496), 290 | (38626), (37467), (37579), (38261), (38263), (38264), (38268), (38269), (38273), (38274), (38605), (40481), (41900), (41911), (41995), (40549), 291 | (39715), (40406), (40407), (40408), (40409), (40410), (40412), (40414), (40650), (39263), (39427), (39467), (39468), (39470), (39472), (39473), 292 | (40307), (40553), (40440), (40441), (40442), (40443), (40444), (39769), (41749), (41342), (39303), (40480), (41605), (41606), (40762), (40777), 293 | (40599), (40727), (40754), (40832), (40839), (40725), (41403), (41404), (41405), (41406), (41407), (41408), (41409), (41410), (41411), (41412), 294 | (41413), (41414), (41415), (41416), (41417), (41418), (41419), (41420), (41421), (41422), (41423), (41796), (41125), (39370), (40232), (41133), 295 | (39364), (39410), (39440), (39460), (39819), (39828), (41756), (41757), (41758), (41759), (39707), (39708), (39709), (39710), (39711), (41178), 296 | (41750), (41753), (39685), (41147), (41166), (41174), (41196), (39644), (39687), (39738), (39969), (40199), (40776), (41091), (41093), (41111), 297 | (41118), (41173), (39526), (39527), (41195), (39148), (39213), (39343), (39692), (41741), (41800), (41801), (41802), (41803), (41804), (41805), 298 | (41806), (41807), (41808), (41809), (41810), (41811), (41812), (41813), (41814), (40773), (41194), (39342), (40484), (40948), (41193), (41172), 299 | (39341), (41192), (41171), (39340), (41169), (41191), (39339), (41170), (39338), (39302), (39334), (39151), (39162), (39163), (39314), (39575), 300 | (39576), (39614), (39739), (39748), (39903), (39904), (40110), (40218), (40219), (40220), (40221), (40222), (40223), (40224), (40225), (40226), 301 | (40227), (40228), (40229), (40230), (40231), (40389), (40686), (41132), (41585), (39506), (39883), (39153), (39743), (39754), (42000), (42007), 302 | (42013), (42019), (42083), (42238), (42207), (42226), (42231), (42236), (42241), (42254), (42259), (42264), (42269), (42274), (42279), (42284), 303 | (42289), (42316), (42321), (42326), (42331), (42345), (42351), (42359), (42383), (42389), (42449), (42484), (42489), (42494), (42501), (42512), 304 | (42518), (42524), (42530), (42536), (42558), (42563), (42569), (42577), (42582), (42587), (42596), (42601), (42606), (42613), (42619), (42654), 305 | (42655), (42656), (42657), (42658), (42851), (42664), (42665), (42666), (42667), (42668), (42625), (42626), (42627), (42628), (42629), (42659), 306 | (42660), (42661), (42662), (42663), (42690), (42691), (42692), (42693), (42694), (42695), (42696), (42697), (42698), (42699), (42630), (42631), 307 | (42632), (42633), (42634), (42635), (42636), (42637), (42638), (42639), (42669), (42670), (42671), (42672), (42673), (42674), (42675), (42676), 308 | (42677), (42678), (42680), (42681), (42682), (42683), (42684), (42685), (42686), (42687), (42688), (42689), (42703), (42704), (42705), (42706), 309 | (42707), (42708), (42709), (42710), (42711), (42712), (42713), (42714), (42715), (42716), (42717), (42718), (42719), (42720), (42721), (42722), 310 | (42197), (42198), (42199), (42200), (42201), (42202), (42976), (42206), (42212), (42213), (42214), (42215), (42216), (42217), (42218), (42219), 311 | (42220), (42221), (42222), (42223), (42224), (42294), (42295), (42296), (42297), (42343), (42344), (42356), (42382), (42388), (42444), (42445), 312 | (42446), (42447), (42448), (42511), (42517), (42523), (42529), (42535), (42556), (42557), (42568), (42574), (42575), (42576), (42593), (42594), 313 | (42595), (42611), (42612), (42618), (42755), (42953), (42975), (42977), (42978), (42979), (42980), (42981), (42982), (42983), (42875), (42885), 314 | (42886), (42174), (42179), (42425), (42147), (42434), (42171), (42545), (42180), (42181), (42182), (42186), (42189), (42190), (42191), (42192), 315 | (42193), (42194), (42195), (42196), (42432), (42433), (42170), (42986), (42590), (42474), (42440), (42894), (42733), (42342), (42350), (42381), 316 | (42776), (42940), (43651), (43727), (43728), (43729), (43730), (43731), (43460), (43611), (43612), (43613), (43732), (43733), (43734), (43735), 317 | (43736), (43737), (43738), (43739), (43740), (43741), (43742), (43743), (43744), (43745), (43746), (43747), (43748), (43749), (43750), (43751), 318 | (43752), (43753), (43754), (43755), (43756), (43757), (43758), (43759), (43760), (43761), (43762), (43763), (43764), (43765), (43766), (43767), 319 | (43768), (43769), (43770), (43771), (43772), (43773), (43774), (43775), (43776), (43777), (43778), (43779), (43780), (43781), (43782), (43783), 320 | (43784), (43785), (43786), (43787), (43788), (43789), (43790), (43791), (43792), (43793), (43794), (43795), (43796), (43797), (43798), (43799), 321 | (43800), (43801), (43802), (43803), (43804), (43805), (43806), (43807), (43808), (43809), (43810), (43811), (43812), (43813), (43814), (43815), 322 | (43816), (43817), (43818), (43819), (43820), (43822), (43069), (43071), (43072), (43075), (43076), (43079), (43080), (43083), (43267), (43963), 323 | (43964), (43475), (43476), (43302), (43303), (43304), (43949), (43517), (43698), (43648), (43848), (43878), (43895), (43922), (43936), (43938), 324 | (43109), (43563), (43108), (43298), (43562), (43107), (43561), (43106), (43560), (43105), (43559), (43104), (43558), (43103), (43557), (43150), 325 | (43523), (43087), (43097), (43518), (43468), (43571), (43572), (43614), (43620), (43621), (43647), (43652), (43038), (43646), (43002), (43099), 326 | (43136), (43144), (43149), (43269), (43270), (43272), (43274), (43275), (43276), (43308), (43336), (43337), (43384), (43362), (43006), (43093), 327 | (43288), (43307), (43471), (43486), (43489), (43617), (43618), (43619), (43627), (43628), (43629), (43630), (43631), (43632), (43633), (43634), 328 | (43635), (43636), (43637), (43638), (43639), (43640), (43641), (43650), (43695), (43215), (43493), (43659), (43003), (43321), (43325), (43326), 329 | (43328), (43329), (43330), (43333), (43341), (43576), (43577), (43643), (43644), (43645), (43653), (43658), (43675), (43676), (43677), (43678), 330 | (43679), (43680), (43681), (43682), (43683), (43684), (43685), (43686), (43687), (43694), (43701), (43702), (43703), (43704), (43705), (43706), 331 | (43707), (43708), (43709), (43710), (43711), (43712), (43713), (43714), (43715), (43716), (43717), (43718), (43719), (43720), (43721), (43722), 332 | (43723), (44090), (44807), (45457), (45459), (45460), (45461), (45462), (45605), (45455), (45538), (45539), (45540), (45541), (45542), (45543), 333 | (45544), (45547), (45548), (45549), (45350), (45464), (44310), (44311), (44333), (44417), (44418), (44869), (44870), (44926), (44948), (45924), 334 | (44924), (44555), (44556), (44557), (44871), (44872), (44873), (44874), (44164), (44175), (45280), (45024), (45037), (45173), (44191), (44415), 335 | (44416), (45172), (44505), (45174), (45175), (44391), (44392), (45850), (45851), (45852), (45853), (44945), (44563), (44875), (44876), (44877), 336 | (44878), (44879), (44880), (44881), (44882), (44883), (44884), (45705), (44451), (44619), (44627), (44629), (44600), (44811), (44158), (44148), 337 | (45180), (44260), (44261), (44262), (44263), (44264), (44265), (44266), (44267), (44268), (44269), (44270), (44271), (44272), (44273), (44274), 338 | (44275), (44277), (44278), (44279), (44280), (44281), (44282), (44284), (44285), (44286), (44287), (44288), (44289), (44290), (44291), (44292), 339 | (44293), (44866), (44972), (45063), (44703), (45575), (45126), (44428), (45052), (45050), (45629), (44849), (45127), (45229), (45230), (45231), 340 | (45500), (44817), (44607), (45006), (45007), (45008), (45009), (44506), (44507), (45279), (45863), (45901), (45909), (44221), (44229), (44598), 341 | (44608), (44609), (44475), (45276), (45277), (44432), (45908), (44743), (44604), (45942), (44462), (44480), (44508), (44620), (44646), (44680), 342 | (44832), (44851), (44852), (44856), (44915), (44981), (44988), (44989), (44991), (44992), (44993), (44994), (44996), (44997), (45003), (45026), 343 | (45028), (45029), (45030), (45031), (45032), (45033), (45036), (45045), (45049), (45082), (45120), (45278), (45328), (45569), (45728), (45729), 344 | (45730), (45748), (45749), (45750), (45751), (45752), (45754), (45759), (45765), (45860), (45899), (45902), (45903), (45904), (45905), (44304), 345 | (44434), (44656), (44718), (45034), (45035), (45568), (44299), (45630), (44728), (44236), (44298), (44300), (44578), (44580), (44705), (44755), 346 | (44760), (44761), (44833), (45061), (45176), (45177), (45178), (45179), (45188), (45189), (45190), (45191), (45194), (45195), (45196), (45197), 347 | (45198), (45199), (45200), (45201), (45202), (45900), (45907), (46105), (46104), (46214), (46215), (46217), (46218), (46219), (46220), (46222), 348 | (46225), (46227), (46228), (46230), (46232), (46233), (46234), (46235), (46236), (46237), (46238), (46239), (46240), (46241), (46242), (46243), 349 | (46244), (46245), (46246), (46248), (46255), (46256), (46257), (46273), (46274), (46275), (46276), (46277), (46288), (46289), (46290), (46291), 350 | (46292), (46293), (46294), (46295), (46296), (46297), (46298), (46299), (46300), (46301), (46302), (46303), (46304), (46305), (46306), (46307), 351 | (46103), (46213), (46216), (46221), (46223), (46224), (46226), (46231), (46247), (46249), (46250), (46251), (46252), (46253), (46254), (46258), 352 | (46259), (46260), (46261), (46262), (46263), (46264), (46265), (46266), (46267), (46268), (46269), (46270), (46271), (46272), (46278), (46279), 353 | (46280), (46281), (46282), (46283), (46284), (46285), (46286), (46287), (46309), (46339), (46340), (46341), (46342), (46343), (46344), (46345), 354 | (46346), (46347), (46350), (46351), (47497), (47229), (46101), (46778), (46331), (47246), (46709), (46767), (46802), (46892), (46780), (46765), 355 | (46766), (46849), (47507), (47395), (46399), (46400), (46401), (46402), (46403), (46055), (46847), (47030), (46887), (46054), (46735), (46069), 356 | (46070), (46106), (46319), (46395), (46783), (46830), (46978), (47036), (46852), (46957), (49686), (48435), (48438), (48440), (48442), (48444), 357 | (48507), (48509), (48511), (48513), (48515), (48517), (48519), (48521), (48523), (49191), (49497), (48725), (48726), (48727), (48728), (48729), 358 | (48730), (48731), (48732), (48733), (48734), (48735), (48736), (48737), (48738), (48739), (48740), (48741), (48742), (48743), (48744), (48745), 359 | (48746), (48747), (48748), (48749), (48750), (48751), (48752), (48753), (48754), (48755), (48756), (48757), (48758), (48759), (48760), (48761), 360 | (48762), (48763), (48764), (48769), (48770), (48771), (48772), (48773), (48774), (48775), (48776), (48777), (48778), (48781), (48782), (48783), 361 | (48784), (48785), (48786), (48787), (48788), (48789), (48790), (48794), (48795), (48796), (48797), (48798), (48799), (48800), (48801), (48802), 362 | (48803), (48804), (48805), (48806), (48807), (48808), (48809), (48810), (48811), (48812), (48813), (48814), (48815), (48816), (48817), (48818), 363 | (48819), (48820), (48821), (48822), (48823), (48824), (48825), (48826), (48827), (48828), (48829), (48830), (48831), (48832), (48833), (48836), 364 | (48837), (48838), (48839), (48840), (48841), (48842), (48843), (48844), (48845), (48846), (48847), (48848), (48849), (48850), (48851), (48852), 365 | (48853), (48854), (48855), (48860), (48861), (48862), (48863), (48864), (48865), (48866), (48867), (48868), (48869), (48870), (48871), (48872), 366 | (48873), (48874), (48875), (48876), (48877), (48878), (48879), (48880), (48881), (48882), (48883), (48884), (48885), (48886), (48887), (48888), 367 | (48889), (48890), (48891), (48892), (48893), (48894), (48895), (48896), (48897), (48898), (48899), (48900), (48901), (48902), (48903), (48904), 368 | (48905), (48906), (48907), (48908), (48909), (48910), (48911), (48912), (48913), (48914), (48915), (48916), (48917), (48918), (48919), (48922), 369 | (48923), (48924), (48925), (48926), (48927), (48928), (48929), (48930), (48931), (49301), (49312), (49313), (49314), (49852), (49853), (49854), 370 | (49855), (49334), (49703), (49704), (49706), (48945), (49050), (48527), (49662), (49663), (49665), (49693), (49343), (49640), (49917), (48601), 371 | (49288), (49289), (48679), (49362), (49223), (49278), (49340), (49373), (49655), (49680), (49739), (49750), (49915), (49916), (49209), (49645), 372 | (49689), (49708), (49733), (49873), (49984), (50442), (50204), (51682), (51683), (51684), (51685), (51686), (51687), (51688), (51689), (51690), 373 | (51691), (51692), (51693), (51694), (51695), (51696), (51697), (51698), (51699), (51700), (51701), (51702), (51703), (51704), (51705), (51706), 374 | (51707), (51708), (51709), (51710), (51711), (51712), (51713), (51714), (51715), (51716), (51717), (51718), (51719), (51720), (51721), (51722), 375 | (51723), (51724), (51725), (51726), (51727), (51728), (51729), (51730), (51731), (51732), (51733), (51734), (51735), (51736), (51737), (51738), 376 | (51739), (51740), (51741), (51742), (51743), (51744), (51745), (51746), (51747), (51748), (51749), (51750), (51751), (51752), (51753), (51754), 377 | (51755), (51756), (51757), (51758), (51759), (51760), (51761), (51762), (51763), (51764), (51765), (51766), (51767), (51768), (51769), (51770), 378 | (51771), (51772), (51773), (51774), (51775), (51776), (53491), (53492), (53493), (53494), (53495), (53496), (53497), (53498), (53499), (53500), 379 | (53501), (53502), (53503), (53504), (53505), (53506), (53507), (53508), (53509), (54592), (50315), (50318), (50319), (52567), (50815), (53889), 380 | (53890), (54069), (54860), (50840), (53891), (53924), (51997), (51998), (54847), (54857), (56806), (54212), (54452), (54810), (50093), (54822), 381 | (50289), (50301), (50307), (52189), (52202), (52272), (52275), (52276), (52345), (52562), (52563), (52565), (52729), (53510), (54218), (54455), 382 | (54467), (50248), (50431), (52011), (52062), (54291), (54470); 383 | -------------------------------------------------------------------------------- /src/AuctionHouseBot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2010 Trinity 3 | * Copyright (C) 2005-2009 MaNGOS 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #include "ObjectMgr.h" 21 | #include "AuctionHouseMgr.h" 22 | #include "Config.h" 23 | #include "Player.h" 24 | #include "WorldSession.h" 25 | #include "GameTime.h" 26 | #include "DatabaseEnv.h" 27 | #include "ScriptMgr.h" 28 | 29 | #include "AuctionHouseBot.h" 30 | #include "AuctionHouseBotCommon.h" 31 | #include "AuctionHouseSearcher.h" 32 | 33 | using namespace std; 34 | 35 | AuctionHouseBot::AuctionHouseBot(uint32 account, uint32 id) 36 | { 37 | _account = account; 38 | _id = id; 39 | 40 | _lastrun_a_sec = time(NULL); 41 | _lastrun_h_sec = time(NULL); 42 | _lastrun_n_sec = time(NULL); 43 | 44 | _allianceConfig = NULL; 45 | _hordeConfig = NULL; 46 | _neutralConfig = NULL; 47 | } 48 | 49 | AuctionHouseBot::~AuctionHouseBot() 50 | { 51 | // Nothing 52 | } 53 | 54 | uint32 AuctionHouseBot::getElement(std::set set, int index, uint32 botId, uint32 maxDup, AuctionHouseObject* auctionHouse) 55 | { 56 | std::set::iterator it = set.begin(); 57 | std::advance(it, index); 58 | 59 | if (maxDup > 0) 60 | { 61 | uint32 noStacks = 0; 62 | 63 | for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) 64 | { 65 | AuctionEntry* Aentry = itr->second; 66 | 67 | if (Aentry->owner.GetCounter() == botId) 68 | { 69 | if (*it == Aentry->item_template) 70 | { 71 | noStacks++; 72 | } 73 | } 74 | } 75 | 76 | if (noStacks >= maxDup) 77 | { 78 | return 0; 79 | } 80 | } 81 | 82 | return *it; 83 | } 84 | 85 | uint32 AuctionHouseBot::getStackCount(AHBConfig* config, uint32 max) 86 | { 87 | if (max == 1) 88 | { 89 | return 1; 90 | } 91 | 92 | // 93 | // Organize the stacks in a pseudo random way 94 | // 95 | 96 | if (config->DivisibleStacks) 97 | { 98 | uint32 ret = 0; 99 | 100 | if (max % 5 == 0) // 5, 10, 15, 20 101 | { 102 | ret = urand(1, 4) * 5; 103 | } 104 | 105 | if (max % 4 == 0) // 4, 8, 12, 16 106 | { 107 | ret = urand(1, 4) * 4; 108 | } 109 | 110 | if (max % 3 == 0) // 3, 6, 9, 18 111 | { 112 | ret = urand(1, 3) * 3; 113 | } 114 | 115 | if (ret > max) 116 | { 117 | ret = max; 118 | } 119 | 120 | return ret; 121 | } 122 | 123 | // 124 | // Totally random 125 | // 126 | 127 | return urand(1, max); 128 | } 129 | 130 | uint32 AuctionHouseBot::getElapsedTime(uint32 timeClass) 131 | { 132 | switch (timeClass) 133 | { 134 | case 2: 135 | return urand(1, 6) * 600; // SHORT = From 10 to 60 minutes 136 | 137 | case 1: 138 | return urand(1, 24) * 3600; // MEDIUM = From 1 to 24 hours 139 | 140 | default: 141 | return urand(24, 72) * 3600; // LONG = From 1 to 3 days 142 | } 143 | } 144 | 145 | uint32 AuctionHouseBot::getNofAuctions(AHBConfig* config, AuctionHouseObject* auctionHouse, ObjectGuid guid) 146 | { 147 | // 148 | // All the auctions 149 | // 150 | 151 | if (!config->ConsiderOnlyBotAuctions) 152 | { 153 | return auctionHouse->Getcount(); 154 | } 155 | 156 | // 157 | // Just the one handled by the bot 158 | // 159 | 160 | uint32 count = 0; 161 | 162 | for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) 163 | { 164 | AuctionEntry* Aentry = itr->second; 165 | 166 | if (guid == Aentry->owner) 167 | { 168 | count++; 169 | } 170 | } 171 | 172 | return count; 173 | } 174 | 175 | // ============================================================================= 176 | // This routine performs the bidding/buyout operations for the bot 177 | // ============================================================================= 178 | 179 | void AuctionHouseBot::Buy(Player* AHBplayer, AHBConfig* config, WorldSession* session) 180 | { 181 | // 182 | // Check if disabled 183 | // 184 | 185 | if (!config->AHBBuyer) 186 | { 187 | return; 188 | } 189 | 190 | // 191 | // Retrieve items not owned by the bot and not bought/bidded on by the bot 192 | // 193 | 194 | QueryResult ahContentQueryResult = CharacterDatabase.Query("SELECT id FROM auctionhouse WHERE houseid={} AND itemowner<>{} AND buyguid<>{}", config->GetAHID(), _id, _id); 195 | 196 | if (!ahContentQueryResult) 197 | { 198 | return; 199 | } 200 | 201 | if (ahContentQueryResult->GetRowCount() == 0) 202 | { 203 | return; 204 | } 205 | 206 | if (config->DebugOutBuyer) 207 | { 208 | LOG_INFO("module", "AHBot [{}]: Performing Buy operations for AH={} nbOfAuctions={}", _id, config->GetAHID(), ahContentQueryResult->GetRowCount()); 209 | } 210 | 211 | // 212 | // Fetches content of selected AH to look for possible bids 213 | // 214 | 215 | AuctionHouseObject* auctionHouseObject = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); 216 | std::set auctionsGuidsToConsider; 217 | 218 | do 219 | { 220 | uint32 autionGuid = ahContentQueryResult->Fetch()->Get(); 221 | auctionsGuidsToConsider.insert(autionGuid); 222 | } while (ahContentQueryResult->NextRow()); 223 | 224 | // 225 | // If it's not possible to bid stop here 226 | // 227 | 228 | if (auctionsGuidsToConsider.empty()) 229 | { 230 | if (config->DebugOutBuyer) 231 | { 232 | LOG_INFO("module", "AHBot [{}]: no auctions to bid on has been recovered", _id); 233 | } 234 | 235 | return; 236 | } 237 | 238 | // 239 | // Perform the operation for a maximum amount of bids attempts configured 240 | // 241 | 242 | if (config->TraceBuyer) 243 | { 244 | LOG_INFO("module", "AHBot [{}]: Considering {} auctions per interval to bid on.", _id, config->GetBidsPerInterval()); 245 | } 246 | 247 | for (uint32 count = 1; count <= config->GetBidsPerInterval(); ++count) 248 | { 249 | if (auctionsGuidsToConsider.empty()) { 250 | return; 251 | } 252 | 253 | std::set::iterator it = auctionsGuidsToConsider.begin(); 254 | std::advance(it, 0); 255 | uint32 auctionID = *it; 256 | AuctionEntry* auction = auctionHouseObject->GetAuction(auctionID); 257 | 258 | // 259 | // Prevent to bid again on the same auction 260 | // 261 | auctionsGuidsToConsider.erase(it); 262 | 263 | if (!auction) 264 | { 265 | if (config->DebugOutBuyer) 266 | { 267 | LOG_ERROR("module", "AHBot [{}]: Auction id: {} Possible entry to buy/bid from AH pool is invalid, this should not happen, moving on next auciton", _id, auctionID); 268 | } 269 | continue; 270 | } 271 | 272 | // 273 | // Prevent from buying items from the other bots 274 | // 275 | 276 | if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) 277 | { 278 | continue; 279 | } 280 | 281 | // 282 | // Get the item information 283 | // 284 | 285 | Item* pItem = sAuctionMgr->GetAItem(auction->item_guid); 286 | 287 | if (!pItem) 288 | { 289 | if (config->DebugOutBuyer) 290 | { 291 | LOG_ERROR("module", "AHBot [{}]: item {} doesn't exist, perhaps bought already?", _id, auction->item_guid.ToString()); 292 | } 293 | 294 | continue; 295 | } 296 | 297 | // 298 | // Get the item prototype 299 | // 300 | 301 | ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); 302 | 303 | 304 | // 305 | // Determine current price. 306 | // 307 | 308 | uint32 currentPrice = static_cast(auction->bid ? auction->bid : auction->startbid); 309 | 310 | // 311 | // Determine maximum bid and skip auctions with too high a currentPrice. 312 | // 313 | 314 | uint32 basePrice = static_cast(config->UseBuyPriceForBuyer ? prototype->BuyPrice : prototype->SellPrice); 315 | uint32 maximumBid = static_cast(basePrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality)); 316 | 317 | if (config->TraceBuyer) 318 | { 319 | LOG_INFO("module", "-------------------------------------------------"); 320 | LOG_INFO("module", "AHBot [{}]: Info for Auction #{}:", _id, auction->Id); 321 | LOG_INFO("module", "AHBot [{}]: AuctionHouse: {}", _id, auction->GetHouseId()); 322 | LOG_INFO("module", "AHBot [{}]: Owner: {}", _id, auction->owner.ToString()); 323 | LOG_INFO("module", "AHBot [{}]: Bidder: {}", _id, auction->bidder.ToString()); 324 | LOG_INFO("module", "AHBot [{}]: Starting Bid: {}", _id, auction->startbid); 325 | LOG_INFO("module", "AHBot [{}]: Current Bid: {}", _id, currentPrice); 326 | LOG_INFO("module", "AHBot [{}]: Buyout: {}", _id, auction->buyout); 327 | LOG_INFO("module", "AHBot [{}]: Deposit: {}", _id, auction->deposit); 328 | LOG_INFO("module", "AHBot [{}]: Expire Time: {}", _id, uint32(auction->expire_time)); 329 | LOG_INFO("module", "AHBot [{}]: Bid Max: {}", _id, maximumBid); 330 | LOG_INFO("module", "AHBot [{}]: Item GUID: {}", _id, auction->item_guid.ToString()); 331 | LOG_INFO("module", "AHBot [{}]: Item Template: {}", _id, auction->item_template); 332 | LOG_INFO("module", "AHBot [{}]: Item ID: {}", _id, prototype->ItemId); 333 | LOG_INFO("module", "AHBot [{}]: Buy Price: {}", _id, prototype->BuyPrice); 334 | LOG_INFO("module", "AHBot [{}]: Sell Price: {}", _id, prototype->SellPrice); 335 | LOG_INFO("module", "AHBot [{}]: Bonding: {}", _id, prototype->Bonding); 336 | LOG_INFO("module", "AHBot [{}]: Quality: {}", _id, prototype->Quality); 337 | LOG_INFO("module", "AHBot [{}]: Item Level: {}", _id, prototype->ItemLevel); 338 | LOG_INFO("module", "AHBot [{}]: Ammo Type: {}", _id, prototype->AmmoType); 339 | LOG_INFO("module", "-------------------------------------------------"); 340 | } 341 | 342 | if (currentPrice > maximumBid) 343 | { 344 | if (config->TraceBuyer) 345 | { 346 | LOG_INFO("module", "AHBot [{}]: Current price too high, skipped.", _id); 347 | } 348 | continue; 349 | } 350 | 351 | 352 | // 353 | // Recalculate the bid depending on the type of the item 354 | // 355 | 356 | switch (prototype->Class) 357 | { 358 | case ITEM_CLASS_PROJECTILE: 359 | maximumBid = 0; 360 | break; 361 | case ITEM_CLASS_GENERIC: 362 | maximumBid = 0; 363 | break; 364 | case ITEM_CLASS_MONEY: 365 | maximumBid = 0; 366 | break; 367 | case ITEM_CLASS_PERMANENT: 368 | maximumBid = 0; 369 | break; 370 | default: 371 | break; 372 | } 373 | 374 | // 375 | // Make sure to skip the auction if maximum bid is 0. 376 | // 377 | 378 | if (maximumBid == 0) 379 | { 380 | if (config->TraceBuyer) 381 | { 382 | LOG_INFO("module", "AHBot [{}]: Maximum bid value for item class {} is 0, skipped.", _id, prototype->Class); 383 | } 384 | continue; 385 | } 386 | 387 | // 388 | // Calculate our bid 389 | // 390 | 391 | double bidRate = static_cast(urand(1, 100)) / 100; 392 | double bidValue = currentPrice + ((maximumBid - currentPrice) * bidRate); 393 | uint32 bidPrice = static_cast(bidValue); 394 | 395 | 396 | // 397 | // Check our bid is high enough to be valid. If not, correct it to minimum. 398 | // 399 | uint32 minimumOutbid = auction->GetAuctionOutBid(); 400 | if ((currentPrice + minimumOutbid) > bidPrice) 401 | { 402 | bidPrice = static_cast(currentPrice + minimumOutbid); 403 | } 404 | 405 | if (bidPrice > maximumBid) 406 | { 407 | if (config->TraceBuyer) 408 | { 409 | LOG_INFO("module", "AHBot [{}]: Bid was above bidMax for item={} AH={}", _id, auction->item_guid.ToString(), config->GetAHID()); 410 | } 411 | bidPrice = static_cast(maximumBid); 412 | } 413 | 414 | if (config->DebugOutBuyer) 415 | { 416 | LOG_INFO("module", "-------------------------------------------------"); 417 | LOG_INFO("module", "AHBot [{}]: Bid Rate: {}", _id, bidRate); 418 | LOG_INFO("module", "AHBot [{}]: Bid Value: {}", _id, bidValue); 419 | LOG_INFO("module", "AHBot [{}]: Bid Price: {}", _id, bidPrice); 420 | LOG_INFO("module", "AHBot [{}]: Minimum Outbid: {}", _id, minimumOutbid); 421 | LOG_INFO("module", "-------------------------------------------------"); 422 | } 423 | 424 | 425 | // 426 | // Check whether we do normal bid, or buyout 427 | // 428 | 429 | if ((bidPrice < auction->buyout) || (auction->buyout == 0)) 430 | { 431 | // 432 | // Return money to last bidder. 433 | // 434 | 435 | if (auction->bidder) 436 | { 437 | if (auction->bidder != AHBplayer->GetGUID()) 438 | { 439 | // 440 | // Mail to last bidder and return their money 441 | // 442 | 443 | auto trans = CharacterDatabase.BeginTransaction(); 444 | sAuctionMgr->SendAuctionOutbiddedMail(auction, bidPrice, session->GetPlayer(), trans); 445 | CharacterDatabase.CommitTransaction(trans); 446 | } 447 | } 448 | 449 | auction->bidder = AHBplayer->GetGUID(); 450 | auction->bid = bidPrice; 451 | 452 | sAuctionMgr->GetAuctionHouseSearcher()->UpdateBid(auction); 453 | 454 | // 455 | // update/save the auction into database 456 | // 457 | CharacterDatabase.Execute("UPDATE auctionhouse SET buyguid = '{}', lastbid = '{}' WHERE id = '{}'", auction->bidder.GetCounter(), auction->bid, auction->Id); 458 | 459 | if (config->TraceBuyer) 460 | { 461 | LOG_INFO("module", "AHBot [{}]: New bid, itemid={}, ah={}, auctionId={} item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, auction->GetHouseId(), auction->Id, auction->item_template, auction->startbid, currentPrice, auction->buyout); 462 | } 463 | } 464 | else 465 | { 466 | // 467 | // Perform the buyout 468 | // 469 | 470 | auto trans = CharacterDatabase.BeginTransaction(); 471 | 472 | if ((auction->bidder) && (AHBplayer->GetGUID() != auction->bidder)) 473 | { 474 | // 475 | // Mail to last bidder and return their money 476 | // 477 | 478 | sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, session->GetPlayer(), trans); 479 | } 480 | 481 | auction->bidder = AHBplayer->GetGUID(); 482 | auction->bid = auction->buyout; 483 | 484 | // 485 | // Send mails to buyer & seller 486 | // 487 | 488 | sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); 489 | sAuctionMgr->SendAuctionWonMail(auction, trans); 490 | 491 | // 492 | // Removes any trace of the item 493 | // 494 | 495 | ScriptMgr::instance()->OnAuctionSuccessful(auctionHouseObject, auction); 496 | auction->DeleteFromDB(trans); 497 | sAuctionMgr->RemoveAItem(auction->item_guid); 498 | auctionHouseObject->RemoveAuction(auction); 499 | 500 | 501 | CharacterDatabase.CommitTransaction(trans); 502 | 503 | if (config->TraceBuyer) 504 | { 505 | LOG_INFO("module", "AHBot [{}]: Bought , itemid={}, ah={}, item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, AuctionHouseId(auction->GetHouseId()), auction->item_template, auction->startbid, currentPrice, auction->buyout); 506 | } 507 | } 508 | } 509 | } 510 | 511 | // ============================================================================= 512 | // This routine performs the selling operations for the bot 513 | // ============================================================================= 514 | 515 | void AuctionHouseBot::Sell(Player* AHBplayer, AHBConfig* config) 516 | { 517 | // 518 | // Check if disabled 519 | // 520 | 521 | if (!config->AHBSeller) 522 | { 523 | return; 524 | } 525 | 526 | // 527 | // Check the given limits 528 | // 529 | 530 | uint32 minTotalItems = config->GetMinItems(); 531 | uint32 maxTotalItems = config->GetMaxItems(); 532 | 533 | if (maxTotalItems == 0) 534 | { 535 | return; 536 | } 537 | 538 | // 539 | // Retrieve the auction house situation 540 | // 541 | 542 | AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromFactionTemplate(config->GetAHFID()); 543 | 544 | if (!ahEntry) 545 | { 546 | return; 547 | } 548 | 549 | AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); 550 | 551 | if (!auctionHouse) 552 | { 553 | return; 554 | } 555 | 556 | // don't mess with the AH update let server do it. 557 | //auctionHouseObject->Update(); 558 | 559 | // 560 | // Check if we are clear to proceed 561 | // 562 | 563 | bool aboveMin = false; 564 | bool aboveMax = false; 565 | uint32 nbOfAuctions = getNofAuctions(config, auctionHouse, AHBplayer->GetGUID()); 566 | uint32 nbItemsToSellThisCycle = 0; 567 | 568 | if (nbOfAuctions >= minTotalItems) 569 | { 570 | aboveMin = true; 571 | 572 | if (config->DebugOutSeller) 573 | { 574 | LOG_TRACE("module", "AHBot [{}]: Auctions above minimum", _id); 575 | } 576 | } 577 | 578 | if (nbOfAuctions >= maxTotalItems) 579 | { 580 | aboveMax = true; 581 | 582 | if (config->DebugOutSeller) 583 | { 584 | LOG_TRACE("module", "AHBot [{}]: Auctions at or above maximum", _id); 585 | } 586 | 587 | return; 588 | } 589 | 590 | if ((maxTotalItems - nbOfAuctions) >= config->ItemsPerCycle) 591 | { 592 | nbItemsToSellThisCycle = config->ItemsPerCycle; 593 | } 594 | else 595 | { 596 | nbItemsToSellThisCycle = (maxTotalItems - nbOfAuctions); 597 | } 598 | 599 | // 600 | // Retrieve the configuration for this run 601 | // 602 | 603 | uint32 maxGreyTG = config->GetMaximum(AHB_GREY_TG); 604 | uint32 maxWhiteTG = config->GetMaximum(AHB_WHITE_TG); 605 | uint32 maxGreenTG = config->GetMaximum(AHB_GREEN_TG); 606 | uint32 maxBlueTG = config->GetMaximum(AHB_BLUE_TG); 607 | uint32 maxPurpleTG = config->GetMaximum(AHB_PURPLE_TG); 608 | uint32 maxOrangeTG = config->GetMaximum(AHB_ORANGE_TG); 609 | uint32 maxYellowTG = config->GetMaximum(AHB_YELLOW_TG); 610 | 611 | uint32 maxGreyI = config->GetMaximum(AHB_GREY_I); 612 | uint32 maxWhiteI = config->GetMaximum(AHB_WHITE_I); 613 | uint32 maxGreenI = config->GetMaximum(AHB_GREEN_I); 614 | uint32 maxBlueI = config->GetMaximum(AHB_BLUE_I); 615 | uint32 maxPurpleI = config->GetMaximum(AHB_PURPLE_I); 616 | uint32 maxOrangeI = config->GetMaximum(AHB_ORANGE_I); 617 | uint32 maxYellowI = config->GetMaximum(AHB_YELLOW_I); 618 | 619 | uint32 currentGreyTG = config->GetItemCounts(AHB_GREY_TG); 620 | uint32 currentWhiteTG = config->GetItemCounts(AHB_WHITE_TG); 621 | uint32 currentGreenTG = config->GetItemCounts(AHB_GREEN_TG); 622 | uint32 currentBlueTG = config->GetItemCounts(AHB_BLUE_TG); 623 | uint32 currentPurpleTG = config->GetItemCounts(AHB_PURPLE_TG); 624 | uint32 currentOrangeTG = config->GetItemCounts(AHB_ORANGE_TG); 625 | uint32 currentYellowTG = config->GetItemCounts(AHB_YELLOW_TG); 626 | 627 | uint32 currentGreyItems = config->GetItemCounts(AHB_GREY_I); 628 | uint32 currentWhiteItems = config->GetItemCounts(AHB_WHITE_I); 629 | uint32 currentGreenItems = config->GetItemCounts(AHB_GREEN_I); 630 | uint32 currentBlueItems = config->GetItemCounts(AHB_BLUE_I); 631 | uint32 currentPurpleItems = config->GetItemCounts(AHB_PURPLE_I); 632 | uint32 currentOrangeItems = config->GetItemCounts(AHB_ORANGE_I); 633 | uint32 currentYellowItems = config->GetItemCounts(AHB_YELLOW_I); 634 | 635 | // 636 | // Loop variables 637 | // 638 | 639 | uint32 nbSold = 0; // Tracing counter 640 | uint32 binEmpty = 0; // Tracing counter 641 | uint32 noNeed = 0; // Tracing counter 642 | uint32 tooMany = 0; // Tracing counter 643 | uint32 loopBrk = 0; // Tracing counter 644 | uint32 err = 0; // Tracing counter 645 | 646 | for (uint32 cnt = 1; cnt <= nbItemsToSellThisCycle; cnt++) 647 | { 648 | uint32 itemTypeSelectedToSell = 0; 649 | uint32 itemID = 0; 650 | uint32 loopbreaker = 0; 651 | 652 | // 653 | // Select, in rarity order, a new random item 654 | // 655 | 656 | while (itemID == 0 && loopbreaker <= AUCTION_HOUSE_BOT_LOOP_BREAKER) 657 | { 658 | loopbreaker++; 659 | 660 | // Poor 661 | 662 | if ((config->GreyItemsBin.size() > 0) && (currentGreyItems < maxGreyI)) 663 | { 664 | itemTypeSelectedToSell = AHB_GREY_I; 665 | itemID = getElement(config->GreyItemsBin, urand(0, config->GreyItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 666 | } 667 | 668 | if (itemID == 0 && (config->GreyTradeGoodsBin.size() > 0) && (currentGreyTG < maxGreyTG)) 669 | { 670 | itemTypeSelectedToSell = AHB_GREY_TG; 671 | itemID = getElement(config->GreyTradeGoodsBin, urand(0, config->GreyTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 672 | } 673 | 674 | // Normal 675 | 676 | if (itemID == 0 && (config->WhiteItemsBin.size() > 0) && (currentWhiteItems < maxWhiteI)) 677 | { 678 | itemTypeSelectedToSell = AHB_WHITE_I; 679 | itemID = getElement(config->WhiteItemsBin, urand(0, config->WhiteItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 680 | } 681 | 682 | if (itemID == 0 && (config->WhiteTradeGoodsBin.size() > 0) && (currentWhiteTG < maxWhiteTG)) 683 | { 684 | itemTypeSelectedToSell = AHB_WHITE_TG; 685 | itemID = getElement(config->WhiteTradeGoodsBin, urand(0, config->WhiteTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 686 | } 687 | 688 | // Uncommon 689 | 690 | if (itemID == 0 && (config->GreenItemsBin.size() > 0) && (currentGreenItems < maxGreenI)) 691 | { 692 | itemTypeSelectedToSell = AHB_GREEN_I; 693 | itemID = getElement(config->GreenItemsBin, urand(0, config->GreenItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 694 | } 695 | 696 | if (itemID == 0 && (config->GreenTradeGoodsBin.size() > 0) && (currentGreenTG < maxGreenTG)) 697 | { 698 | itemTypeSelectedToSell = AHB_GREEN_TG; 699 | itemID = getElement(config->GreenTradeGoodsBin, urand(0, config->GreenTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 700 | } 701 | 702 | // Rare 703 | 704 | if (itemID == 0 && (config->BlueItemsBin.size() > 0) && (currentBlueItems < maxBlueI)) 705 | { 706 | itemTypeSelectedToSell = AHB_BLUE_I; 707 | itemID = getElement(config->BlueItemsBin, urand(0, config->BlueItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 708 | } 709 | 710 | if (itemID == 0 && (config->BlueTradeGoodsBin.size() > 0) && (currentBlueTG < maxBlueTG)) 711 | { 712 | itemTypeSelectedToSell = AHB_BLUE_TG; 713 | itemID = getElement(config->BlueTradeGoodsBin, urand(0, config->BlueTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 714 | } 715 | 716 | // Epic 717 | 718 | if (itemID == 0 && (config->PurpleItemsBin.size() > 0) && (currentPurpleItems < maxPurpleI)) 719 | { 720 | itemTypeSelectedToSell = AHB_PURPLE_I; 721 | itemID = getElement(config->PurpleItemsBin, urand(0, config->PurpleItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 722 | } 723 | 724 | if (itemID == 0 && (config->PurpleTradeGoodsBin.size() > 0) && (currentPurpleTG < maxPurpleTG)) 725 | { 726 | itemTypeSelectedToSell = AHB_PURPLE_TG; 727 | itemID = getElement(config->PurpleTradeGoodsBin, urand(0, config->PurpleTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 728 | } 729 | 730 | // Legendary 731 | 732 | if (itemID == 0 && (config->OrangeItemsBin.size() > 0) && (currentOrangeItems < maxOrangeI)) 733 | { 734 | itemTypeSelectedToSell = AHB_ORANGE_I; 735 | itemID = getElement(config->OrangeItemsBin, urand(0, config->OrangeItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 736 | } 737 | 738 | if (itemID == 0 && (config->OrangeTradeGoodsBin.size() > 0) && (currentOrangeTG < maxOrangeTG)) 739 | { 740 | itemTypeSelectedToSell = AHB_ORANGE_TG; 741 | itemID = getElement(config->OrangeTradeGoodsBin, urand(0, config->OrangeTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 742 | } 743 | 744 | // Artifact 745 | 746 | if (itemID == 0 && (config->YellowItemsBin.size() > 0) && (currentYellowItems < maxYellowI)) 747 | { 748 | itemTypeSelectedToSell = AHB_YELLOW_I; 749 | itemID = getElement(config->YellowItemsBin, urand(0, config->YellowItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 750 | } 751 | 752 | if (itemID == 0 && (config->YellowTradeGoodsBin.size() > 0) && (currentYellowTG < maxYellowTG)) 753 | { 754 | itemTypeSelectedToSell = AHB_YELLOW_TG; 755 | itemID = getElement(config->YellowTradeGoodsBin, urand(0, config->YellowTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); 756 | } 757 | 758 | if (itemID == 0) 759 | { 760 | binEmpty++; 761 | 762 | if (config->DebugOutSeller) 763 | { 764 | LOG_ERROR("module", "AHBot [{}]: No item could be selected from the bins", _id); 765 | } 766 | 767 | break; 768 | } 769 | } 770 | 771 | if (itemID == 0 || loopbreaker > AUCTION_HOUSE_BOT_LOOP_BREAKER) 772 | { 773 | loopBrk++; 774 | continue; 775 | } 776 | 777 | // 778 | // Retrieve information about the selected item 779 | // 780 | 781 | ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemID); 782 | 783 | if (prototype == NULL) 784 | { 785 | err++; 786 | 787 | if (config->DebugOutSeller) 788 | { 789 | LOG_ERROR("module", "AHBot [{}]: could not get prototype of item {}", _id, itemID); 790 | } 791 | 792 | continue; 793 | } 794 | 795 | Item* item = Item::CreateItem(itemID, 1, AHBplayer); 796 | 797 | if (item == NULL) 798 | { 799 | err++; 800 | 801 | if (config->DebugOutSeller) 802 | { 803 | LOG_ERROR("module", "AHBot [{}]: could not create item from prototype {}", _id, itemID); 804 | } 805 | 806 | continue; 807 | } 808 | 809 | // 810 | // Start interacting with the item by adding a random property 811 | // 812 | 813 | item->AddToUpdateQueueOf(AHBplayer); 814 | 815 | uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); 816 | 817 | if (randomPropertyId != 0) 818 | { 819 | item->SetItemRandomProperties(randomPropertyId); 820 | } 821 | 822 | if (prototype->Quality > AHB_MAX_QUALITY) 823 | { 824 | err++; 825 | 826 | if (config->DebugOutSeller) 827 | { 828 | LOG_ERROR("module", "AHBot [{}]: Quality {} TOO HIGH for item {}", _id, prototype->Quality, itemID); 829 | } 830 | 831 | item->RemoveFromUpdateQueueOf(AHBplayer); 832 | continue; 833 | } 834 | 835 | // 836 | // Determine the price 837 | // 838 | 839 | uint64 buyoutPrice = 0; 840 | uint64 bidPrice = 0; 841 | uint32 stackCount = 1; 842 | 843 | if (config->SellAtMarketPrice) 844 | { 845 | buyoutPrice = config->GetItemPrice(itemID); 846 | } 847 | 848 | if (buyoutPrice == 0) 849 | { 850 | if (config->UseBuyPriceForSeller) 851 | { 852 | buyoutPrice = prototype->BuyPrice; 853 | } 854 | else 855 | { 856 | buyoutPrice = prototype->SellPrice; 857 | } 858 | } 859 | 860 | buyoutPrice = buyoutPrice * urand(config->GetMinPrice(prototype->Quality), config->GetMaxPrice(prototype->Quality)); 861 | buyoutPrice = buyoutPrice / 100; 862 | 863 | bidPrice = buyoutPrice * urand(config->GetMinBidPrice(prototype->Quality), config->GetMaxBidPrice(prototype->Quality)); 864 | bidPrice = bidPrice / 100; 865 | 866 | // 867 | // Determine the stack size 868 | // 869 | 870 | if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1) 871 | { 872 | stackCount = minValue(getStackCount(config, item->GetMaxStackCount()), config->GetMaxStack(prototype->Quality)); 873 | } 874 | else if (config->GetMaxStack(prototype->Quality) == 0 && item->GetMaxStackCount() > 1) 875 | { 876 | stackCount = getStackCount(config, item->GetMaxStackCount()); 877 | } 878 | else 879 | { 880 | stackCount = 1; 881 | } 882 | 883 | item->SetCount(stackCount); 884 | 885 | // 886 | // Determine the auction time 887 | // 888 | 889 | uint32 elapsingTime = getElapsedTime(config->ElapsingTimeClass); 890 | 891 | // 892 | // Determine the deposit 893 | // 894 | 895 | uint32 deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, elapsingTime, item, stackCount); 896 | 897 | // 898 | // Perform the auction 899 | // 900 | 901 | auto trans = CharacterDatabase.BeginTransaction(); 902 | 903 | AuctionEntry* auctionEntry = new AuctionEntry(); 904 | auctionEntry->Id = sObjectMgr->GenerateAuctionID(); 905 | auctionEntry->houseId = AuctionHouseId(config->GetAHID()); 906 | auctionEntry->item_guid = item->GetGUID(); 907 | auctionEntry->item_template = item->GetEntry(); 908 | auctionEntry->itemCount = item->GetCount(); 909 | auctionEntry->owner = AHBplayer->GetGUID(); 910 | auctionEntry->startbid = bidPrice * stackCount; 911 | auctionEntry->buyout = buyoutPrice * stackCount; 912 | auctionEntry->bid = 0; 913 | auctionEntry->deposit = deposit; 914 | auctionEntry->expire_time = (time_t)elapsingTime + time(NULL); 915 | auctionEntry->auctionHouseEntry = ahEntry; 916 | 917 | item->SaveToDB(trans); 918 | item->RemoveFromUpdateQueueOf(AHBplayer); 919 | sAuctionMgr->AddAItem(item); 920 | auctionHouse->AddAuction(auctionEntry); 921 | auctionEntry->SaveToDB(trans); 922 | 923 | CharacterDatabase.CommitTransaction(trans); 924 | 925 | // 926 | // Increments the number of items presents in the auction 927 | // 928 | 929 | // todo: reread config for actual values, maybe an array to not rely on local count that could potentially be mismatched from config. 930 | // config is updated from callback received after auctionHouseObject->AddAuction(auctionEntry); 931 | // or maybe reparse the server actual value each update cycle, would need profiling. 932 | switch (itemTypeSelectedToSell) 933 | { 934 | case AHB_GREY_I: 935 | ++currentGreyItems; 936 | break; 937 | 938 | case AHB_WHITE_I: 939 | ++currentWhiteItems; 940 | break; 941 | 942 | case AHB_GREEN_I: 943 | ++currentGreenItems; 944 | break; 945 | 946 | case AHB_BLUE_I: 947 | ++currentBlueItems; 948 | break; 949 | 950 | case AHB_PURPLE_I: 951 | ++currentPurpleItems; 952 | break; 953 | 954 | case AHB_ORANGE_I: 955 | ++currentOrangeItems; 956 | break; 957 | 958 | case AHB_YELLOW_I: 959 | ++currentYellowItems; 960 | break; 961 | 962 | case AHB_GREY_TG: 963 | ++currentGreyTG; 964 | break; 965 | 966 | case AHB_WHITE_TG: 967 | ++currentWhiteTG; 968 | break; 969 | 970 | case AHB_GREEN_TG: 971 | ++currentGreenTG; 972 | break; 973 | 974 | case AHB_BLUE_TG: 975 | ++currentBlueTG; 976 | break; 977 | 978 | case AHB_PURPLE_TG: 979 | ++currentPurpleTG; 980 | break; 981 | 982 | case AHB_ORANGE_TG: 983 | ++currentOrangeTG; 984 | break; 985 | 986 | case AHB_YELLOW_TG: 987 | ++currentYellowTG; 988 | break; 989 | 990 | default: 991 | break; 992 | } 993 | 994 | nbSold++; 995 | 996 | if (config->TraceSeller) 997 | { 998 | LOG_INFO("module", "AHBot [{}]: New stack ah={}, id={}, stack={}, bid={}, buyout={}", _id, config->GetAHID(), itemID, stackCount, auctionEntry->startbid, auctionEntry->buyout); 999 | } 1000 | } 1001 | 1002 | if (config->TraceSeller) 1003 | { 1004 | LOG_INFO("module", "AHBot [{}]: auctionhouse {}, req={}, sold={}, aboveMin={}, aboveMax={}, loopBrk={}, noNeed={}, tooMany={}, binEmpty={}, err={}", _id, config->GetAHID(), nbItemsToSellThisCycle, nbSold, aboveMin, aboveMax, loopBrk, noNeed, tooMany, binEmpty, err); 1005 | } 1006 | } 1007 | 1008 | // ============================================================================= 1009 | // Perform an update cycle 1010 | // ============================================================================= 1011 | 1012 | void AuctionHouseBot::Update() 1013 | { 1014 | time_t _newrun = time(NULL); 1015 | 1016 | // 1017 | // If no configuration is associated, then stop here 1018 | // 1019 | 1020 | if (!_allianceConfig && !_hordeConfig && !_neutralConfig) 1021 | { 1022 | return; 1023 | } 1024 | 1025 | // 1026 | // Preprare for operation 1027 | // 1028 | 1029 | std::string accountName = "AuctionHouseBot" + std::to_string(_account); 1030 | 1031 | WorldSession _session(_account, std::move(accountName), 0, nullptr, SEC_PLAYER, sWorld->getIntConfig(CONFIG_EXPANSION), 0, LOCALE_enUS, 0, false, false, 0); 1032 | 1033 | Player _AHBplayer(&_session); 1034 | _AHBplayer.Initialize(_id); 1035 | 1036 | ObjectAccessor::AddObject(&_AHBplayer); 1037 | 1038 | LOG_INFO("module", "AHBot [{}]: Begin Performing Update Cycle", _id); 1039 | 1040 | // 1041 | // Perform update for the factions markets 1042 | // 1043 | 1044 | if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) 1045 | { 1046 | // 1047 | // Alliance 1048 | // 1049 | 1050 | if (_allianceConfig) 1051 | { 1052 | if (_allianceConfig->TraceSeller) 1053 | { 1054 | LOG_INFO("module", "AHBot [{}]: Begin Sell for Alliance...", _id); 1055 | } 1056 | 1057 | Sell(&_AHBplayer, _allianceConfig); 1058 | 1059 | if (((_newrun - _lastrun_a_sec) >= (_allianceConfig->GetBiddingInterval() * MINUTE)) && (_allianceConfig->GetBidsPerInterval() > 0)) 1060 | { 1061 | if (_allianceConfig->TraceBuyer) 1062 | { 1063 | LOG_INFO("module", "AHBot [{}]: Begin Buy for Alliance...", _id); 1064 | } 1065 | 1066 | Buy(&_AHBplayer, _allianceConfig, &_session); 1067 | _lastrun_a_sec = _newrun; 1068 | } 1069 | } 1070 | 1071 | // 1072 | // Horde 1073 | // 1074 | 1075 | if (_hordeConfig) 1076 | { 1077 | if (_hordeConfig->TraceSeller) 1078 | { 1079 | LOG_INFO("module", "AHBot [{}]: Begin Sell for Horde...", _id); 1080 | } 1081 | Sell(&_AHBplayer, _hordeConfig); 1082 | 1083 | if (((_newrun - _lastrun_h_sec) >= (_hordeConfig->GetBiddingInterval() * MINUTE)) && (_hordeConfig->GetBidsPerInterval() > 0)) 1084 | { 1085 | if (_hordeConfig->TraceBuyer) 1086 | { 1087 | LOG_INFO("module", "AHBot [{}]: Begin Buy for Horde...", _id); 1088 | } 1089 | Buy(&_AHBplayer, _hordeConfig, &_session); 1090 | _lastrun_h_sec = _newrun; 1091 | } 1092 | } 1093 | 1094 | } 1095 | 1096 | // 1097 | // Neutral 1098 | // 1099 | 1100 | if (_neutralConfig) 1101 | { 1102 | if (_neutralConfig->TraceSeller) 1103 | { 1104 | LOG_INFO("module", "AHBot [{}]: Begin Sell for Neutral...", _id); 1105 | } 1106 | Sell(&_AHBplayer, _neutralConfig); 1107 | 1108 | if (((_newrun - _lastrun_n_sec) >= (_neutralConfig->GetBiddingInterval() * MINUTE)) && (_neutralConfig->GetBidsPerInterval() > 0)) 1109 | { 1110 | if (_neutralConfig->TraceBuyer) 1111 | { 1112 | LOG_INFO("module", "AHBot [{}]: Begin Buy for Neutral...", _id); 1113 | } 1114 | Buy(&_AHBplayer, _neutralConfig, &_session); 1115 | _lastrun_n_sec = _newrun; 1116 | } 1117 | } 1118 | 1119 | ObjectAccessor::RemoveObject(&_AHBplayer); 1120 | } 1121 | 1122 | // ============================================================================= 1123 | // Execute commands coming from the console 1124 | // ============================================================================= 1125 | 1126 | void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, char* args) 1127 | { 1128 | // 1129 | // Retrieve the auction house configuration 1130 | // 1131 | 1132 | AHBConfig *config = NULL; 1133 | 1134 | switch (ahMapID) 1135 | { 1136 | case 2: 1137 | config = _allianceConfig; 1138 | break; 1139 | case 6: 1140 | config = _hordeConfig; 1141 | break; 1142 | default: 1143 | config = _neutralConfig; 1144 | break; 1145 | } 1146 | 1147 | // 1148 | // Retrive the item quality 1149 | // 1150 | 1151 | std::string color; 1152 | 1153 | switch (col) 1154 | { 1155 | case AHB_GREY: 1156 | color = "grey"; 1157 | break; 1158 | case AHB_WHITE: 1159 | color = "white"; 1160 | break; 1161 | case AHB_GREEN: 1162 | color = "green"; 1163 | break; 1164 | case AHB_BLUE: 1165 | color = "blue"; 1166 | break; 1167 | case AHB_PURPLE: 1168 | color = "purple"; 1169 | break; 1170 | case AHB_ORANGE: 1171 | color = "orange"; 1172 | break; 1173 | case AHB_YELLOW: 1174 | color = "yellow"; 1175 | break; 1176 | default: 1177 | break; 1178 | } 1179 | 1180 | // 1181 | // Perform the command 1182 | // 1183 | 1184 | switch (command) 1185 | { 1186 | case AHBotCommand::buyer: 1187 | { 1188 | char* param1 = strtok(args, " "); 1189 | uint32 state = (uint32)strtoul(param1, NULL, 0); 1190 | 1191 | if (state == 0) 1192 | { 1193 | _allianceConfig->AHBBuyer = false; 1194 | _hordeConfig->AHBBuyer = false; 1195 | _neutralConfig->AHBBuyer = false; 1196 | } 1197 | else 1198 | { 1199 | _allianceConfig->AHBBuyer = true; 1200 | _hordeConfig->AHBBuyer = true; 1201 | _neutralConfig->AHBBuyer = true; 1202 | } 1203 | 1204 | break; 1205 | } 1206 | case AHBotCommand::seller: 1207 | { 1208 | char* param1 = strtok(args, " "); 1209 | uint32 state = (uint32)strtoul(param1, NULL, 0); 1210 | 1211 | if (state == 0) 1212 | { 1213 | _allianceConfig->AHBSeller = false; 1214 | _hordeConfig->AHBSeller = false; 1215 | _neutralConfig->AHBSeller = false; 1216 | } 1217 | else 1218 | { 1219 | _allianceConfig->AHBSeller = true; 1220 | _hordeConfig->AHBSeller = true; 1221 | _neutralConfig->AHBSeller = true; 1222 | } 1223 | 1224 | break; 1225 | } 1226 | case AHBotCommand::useMarketPrice: 1227 | { 1228 | char* param1 = strtok(args, " "); 1229 | uint32 state = (uint32)strtoul(param1, NULL, 0); 1230 | 1231 | if (state == 0) 1232 | { 1233 | _allianceConfig->SellAtMarketPrice = false; 1234 | _hordeConfig->SellAtMarketPrice = false; 1235 | _neutralConfig->SellAtMarketPrice = false; 1236 | } 1237 | else 1238 | { 1239 | _allianceConfig->SellAtMarketPrice = true; 1240 | _hordeConfig->SellAtMarketPrice = true; 1241 | _neutralConfig->SellAtMarketPrice = true; 1242 | } 1243 | 1244 | break; 1245 | } 1246 | case AHBotCommand::ahexpire: 1247 | { 1248 | AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); 1249 | 1250 | AuctionHouseObject::AuctionEntryMap::iterator itr; 1251 | itr = auctionHouse->GetAuctionsBegin(); 1252 | 1253 | // 1254 | // Iterate through all the autions and if they belong to the bot, make them expired 1255 | // 1256 | 1257 | while (itr != auctionHouse->GetAuctionsEnd()) 1258 | { 1259 | if (itr->second->owner.GetCounter() == _id) 1260 | { 1261 | // Expired NOW. 1262 | itr->second->expire_time = GameTime::GetGameTime().count(); 1263 | 1264 | uint32 id = itr->second->Id; 1265 | uint32 expire_time = itr->second->expire_time; 1266 | 1267 | CharacterDatabase.Execute("UPDATE auctionhouse SET time = '{}' WHERE id = '{}'", expire_time, id); 1268 | } 1269 | 1270 | ++itr; 1271 | } 1272 | 1273 | break; 1274 | } 1275 | case AHBotCommand::minitems: 1276 | { 1277 | char * param1 = strtok(args, " "); 1278 | uint32 minItems = (uint32) strtoul(param1, NULL, 0); 1279 | 1280 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minitems = '{}' WHERE auctionhouse = '{}'", minItems, ahMapID); 1281 | 1282 | config->SetMinItems(minItems); 1283 | 1284 | break; 1285 | } 1286 | case AHBotCommand::maxitems: 1287 | { 1288 | char * param1 = strtok(args, " "); 1289 | uint32 maxItems = (uint32) strtoul(param1, NULL, 0); 1290 | 1291 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxitems = '{}' WHERE auctionhouse = '{}'", maxItems, ahMapID); 1292 | 1293 | config->SetMaxItems(maxItems); 1294 | config->CalculatePercents(); 1295 | break; 1296 | } 1297 | case AHBotCommand::percentages: 1298 | { 1299 | char * param1 = strtok(args, " "); 1300 | char * param2 = strtok(NULL, " "); 1301 | char * param3 = strtok(NULL, " "); 1302 | char * param4 = strtok(NULL, " "); 1303 | char * param5 = strtok(NULL, " "); 1304 | char * param6 = strtok(NULL, " "); 1305 | char * param7 = strtok(NULL, " "); 1306 | char * param8 = strtok(NULL, " "); 1307 | char * param9 = strtok(NULL, " "); 1308 | char * param10 = strtok(NULL, " "); 1309 | char * param11 = strtok(NULL, " "); 1310 | char * param12 = strtok(NULL, " "); 1311 | char * param13 = strtok(NULL, " "); 1312 | char * param14 = strtok(NULL, " "); 1313 | 1314 | uint32 greytg = (uint32) strtoul(param1, NULL, 0); 1315 | uint32 whitetg = (uint32) strtoul(param2, NULL, 0); 1316 | uint32 greentg = (uint32) strtoul(param3, NULL, 0); 1317 | uint32 bluetg = (uint32) strtoul(param4, NULL, 0); 1318 | uint32 purpletg = (uint32) strtoul(param5, NULL, 0); 1319 | uint32 orangetg = (uint32) strtoul(param6, NULL, 0); 1320 | uint32 yellowtg = (uint32) strtoul(param7, NULL, 0); 1321 | uint32 greyi = (uint32) strtoul(param8, NULL, 0); 1322 | uint32 whitei = (uint32) strtoul(param9, NULL, 0); 1323 | uint32 greeni = (uint32) strtoul(param10, NULL, 0); 1324 | uint32 bluei = (uint32) strtoul(param11, NULL, 0); 1325 | uint32 purplei = (uint32) strtoul(param12, NULL, 0); 1326 | uint32 orangei = (uint32) strtoul(param13, NULL, 0); 1327 | uint32 yellowi = (uint32) strtoul(param14, NULL, 0); 1328 | 1329 | // 1330 | // Setup the percentage in the configuration first, so validity test can be performed 1331 | // 1332 | 1333 | config->SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); 1334 | 1335 | // 1336 | // Save the results into the database (after the tests) 1337 | // 1338 | 1339 | auto trans = WorldDatabase.BeginTransaction(); 1340 | 1341 | trans->Append("UPDATE mod_auctionhousebot SET percentgreytradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREY_TG) , ahMapID); 1342 | trans->Append("UPDATE mod_auctionhousebot SET percentwhitetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_WHITE_TG) , ahMapID); 1343 | trans->Append("UPDATE mod_auctionhousebot SET percentgreentradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREEN_TG) , ahMapID); 1344 | trans->Append("UPDATE mod_auctionhousebot SET percentbluetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_BLUE_TG) , ahMapID); 1345 | trans->Append("UPDATE mod_auctionhousebot SET percentpurpletradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_PURPLE_TG), ahMapID); 1346 | trans->Append("UPDATE mod_auctionhousebot SET percentorangetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_ORANGE_TG), ahMapID); 1347 | trans->Append("UPDATE mod_auctionhousebot SET percentyellowtradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_YELLOW_TG), ahMapID); 1348 | trans->Append("UPDATE mod_auctionhousebot SET percentgreyitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREY_I) , ahMapID); 1349 | trans->Append("UPDATE mod_auctionhousebot SET percentwhiteitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_WHITE_I) , ahMapID); 1350 | trans->Append("UPDATE mod_auctionhousebot SET percentgreenitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREEN_I) , ahMapID); 1351 | trans->Append("UPDATE mod_auctionhousebot SET percentblueitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_BLUE_I) , ahMapID); 1352 | trans->Append("UPDATE mod_auctionhousebot SET percentpurpleitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_PURPLE_I) , ahMapID); 1353 | trans->Append("UPDATE mod_auctionhousebot SET percentorangeitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_ORANGE_I) , ahMapID); 1354 | trans->Append("UPDATE mod_auctionhousebot SET percentyellowitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_YELLOW_I) , ahMapID); 1355 | 1356 | WorldDatabase.CommitTransaction(trans); 1357 | 1358 | break; 1359 | } 1360 | case AHBotCommand::minprice: 1361 | { 1362 | char * param1 = strtok(args, " "); 1363 | uint32 minPrice = (uint32) strtoul(param1, NULL, 0); 1364 | 1365 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minprice{} = '{}' WHERE auctionhouse = '{}'", color, minPrice, ahMapID); 1366 | 1367 | config->SetMinPrice(col, minPrice); 1368 | 1369 | break; 1370 | } 1371 | case AHBotCommand::maxprice: 1372 | { 1373 | char * param1 = strtok(args, " "); 1374 | uint32 maxPrice = (uint32) strtoul(param1, NULL, 0); 1375 | 1376 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxprice{} = '{}' WHERE auctionhouse = '{}'", color, maxPrice, ahMapID); 1377 | 1378 | config->SetMaxPrice(col, maxPrice); 1379 | 1380 | break; 1381 | } 1382 | case AHBotCommand::minbidprice: 1383 | { 1384 | char * param1 = strtok(args, " "); 1385 | uint32 minBidPrice = (uint32) strtoul(param1, NULL, 0); 1386 | 1387 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minbidprice{} = '{}' WHERE auctionhouse = '{}'", color, minBidPrice, ahMapID); 1388 | 1389 | config->SetMinBidPrice(col, minBidPrice); 1390 | 1391 | break; 1392 | } 1393 | case AHBotCommand::maxbidprice: 1394 | { 1395 | char * param1 = strtok(args, " "); 1396 | uint32 maxBidPrice = (uint32) strtoul(param1, NULL, 0); 1397 | 1398 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxbidprice{} = '{}' WHERE auctionhouse = '{}'", color, maxBidPrice, ahMapID); 1399 | 1400 | config->SetMaxBidPrice(col, maxBidPrice); 1401 | 1402 | break; 1403 | } 1404 | case AHBotCommand::maxstack: 1405 | { 1406 | char * param1 = strtok(args, " "); 1407 | uint32 maxStack = (uint32) strtoul(param1, NULL, 0); 1408 | 1409 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxstack{} = '{}' WHERE auctionhouse = '{}'", color, maxStack, ahMapID); 1410 | 1411 | config->SetMaxStack(col, maxStack); 1412 | 1413 | break; 1414 | } 1415 | case AHBotCommand::buyerprice: 1416 | { 1417 | char * param1 = strtok(args, " "); 1418 | uint32 buyerPrice = (uint32) strtoul(param1, NULL, 0); 1419 | 1420 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerprice{} = '{}' WHERE auctionhouse = '{}'", color, buyerPrice, ahMapID); 1421 | 1422 | config->SetBuyerPrice(col, buyerPrice); 1423 | 1424 | break; 1425 | } 1426 | case AHBotCommand::bidinterval: 1427 | { 1428 | char * param1 = strtok(args, " "); 1429 | uint32 bidInterval = (uint32) strtoul(param1, NULL, 0); 1430 | 1431 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerbiddinginterval = '{}' WHERE auctionhouse = '{}'", bidInterval, ahMapID); 1432 | 1433 | config->SetBiddingInterval(bidInterval); 1434 | 1435 | break; 1436 | } 1437 | case AHBotCommand::bidsperinterval: 1438 | { 1439 | char * param1 = strtok(args, " "); 1440 | uint32 bidsPerInterval = (uint32) strtoul(param1, NULL, 0); 1441 | 1442 | WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerbidsperinterval = '{}' WHERE auctionhouse = '{}'", bidsPerInterval, ahMapID); 1443 | 1444 | config->SetBidsPerInterval(bidsPerInterval); 1445 | 1446 | break; 1447 | } 1448 | default: 1449 | break; 1450 | } 1451 | } 1452 | 1453 | // ============================================================================= 1454 | // Initialization of the bot 1455 | // ============================================================================= 1456 | 1457 | void AuctionHouseBot::Initialize(AHBConfig* allianceConfig, AHBConfig* hordeConfig, AHBConfig* neutralConfig) 1458 | { 1459 | // 1460 | // Save the pointer for the configurations 1461 | // 1462 | 1463 | _allianceConfig = allianceConfig; 1464 | _hordeConfig = hordeConfig; 1465 | _neutralConfig = neutralConfig; 1466 | 1467 | // 1468 | // Done 1469 | // 1470 | 1471 | LOG_INFO("module", "AHBot [{}]: initialization complete", uint32(_id)); 1472 | } 1473 | --------------------------------------------------------------------------------