buffbitch.mac - v1.2 buff bot supporting aliasing and more

A forum for you to dump all the macros you create, allowing users to use, modify, and comment on your work.

Moderator: MacroQuest Developers

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

buffbitch.mac - v1.2 buff bot supporting aliasing and more

Post by Gumby » Wed Jan 28, 2004 6:20 pm

v1.2 updated.

Documentation on features and use is complete in the code and the INI file, but here's a quick update for what's new in 1.2:

| - Any or all authentication types may now be used at once in a heirarchical fashion (Password/User/Guild)
| - No more "local/remote" customization; bot will determine which is the case and execute upon it.
| - MGB support added, authenticated against a user list.
| - AA ability buff capability added.
| - CAMP desk feature now authenticates against a user list.
| - Horse checks added
| - Stronger error checking on building the configuration, especially buff and authentication lists.
| - Generalized functions for parsing and indexfind are now used, split into seperate include files
| as they were released for public consumption.
| - Changed undetermined length loop parameters, bot loads much quicker now.

There are now three external dependencies in addition to the buffbitch.ini file which is found in the post beneath this one.

1) spellcast.inc http://macroquest2.com/phpBB2/viewtopic.php?t=5090

2) indexfind.inc http://macroquest2.com/phpBB2/viewtopic.php?t=5138

3) initoarray.inc http://macroquest2.com/phpBB2/viewtopic.php?t=5141

Comments / Questions / Flames always appreciated. Post on the topic here, or PM them to me.

G

EDIT: Some of the $spell(xxx,range) parses under current revisions of MQ are reporting -1 instead of 0, updated code to reflect this.

Code: Select all

| -- BuffBitch.mac
| 
| Program by Gumby, except where noted.
| Date: 2/02/2004
| Version: 1.2
| 
| Overview:
| BuffBitch is a tell buff bot.  It supports multiple features such as:
|   * Full configuration via INI file.
|   * Buff Aliasing for ease of requests, configurable by the end user
|   * Multiple methods of user authentication: Password, individual Username, and Guildtag
|   * Support for AA buffs
|   * Support for MGB usage
|   * Supports Buff Queuing; multiple buffs may be requested by a single tell, or requests
|     by multiple users may be handled at the same time.
|   * Supports buffs being cast on both requestor or on another player character.
|   * Rudimentary chat back options, expansion of this feature is slated for next release (1.3).
|   * Uses any spell set; if a requested spell is not available, it will mem the spell, cast it
|     and restore the original spell.  No more folks yelling about having to remem spells when
|     they log back onto their toon; or worse, casting the incorrect spell in a critical situation.
|
| Acknowledgements:
|   Plazmic and the other writers/updaters denoted in spellcast.inc, utilized by this script.
|   Brat - whom I pillaged much of the buff queuing code from.
|   
| General Notes: BuffBitch is designed to be a flexible buff bot in allowing configured individuals
|                and guilds to request buffs.  I have attempted to make the requests as generic and as 
|                human-like as possible such that it's not strictly necessary (with the 
|                exception of Password authorized users) to inform the requesting party that the
|                buffing toon is a bot.  Tells are parsed for the requisite information that the bot
|                needs to service buff requests, and even utterly random yoda-speak if it has the 
|                aliases, meets the requirements of giving a target if the requester is not the individual
|                to be cast upon, and the authentication requirements are met.  Any request that does 
|                not meet the authorization criteria is simply dropped; authorized users will receive
|                updates on various errors.  The code was written at the request of individuals in an
|                end-game raid guild; many of the features included have been designed to support this.
|
| External dependencies: You must have the following include files: spellcast.inc, indexfind.inc, and 
|                        initoarray.inc.  All three are found in the Macro Snippets forum, and direct
|                        URL's to the threads will be posted in message containing this code.  Not 
|                        having these files will result in this error:
|
|                        Error: Couldn't open include file
| 
| Usage: /macro buffbitch BotClass where BotClass is one of: cleric, druid, etc. (See INI file)
|    NOTE: BotClass is case-insenstive
|
|      * ex: /macro buffbitch Druid 
|            Will load the Druid spells and aliases into the arrays.
|
| Ending: Simply /end, or optionally use the CAMP desk feature enabled through the INI file.  The CAMP 
|         functionality is handled through a user authorization list.
|
| In Game commands: /tell <botname> <password> <aliases> and "<to/on/give> <target>" if applicable
|    NOTE: Beyond the /tell <botname> the other parameters may come anywhere in the request
|          To specify a target besides the requester, the use of 'to' 'on' or 'give' must preceed 
|          the target name.  Also, to use Guild authentication, the requester must be in the
|          same zone as the bot.
|
|      USER and GUILD authenticated requests:
|      * ex: /tell Bitchname Please buff my group with b9
|            Will cast Blessing of the Nine on the requester (group in this case, but bot doesn't identify that)
|      * ex: /tell Bitchname Could you give me p9 ds and seasons when mana please?
|            Will cast Protection of the Nine, legacy of bracken, prot of seasons on requester
|            Me is interpreted to be the requesting toon by the bot for the target.
|      * ex: /tell Bitchname cast p9 and seasons on CheekyMonkey
|            Will cast 9 and prot of seasons on CheekyMonkey
|            Either 'to' or 'give' could've replaced 'on' in this example with the same result.
|
|      PASSWORD authenticated requests: (gibb0r is the password in each eample)
|      * ex: /tell Bitchname hey, gibb0r voq and vallons
|            Will cast Voice of Quellious and Vallon's Quickening on the requester
|      * ex: /tell Bitchname hey, gibb0r god voq to CheekyMonkey
|            Will cast Guard of Druzzil and Voice of Quellious on CheekyMonkey
|      * ex: /tell Bitchname howdy, gibb0r voq and sex to me
|            Will cast Voice of QUellious on the requesting user.
|
| Any unathorized request (by any of the authentication models), the bot will drop the request.
| Case of aliases won't matter as long as you leave the aliases in lowercase in the INI file.  Extraneous
| words such as 'sex' in the last example, will be ignored by the bot as it only looks for instances
| of Password (if needed), buff aliases, and to/on/give Target.
|
| Guild tags and User names are authenticated by the bot (again, one must be in the same zone as the bot if 
| you are requesting an authentication based upon Guild tag).  The lists are configured in the INI 
| file, and INI customization notes are documented in the INI file itself.  This script was written
| at the request of some endgame characters and the defacto buff lists reflect that.  Want the bot 
| to buff your friends and guildmates twinks, simply list the spells and the aliases you 
| want and party on.  If you want to go through the grunt work of listing out more spells for each 
| class in the INI file, and then send them to me in a PM on the forums, please feel free to :).
|
| Limited debug functionality may be enabled by changing the /varset DebugFlag to 1.  This is useful 
| for diagnosing issues which come up either in array parses, or INI configuration issues.  There's an 
| option to enable this in the indexfind and initoarray include files as well; however, when testing the 
| full script, I suggest you leave those turned off as they're called repeated times and you'll 
| have to wade through an excessive amount of spam.  Much is duplicated in the debug spewed by BuffBitch.
|
| Code History
|
| version 1.2 2/02/2004 Feature Update
|    - Any or all authentication types may now be used at once in a heirarchical fashion (Password/User/Guild)
|    - No more "local/remote" customization; bot will determine which is the case and execute upon it.
|    - MGB support added, authenticated against a user list.
|    - AA ability buff capability added.
|    - CAMP desk feature now authenticates against a user list.
|    - Horse checks added
|    - Stronger error checking on building the configuration, especially buff and authentication lists.
|    - Generalized functions for parsing and indexfind are now used, split into seperate include files
|      as they were released for public consumption.
|    - Changed undetermined length loop parameters, bot loads much quicker now.
|
| version 1.1 1/28/2004 Feature Update
|    - Added support for multiple authentication types. -- Changed in 1.2
|    - Configurable Local or Remote operation. -- Deprecated 1.2
|    - Added ChatText parsing.  Password, buff aliases, on/to Target can now be placed anywhere 
|      in the /tell request sent to the bot.  Extra overhead but this cuts down on number of requests,
|      and also at first glance, makes the toon seem less botlike.  As with standard MQ etiquette, 
|      the fewer people who know it's botted the better.
|
| version 1.0 1/26/2004 Initial Features
|    - Password authentication rather than single master or defined user lists -- Changed in 1.1 
|    - Requests given through /tell
|    - Queues Buff requests.
|    - Supports Buff Aliases through an INI file, customized to anything the enduser wants.
|    - Uses a single spell gem, and returns the gem to the original spell after casting.
|    - Basic chat-back to the requesting user on errors (assuming valid authentication).
|    - Bot simply ignores those who issue invalid requests.
|    - Camp out feature. -- updated 1.2
|
|  Caveats:
|    - Uses spellcast.inc, there's a /sendkey up up, /sendkey down up on the call.  Useful for combat,
|      not applicable in this routine.  If you wish to execute this script in the background with
|      the default spellcast.inc, since /sendkey requires window focus, you will need to run EQW.  
|      If you do not want to run EQW, simply comment out the two /sendkey's in spellcast.inc, 
|      save as a different filename, and change the below #include line to whatever the new filename is 
|      rather than spellcast.inc.  Do this so you don't break other scripts you may be using which
|      rely on this functionality.
|
|  As always, if you run into issues with this macro, or would like to request added functionality,
|  please feel free to comment to me either on the forum in the Macro Depot in the code's posting,
|  or via a PM on the forums.

#include spellcast.inc
#include indexfind.inc
#include initoarray.inc

#chat tell

#turbo

Sub Main

| *************** Global Declares *********** |

   /declare BotClass      global
   /declare IniFile       global
   /declare DebugFlag     global

   /declare BuffList      array
   /declare BuffAlias     array
   /declare BuffQueue     array
   /declare BuffTargetID  array
   /declare BuffRequester array
   /declare BuffReqNum    global
   /declare BuffMGB       array

   /declare Password      global
   /declare BuffAuthList  array
   /declare MaxAuthIndex  global
   /declare MaxAliasIndex global
   /declare TempOptions   array
   /declare SpellDB	  array
   /declare MGBSupport    global
   /declare MGBAuthList   array
   /declare CAMPSupport   global
   /declare CAMPAuthList  array
   /declare CAMPString    global

| *************** Debug Bock **************** |
| This parameter enables debugging in the global script, 0 disabled, 1 enabled.
| IndexFind and INI Parsing debug flags have been moved to the included files

   /varset  DebugFlag 0
  
| *************** Chat Back Block *********** |
| I recommend you configure these by changing the varsets
| Consolidates room here, v 1.3 slated to INI base these with multiple responses
| in a pseudo humanization routine

   /declare OORMessage global
   /declare OOMMessage global
   /declare CANTSEEMessage global
   /declare NOTINZONEMessage global

   /varset  OORMessage "The target is OOR, please request again later"
   /varset  OOMMessage "I am OOM, I will cast when I have mana available"
   /varset  CANTSEEMessage "I can't see the target, please request again later"
   /varset  NOTINZONEMessage "Target isn't in the zone for me to buff"     

| *************** Main Code start *********** |

   /varset IniFile buffbitch.ini
   /varset BuffReqNum 0
   /varset Password ""
   
   /if $defined(Param0)==TRUE {
      /varset BotClass $lcase(@Param0)
   } else {
      /echo BotClass undefined, exiting
      /end
   }

   /echo Loading BuffBitch v 1.2 by Gumby
   /echo I will be serving the @BotClass spells

   /call BuildBuffList
   /varset MaxAliasIndex $return

   /call BuildOptions

   /echo BuffBitch loaded

   /if ("$char(mounted)"=="FALSE" && "$char(state)"!="SIT") /sit

   :Wait
      /doevents
      /delay 10
      /if n @BuffReqNum>0 /call DoBuffs
      /delay 100
      /goto :Wait
/return


| *************** Subroutines *************** |

| ******* ParseString *******
| Parses through a space delimited text message(SearchText) for a specific 
| word (SearchWord), and returns the position ($arg value) of the word. If the word is 
| not found, it returns -1.

Sub ParseString(SearchWord,SearchText)
   /declare ParseCounter local

   /if n @DebugFlag==1 {
      /echo Searching for @SearchWord
      /echo In @SearchText
   }
   /varset ParseCounter 1
   :StartParseString
      /if "$arg(@ParseCounter,"@SearchText")"=="@SearchWord" /goto :EndParseString
      /if "$arg(@ParseCounter,"@SearchText")"=="" { 
         /return -1
      }
      /varadd ParseCounter 1
      /goto :StartParseString
   :EndParseString
/return @ParseCounter

      
| ******* DoBuffs *******
| Handles the spell setup and makes call to spellcast.inc 

Sub DoBuffs
   /declare StatusUpdateCounter local
   /declare OriginalSpell       local
   /declare Ability             local

   /varset OriginalSpell "$char(gem,8)"
   /if n @DebugFlag==1 {
      /echo BuffReqNum is @BuffReqNum
      /echo OriginalSpell is @OriginalSpell
   }
   :DoBuffLoop
      /if n @BuffReqNum==0 {
         /if ("$char(mounted)"=="FALSE" && "$char(state)"!="SIT") /sit
         /delay 2
         /if "$char(gem,8)"!="@OriginalSpell" {
            /mem 8 "@OriginalSpell"
            /delay 40
         }
         /return
      }
      /varsub BuffReqNum 1
      /echo @BuffQueue(@BuffReqNum)

| Ran across a spell during testing which didn't have range info, next check is a result of it
      /if n $spell("@BuffQueue(@BuffReqNum)",range)<=0 {
         /goto :BrokenRangeInfo
      }
      /if n $spell("@BuffQueue(@BuffReqNum)",range)<$spawn(@BuffTargetID(@BuffReqNum),distance) {
         /if n @BuffMGB(@BuffReqNum)==0 {
            /tell @BuffRequester(@BuffReqNum) @OORMessage
            /goto :BuffEnd
         }
      }
      :BrokenRangeInfo          
      /target id @BuffTargetID(@BuffReqNum)
      /if n $char(gem,"@BuffQueue(@BuffReqNum)")==0 {
         /mem 8 "@BuffQueue(@BuffReqNum)"
         /delay 40
      }
      /if ("$char(mounted)"=="FALSE" && "$char(state)"!="STAND") /stand
      /if n @DebugFlag==1 {
         /echo calling Cast "@BuffQueue(@BuffReqNum)"
      }
      /if n @BuffMGB(@BuffReqNum)==1 {
         /echo This spell, @BuffQueue(@BuffReqNum) will be MGBed
         /alt activate 35
      }
      /if "$left(2,"@BuffQueue(@BuffReqNum)")"=="AA" {
         /varset Ability $right($calc($strlen("@BuffQueue(@BuffReqNum)")-2),"@BuffQueue(@BuffReqNum)") 
         /alt activate @Ability
         /goto :BuffEnd  
      }   
      /call Cast "@BuffQueue(@BuffReqNum)"
      /if "$return"=="CAST_OUTOFMANA" {
         /if ("$char(mounted)"=="FALSE" && "$char(state)"!="SIT") /sit
         /for StatusUpdateCounter 0 to @BuffReqNum
            /tell @BuffRequester(@StatusUpdateCounter) @OOMMessage
         /next StatusUpdateCounter
         /delay 600
         /goto :DoBuffLoop
      }
      /if "$return"=="CAST_OUTOFRANGE" {
         /tell @BuffRequester(@BuffReqNum) @OORMessage
      }
      /if "$return"=="CAST_CANNOTSEE" {
         /tell @BuffRequester(@BuffReqNum) @CANTSEEMessage
      }
      :BuffEnd
      /varset BuffTargetID(@BuffReqNum) 0
   /goto :DoBuffLoop
/return  

| ******* BuildBuffList *******
| Builds the arrays for the Buffs and Aliases from the [BotClass] heading information in INI file

Sub BuildBuffList

   /declare SpellDBIndex   local
   /declare BuffBuildIndex local
   /declare BuildCounter   local
   /declare DebugCounter   local

   /varset SpellDBIndex    0
   /varset BuffBuildIndex  0

| Read Spells in from [BotClass]

   /call INIToArray SpellDB "@IniFile" "@BotClass"
   /if n $return<0 {
      /echo SpellDB build: INI File configuration or call incorrect
      /if n @DebugFlag==1 {
         /echo INIToArray was called with the following parameters:
         /echo ArrayName:     SpellDB
         /echo INIFileName:   @IniFile
         /echo INIHeaderName: @BotClass
         /echo INIKeyName:    <not used>
         /if n $return==-1 /echo No spells were listed for the configured class
         /if n $return==-2 /echo ArrayName not passed
         /if n $return==-3 /echo INIFileName not passed
         /if n $return==-4 /echo Invalid Array passed
         /if n $return==-5 /echo The INI File/Header/Key combination is invalid
      }
       /echo Ending...
       /end
   }

| Get Spell Aliases for spells, and assign them to Spell Names in the arrays

   :StartBuildBuff
      /if "@SpellDB(@SpellDBIndex)"=="UNDEFINED-ARRAY-ELEMENT" /goto :EndBuildBuff
      /call INIToArray BuffAlias "@IniFile" "@BotClass" "@SpellDB(@SpellDBIndex)"
      /if n $return<0 {
         /echo BuffAlias build: INI File configuration or call incorrect
         /if n @DebugFlag==1 {
            /echo INIToArray was called with the following parameters:
            /echo ArrayName:     BuffAlias
            /echo INIFileName:   @IniFile
            /echo INIHeaderName: @BotClass
            /echo INIKeyName:    @SpellDB(@SpellDBIndex)
            /if n $return==-1 /echo No Aliases were found for the listed spell
            /if n $return==-2 /echo ArrayName not passed
            /if n $return==-3 /echo INIFileName not passed
            /if n $return==-4 /echo Invalid Array passed
            /if n $return==-5 /echo The INI File/Header/Key combination is invalid
         }
         /echo Ending...
         /end
      }
      :StartBuffList
         /if "@BuffAlias(@BuffBuildIndex)"=="UNDEFINED-ARRAY-ELEMENT" /goto :EndBuffList
         /varset BuffList(@BuffBuildIndex) "@SpellDB(@SpellDBIndex)"
         /varadd BuffBuildIndex 1
         /goto :StartBuffList
      :EndBuffList
      /varadd SpellDBIndex 1
      /goto :StartBuildBuff
   :EndBuildBuff
   /varsub BuffBuildIndex 1

| Debug dump and information

   /if n @DebugFlag==1 {
      /echo BuffList and BuffAlias built
      /echo Number of total aliases is $calc(@BuffBuildIndex+1)
      /echo ******* Full Dump of Buff Arrays *******
      /for DebugCounter 0 to @BuffBuildIndex
         /echo spell @BuffList(@DebugCounter) alias @BuffAlias(@DebugCounter)
      /next DebugCounter
   }   
/return @BuffBuildIndex

| ******* BuildOptions *******
| Builds [Options] from the INI file, bot configuration done in this subroutine.  

Sub BuildOptions

   /declare OptionsIndex local
   /declare DebugCounter local
   /varset OptionsIndex  0

| Request Authorization Types

   /call INIToArray TempOptions "@IniFile" "Options" "AuthType"
   /if n $return<0 {
      /echo BuffAlias build: INI File configuration or call incorrect
      /if n @DebugFlag==1 {
         /echo INIToArray was called with the following parameters:
         /echo ArrayName:     TempOptions
         /echo INIFileName:   @IniFile
         /echo INIHeaderName: Options
         /echo INIKeyName:    AuthType
         /if n $return==-1 /echo No Authentication Types are configured
         /if n $return==-2 /echo ArrayName not passed
         /if n $return==-3 /echo INIFileName not passed
         /if n $return==-4 /echo Invalid Array passed
         /if n $return==-5 /echo The INI File/Header/Key combination is invalid
      }
      /echo Ending...
      /end
   }

| Get Password and Build Authentication Array

   :StartBuildAuth
      /if "@TempOptions(@OptionsIndex)"=="UNDEFINED-ARRAY-ELEMENT" /goto :EndBuildAuth
         /if "@TempOptions(@OptionsIndex)"=="Password" {
            /varset Password $ini("@IniFile","Options","@TempOptions(@OptionsIndex)")
            /if "@Password"=="" {
               /echo You must supply a password to use Password Authentication, exiting
               /end
            }
         } else {
            /call INIToArray BuffAuthList "@IniFile" "Options" "@TempOptions(@OptionsIndex)"
            /if n $return<0 {
               /echo BuffAuthList build: INI File configuration or call incorrect
               /if n @DebugFlag==1 {
                  /echo INIToArray was called with the following parameters:
                  /echo ArrayName:     BuffAuthList
                  /echo INIFileName:   @IniFile
                  /echo INIHeaderName: Options
                  /echo INIKeyName:    @TempOptions(@OptionsIndex)
                  /if n $return==-1 /echo User/Guild support enabled, but not configured
                  /if n $return==-2 /echo ArrayName not passed
                  /if n $return==-3 /echo INIFileName not passed
                  /if n $return==-4 /echo Invalid Array passed
                  /if n $return==-5 /echo The INI File/Header/Key combination is invalid
               }
               /echo Ending...
               /end
            }
         }
      /varadd OptionsIndex 1
      /goto :StartBuildAuth
   :EndBuildAuth
   /varset MaxAuthIndex $return

| Determine and build MGB functionality support

   /varset MGBSupport $ini("@IniFile","Options","MGBSupport")
   /if n @MGBSupport==1 {
      /call INIToArray MGBAuthList "@IniFile" "Options" "MGBAuthList"
      /if n $return<0 {
         /echo MGBAuthList build: INI File configuration or call incorrect
         /if n @DebugFlag==1 {
            /echo INIToArray was called with the following parameters:
            /echo ArrayName:     MGBAuthList
            /echo INIFileName:   @IniFile
            /echo INIHeaderName: Options
            /echo INIKeyName:    MGBAuthList
            /if n $return==-1 /echo MGB Support enabled but no users defined
            /if n $return==-2 /echo ArrayName not passed
            /if n $return==-3 /echo INIFileName not passed
            /if n $return==-4 /echo Invalid Array passed
            /if n $return==-5 /echo The INI File/Header/Key combination is invalid
         }
         /echo Ending...
         /end
      }
   }

| Determine and build Camp Desk functionality support

   /varset CAMPSupport $ini("@IniFile","Options","CAMPSupport")
   /if n @CAMPSupport==1 {
      /varset CAMPString $ini("@IniFile","Options","CAMPString")
      /if "@CAMPString"=="" {
         /echo CAMP Support configured, but no CAMPString supplied.  Ending...
         /end
      }      
      /call INIToArray CAMPAuthList "@IniFile" "Options" "CAMPAuthList"
      /if n $return<0 {
         /echo CAMPAuthList build: INI File configuration or call incorrect
         /if n @DebugFlag==1 {
            /echo INIToArray was called with the following parameters:
            /echo ArrayName:     CAMPAuthList
            /echo INIFileName:   @IniFile
            /echo INIHeaderName: Options
            /echo INIKeyName:    CampAuthList
            /if n $return==-1 /echo CAMP Support configured but no users defined
            /if n $return==-2 /echo ArrayName not passed
            /if n $return==-3 /echo INIFileName not passed
            /if n $return==-4 /echo Invalid Array passed
            /if n $return==-5 /echo The INI File/Header/Key combination is invalid
         }
         /echo Ending...
         /end
      }
   }

| Debug data dumps and information

   /if n @DebugFlag==1 {
      /echo BuffAuthList built
      /echo Number of total authorized names (guild or users) is @MaxAuthIndex
      /echo ******* Full Dump of Buff Auth Array *******
      /for DebugCounter 0 to @MaxAuthIndex
         /echo AuthName @BuffAuthList(@DebugCounter)
      /next DebugCounter

      /if n @MGBSupport==0 {
         /echo MGB Support not enabled
      } else {
         /echo MGB Support enabled
         /echo ******* Full Dump of MGB Auth Array *******
         /varset DebugCounter 0
         :StartMGBDump
            /if "@MGBAuthList(@DebugCounter)"=="UNDEFINED-ARRAY-ELEMENT" {
               /goto :EndMGBDump
            }
            /echo MGB Authorized User: @MGBAuthList(@DebugCounter)
            /varadd DebugCounter 1
            /goto :StartMGBDump
         :EndMGBDump
      }

      /if n @CAMPSupport==0 {
         /echo CAMP Support not enabled
      } else {
         /echo CAMP Support enabled, with @CAMPString to call
         /echo ******* Full Dump of CAMP Auth Array *******
         /varset DebugCounter 0
         :StartCAMPDump
            /if "@CAMPAuthList(@DebugCounter)"=="UNDEFINED-ARRAY-ELEMENT" {
               /goto :EndCAMPDump
            }
            /echo CAMP Authorized User: @CAMPAuthList(@DebugCounter)
            /varadd DebugCounter 1
            /goto :StartCAMPDump
         :EndCAMPDump
      } 
   }
/return

| ******* Chat Event *******
| Standard chat driven event format called by /doevents.  
| The code validates the request, determines the target and tosses the BuffRequest onto the queue if 
| valid.  This interface also handles the CAMP functionality which allows designated users to
| force the bot to log off if someone else needs to get on the toon.
      
Sub Event_Chat(ChatType,Sender,ChatText)
   /declare Target            local
   /declare RequestIndex      local
   /declare DebugIndex        local
   /declare DebugCounter      local
   /declare GuildTag          local
   /declare ParseAliasCounter local
   /declare MGBUse            local

| CAMP Support code

   /if (n @CAMPSupport==1 && "@ChatText"=="@CAMPString") {
      /echo CAMP Request valid, camping...
      /if "$char(mounted)"=="TRUE" {
         /dism
         /delay 10
      }
      /if "$char(state)"!="SIT" /sit
      /delay 10
      /camp desktop
      /delay 200
      /end
   } 
  
| Authentication Check:
| New integrated check, heirarchical order: Password, User, Guild if any are enabled

   /if "@Password"!="" {
      /if "@ChatText"~~"@Password" {
      /if n @DebugFlag==1 /echo Sender validated by Password
         /goto :EndAuthentication
      }
   }
   /call IndexFind BuffAuthList @Sender
   /if $return>=0 {
      /if n @DebugFlag==1 /echo Sender validated by User
      /goto :EndAuthentication
   }
   /varset GuildTag "$spawn($searchspawn(pc,@Sender),guild)"
   /call IndexFind BuffAuthList "@GuildTag"
   /if $return>=0 {
      /if n @DebugFlag==1 /echo Sender validated by Guild
      /goto :EndAuthentication
   }

| Failed authentication return, request dropped
   /echo Request for buff was not authenticated, not adding to queue
   /return

| Authentication valid, now determine target
   :EndAuthentication

   /if "@ChatText"~~"to" {
      /call ParseString "to" "@ChatText"
      /if n $return>0 {
         /varset Target $arg($calc($return+1),"@ChatText")
         /if "@Target"=="me" {
            /varset Target @Sender
         }
         /if n $searchspawn(pc,@Target)!=0 {
            /goto :EndTarget
         } else {
            /tell @Sender @NOTINZONEMessage
         }
      }
   }
   /if "@ChatText"~~"on" {
      /call ParseString "on" "@ChatText"
      /if n $return>0 {
         /varset Target $arg($calc($return+1),"@ChatText")
         /if "@Target"=="me" {
            /varset Target @Sender
         }
         /if n $searchspawn(pc,@Target)!=0 {
            /goto :EndTarget
         } else {
            /tell @Sender @NOTINZONEMessage
            /return
         }
      }
   }
   /if "@ChatText"~~"give" {
      /call ParseString "give" "@ChatText"
      /if n $return>0 {
         /varset Target $arg($calc($return+1),"@ChatText")
         /if "@Target"=="me" {
            /varset Target @Sender
         }
         /if n $searchspawn(pc,@Target)!=0 {
            /goto :EndTarget
         } else {
            /tell @Sender @NOTINZONEMessage
            /return
         }
      }
   }
   /varset Target @Sender
   /if n $searchspawn(pc,@Target)!=0 {
      /goto :EndTarget
   } else {
      /tell @Sender @NOTINZONEMessage
      /return
   }
   :EndTarget
   /if n @DebugFlag==1 /echo Target is @Target

| Target verified, quick check for MGB

   /varset MGBUse 0
   /if ("@ChatText"~~"mgb" || "@ChatText"~~"MGB") {
      /call IndexFind MGBAuthList @Sender
      /if $return=>0 {
         /varset MGBUse 1
      } else {
         /return
      }
   }

| Parse request for Aliases

   /for ParseAliasCounter 0 to @MaxAliasIndex
      /if "@ChatText"~~"@BuffAlias(@ParseAliasCounter)" {
         /varset BuffTargetID(@BuffReqNum) $searchspawn(pc,@Target)
         /varset BuffQueue(@BuffReqNum) "@BuffList(@ParseAliasCounter)" 
         /varset BuffRequester(@BuffReqNum) @Sender
         /varset BuffMGB(@BuffReqNum) @MGBUse
         /echo @BuffRequester(@BuffReqNum) successfully requested 
         /echo @BuffQueue(@BuffReqNum) to be cast on $spawn(@BuffTargetID(@BuffReqNum),name)
         /varadd BuffReqNum 1
         /if n @DebugFlag==1 {
            /varset DebugIndex $calc(@BuffReqNum-1)
            /echo who's spawn ID is @BuffTargetID(@DebugIndex) with a buff
            /echo alias of @BuffAlias(@ParseAliasCounter) found at Index @ParseAliasCounter.
            /if n @MGBUse==1 /echo This is a MGB Buff request
         }
      }
   /next ParseAliasCounter
/return
Last edited by Gumby on Sat Mar 13, 2004 10:02 am, edited 5 times in total.

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

buffbitch.ini

Post by Gumby » Wed Jan 28, 2004 6:24 pm

Customization INI file for buffbitch.mac

Code: Select all

| --- BuffBitch.ini, by Gumby
| Date: 2/02/2004
| Version: 1.2
|
| Customization file for buffbitch.mac.  Aliasing is supported through here, as 
| well as Options for configuring Authentication type, user names, guild names,
| MGB support, and also the CAMP desk feature.
|
| USAGE v1.0: 
|   - [class] denotes a character class entry.  If you want to add SK's you can...
|   - Key values are spell names: entered Spellname=.
|   - Aliases: =aliases.  |-delimited list.  List the aliases after the Spellname= that you wish.
|         ex: Protection of the Nine=p9|prot 9|prot of 9|prot9|nine
|     
|   - AA Support: Named AA## where ## is the alt activate code.  Define aliases in the same manner
|     as for spells.
|         ex: AA194=di|unfailing divinity
|
| USAGE v1.1 and v1.2: 
|   - Customize [Options]
|     1) AuthType: Password, and/or Guild, and/or User, | delimited list
|        * Password: If the password is in the tell the buff will validate the request.
|                    Exception to this is a MGB request which is checked against a seperate
|                    authorization list (this holds for User and Guild authentication too)
|        * User:     This is basically the same authentication mechanism
|                    as the previous buff bots, only the authorized names are configured 
|                    in the INI instead.
|        * Guild:    The requester has to be in the zone with the bot, and his guildtag will 
|                    be checked against the allowed guilds list.  Buff your guildmates, buff your 
|                    twink / allied guilds, whatever. 
|         ex: AuthenticationType=User                //Sets Bot up for User authetnication only
|         ex: AuthenticationType=Password|Guild      //Bot setup for both password and guild auth
|         ex: AuthenticationType=Password|User|Guild //Bot setup to use all 3 auth types
|
|     2) Guild: | delimited list (just like the alias lists) of guild names.
|         ex: Guilds=Toons of Doom|Uber Bunnies Wearing Pantyhose|etc. ad infinitum
|      
|     3) User: | delimited list just like Guild, except usernames instead of Guild names.  
|         ex: Users=Fred|Alice|Jane|ScoobyDoo
|
|        NOTE: User names and Guild names are both case-sensitive
|
|     4) Password: password used in password-based authentication; case-sensitive
|
|     5) MGBSupport: Set equal to 0 to disable, 1 to enable MGB functionality on the bot.
|                    If you enable, you must configure MGBAuthList
|
|     6) MGBAuthList: | delimited list, setup same manner as User; define user names allowed 
|                     to make an MGB buff request
|
|     7) CAMPSupport: Set equal to 0 to disable, 1 to enable the CAMP desk functionality.  This
|                     feature allows authorized users to force the bot to log off if another
|                     person needs the toon.  You must conigure both CAMPAuthList and CAMPString to use
|
|     8) CAMPAuthList: | delimited list, setup same manner as User; define user names allowed 
|                      to force the bot to log off.
|
|     9) CAMPString: Text string (case sensitive) which when sent to the bot, will force the logoff
|                    if the feature has been enabled.

[beastlord]
Ferocity=fero
Spiritual Dominion=sd
Celerity=haste
Spiritual Vigor=sv
AA128=paragon|pos|paragon of spirit

[cleric]
Hand of Virtue=hov
Aura of Reverence=aor
Kazad's Mark=kazad|symbol
Blessing of Reverence=bor
Bulwark of Vie=vie
Virtue=virt|virtue
AA38=cr|celestial regeneration|mgb heal
AA194=di|unfailing divinity

[druid]
Blessing of the Nine=b9
Legacy of Bracken=ds
Protection of the Nine=p9|prot 9|prot of 9|prot9|nine
Protection of Seasons=seasons
Blessing of Replenishment=regen
Flight of Eagles=foe
Spirit of Eagle=soe
AA185=sotw|wood|mgb heal

[enchanter]
Vallon's Quickening=vallons|haste|vq|sov
Voice of Quellious=voq|c5|crack
Guard of Druzzil=god|grm
Bulwark of Alendar=alendar

[magician]
Malestrom of Ro=ds

[necromancer]
Dead Man Floating=dmf

[paladin]
Brell's Stalwart Shield=bss|brells

[ranger]
Spirit of Eagle=soe
Spirit of the Predator=sop
Call of the Rathe=cor
Strength of Tunare=sot

[shaman]
Ferine Avatar=fa|avatar
Focus of the Seventh=focus|fo7
Talisman of Alacrity=haste
Blessing of Replenishment=regen
Talisman of the Tribunal=trib|tribunal

[Options]
AuthType=Password|User|Guild
Guild=Toons of Doom|Uber Bunnies Wearing Pantyhose
User=Fred|Alice|Jane|ScoobyDoo
Password=gibb0r
MGBSupport=0
MGBAuthList=
CAMPSupport=0
CAMPAuthList=
CAMPString=
Last edited by Gumby on Sat Feb 14, 2004 12:53 pm, edited 4 times in total.

User avatar
Elric
Cheese Whore
Cheese Whore
Posts: 466
Joined: Sun Nov 23, 2003 12:31 am
Location: Tampa, Fl
Contact:

Post by Elric » Wed Jan 28, 2004 6:31 pm

Wow.

You put a lot of work into this. And I'll say, I'm impressed. Kinda makes my buffbot look like shite. So I won't be posting it. :-D
-Elric

seph_yaro
a lesser mummy
a lesser mummy
Posts: 72
Joined: Sat Jul 26, 2003 1:12 pm

Post by seph_yaro » Thu Jan 29, 2004 6:35 am

Wow, this is great, makes me think of buff bots on Asheron's Call. What would be super would be trade support -

If someone handed the bot plat, an item, whatnot, bot would check to see if there was inven space to trade, and hit trade/cancel depending on results.

This would be interesting to see. I could see people 'moving into' a house or something in a city (town = safe spot to park a bot, generally), tell select friends, or possibly their whoel guild (which would be, um, dumb?) about the bot, and requesting regent/plat donations for use of the bot.

I only wish my skills were good enough to even look at this option.

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

Post by Gumby » Thu Jan 29, 2004 7:34 am

seph_yaro wrote:Wow, this is great, makes me think of buff bots on Asheron's Call. What would be super would be trade support -

If someone handed the bot plat, an item, whatnot, bot would check to see if there was inven space to trade, and hit trade/cancel depending on results.

This would be interesting to see. I could see people 'moving into' a house or something in a city (town = safe spot to park a bot, generally), tell select friends, or possibly their whoel guild (which would be, um, dumb?) about the bot, and requesting regent/plat donations for use of the bot.

I only wish my skills were good enough to even look at this option.
Wouldn't you want to not charge friends guildmates? :) Whitelisting would be easy though.

The basic infrastructure could be used to do something like that, especially with a few planned updates but of course some things would have to be added and you could cover 90-95% of the occurances, maybe even statistically higher as people interact with the donation beggers in PoK in a fairly regularized basis (at least I do on my caster toons looking for KEI...). That said, doing a *good* AFK bot macro which requires other player interaction is exceptionally difficult (not to mention a bad idea in the first place). If it were something to do while you were idly checking the screen occasionlly that'd be one thing; but robustly covering most conditions that can be driven by outside players... probably impossible.

Stupid things like, "man, I see you here *all* the time" coming in over a channel... normal human response "yeah *blush* doing my homework as I'm getting slammed in school but figured I'd try to earn a little plat in the downtime..." or whatever is fine and dandy. But that same player if he gets no response a few times in a row since the bot's simply dropping the request probably eventually comes to the "dude are you a bot?" conclusion.

Of course, anyone who realizes this probably has no leg to stand on but anyway.

It might be interesting at some point in this macro's life to add an authentication on a more generic event driven scheme and let users do what they want in terms of validation with a pseudo-dynamic AuthList (even if it's something like a user trade... though doing this cleanly in MQ would be challenging) but in general, humanization of a bot is *really* hard. Updating my combat routines to make it MQ less noticible is one thing... and I use it. Updating this macro to be truly interactive for something I wouldn't use.... ouch. I'd have to be exceptionally bored to even attempt it, and it'd be a long project. Though if someone wants to give it a shot, I'd be happy to discuss how I'd try integrating it.

G

daerck
a ghoul
a ghoul
Posts: 134
Joined: Mon Jan 12, 2004 8:44 pm

Post by daerck » Thu Jan 29, 2004 10:12 am

Looks awesome.

I must admit I haven't worked myself through the code yet, but I would like to know if it's possible (or how much of a hassle) it would be to include AA ability buffs such as Unfailing Divinity (Cleric DI AA) in this. They can be easily cast with /alt activate ## (194 for Unfailing Divinity I think)

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

Post by Gumby » Thu Jan 29, 2004 1:05 pm

daerck wrote:Looks awesome.

I must admit I haven't worked myself through the code yet, but I would like to know if it's possible (or how much of a hassle) it would be to include AA ability buffs such as Unfailing Divinity (Cleric DI AA) in this. They can be easily cast with /alt activate ## (194 for Unfailing Divinity I think)
Good suggestion. To be honest I didn't even think of that but I can definitely see where it'd be useful on raids and perhaps other situations that escape me at the moment.

I can parse out the request easily enough, would be trivial to do that. Debating how to handle the fact that it would not go through the spellcast.inc routines... actually I know how to get it into the buff routine fairly easily, it's just a matter of setup from the INI and putting a seperate flag on it. Probably simply define that the INI string for an AA buff must start with AA, after that I can split it out at the start of DoBuffs as an initial implementation. It'll be sort of kludgy at first as there's certainly no need for all AA's to be accounted for so I'll probably not build a full parse table, but it's an extra 10 lines of code I think. No big deal, will get something workable into 1.2 for certain.

Thanks,

G

daerck
a ghoul
a ghoul
Posts: 134
Joined: Mon Jan 12, 2004 8:44 pm

Post by daerck » Thu Jan 29, 2004 2:57 pm

Here's a list of all the /alt activate thingies:

http://thedruidsgrove.org/forums/showthread.php?t=3839

After thinking about it, the only thinks that could/should be buffed are the DI AA mentioned above and MGB, which would probably be better implemented as a keyword parse. I.e. if MGB is included, do /alt activate 35 before the buff is cast.
Ah well, maybe GoD will bring some more triggered buffs that could use this

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

Post by Gumby » Thu Jan 29, 2004 4:09 pm

daerck wrote:Here's a list of all the /alt activate thingies:

http://thedruidsgrove.org/forums/showthread.php?t=3839

After thinking about it, the only thinks that could/should be buffed are the DI AA mentioned above and MGB, which would probably be better implemented as a keyword parse. I.e. if MGB is included, do /alt activate 35 before the buff is cast.
Ah well, maybe GoD will bring some more triggered buffs that could use this
Yeah, that's the one I pulled up off of Google after reading your suggestion. MGB support was already slated for next release to enhance guild functionality, handled as a keyword to set a flag for both buffs, and now AA's too. DI / CR / SOTW / Paragon was my list of AA's that need to be included by default; if someone else wants to get more creative with it that's their perogative :).

Already hacked in the basic AA buff structure, tested with SoTW, worked fine. INI definition of AA# under the class heading, setting values to whatever the buff abbreviations are. Could be cleaner but for a quick feature addition it'll do.

Probably going to have to do a user auth list for MGB calling; more configuration headache for the end-user but from a guild perspective, only someone in a leadership role, or the bot's owners should be calling it... I'd also rather not deal with the headache of error-checking for reasonable MGB requests by enforcing a non-yoda speech (structured syntax) request to validate it among other things.

G

seph_yaro
a lesser mummy
a lesser mummy
Posts: 72
Joined: Sat Jul 26, 2003 1:12 pm

Post by seph_yaro » Thu Jan 29, 2004 8:53 pm

I was thinking more along the lines of a cleric bot... who can run out of peridots rather quickly doing temperance, aego, virtue, or the symbol lines :)


If you've played Asheron's Call (1, not 2), you'd recognize my meaning. Often the guild buff bot's have a requirement of a platinum scarab or rainbow tapers for buff's, or ask that you donate pyreals or M notes so they can buy them, as they burn them up during spell casting.


This is the same situtation with different spells/regents - peridots cost me 9.5plat with a bard with max faction, max charisma, and knowing which merchants are 'cheap' merchants. 9.5*20=190pp, and I odn't know about you, but I wouldn't want to be burning plat just to buff the same sod over and over for free ;)


Along that lines, dammit, when is EQ gonna get houses? I would have rather had houses than horses :/ Even the apartments in Asheron's Call would have rocked in EQ. /sigh

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

grumble, weak testing on 1.1

Post by Gumby » Fri Jan 30, 2004 1:39 am

Was informed of a glaring error that creeped into 1.1. It's corrected now, but if you run into problems parsing multiple aliases, regrab the code which I edited on the initial post.

Also just as a random note on it, with the switch on parsing in 1.1 multi-word aliases do now work, so the "prot 9" requesters can get their buffs too.

Seph: I see where you're going with the virtue bit, I'll stand by my comment that AFK macroing's a bad idea (at least with a public bot but friend / guild use... the bot'd probably drool on itself currently without a reagent too atm), but I can try to put something small in to take care of what you want sometime after 1.2 and after chat-back's fleshed out. 1.2's near term, 1.3ish (more robust chatting probably here) or 2.0 are a ways off... there's other things on the table I need to get done first from a scripting perspective.

G

Gumby
a ghoul
a ghoul
Posts: 99
Joined: Sat Jan 24, 2004 5:27 pm

Post by Gumby » Mon Feb 02, 2004 11:07 pm

daerck wrote:I must admit I haven't worked myself through the code yet, but I would like to know if it's possible (or how much of a hassle) it would be to include AA ability buffs such as Unfailing Divinity (Cleric DI AA) in this. They can be easily cast with /alt activate ## (194 for Unfailing Divinity I think)
Updated in the 1.2 code just posted along with some other feature changes and functionality requests.

Tested the AA code with MGB SoTW, haven't as of yet loaded it on other toons to check the other AAs but let me know if it works for ya.

Thanks again for the suggestion,

G

blindrebel7
decaying skeleton
decaying skeleton
Posts: 2
Joined: Sun Jan 25, 2004 8:34 pm

Post by blindrebel7 » Sat Feb 28, 2004 12:48 am

I'm horrible at programming so been having a hard time getting the authentication to work, trying to set it up for a guild tag but can't figure out what code to replace or change. Anyone have any advice? :/ Thanks in advance.

*edit* Nevermind, I figured it out.

omper
a ghoul
a ghoul
Posts: 110
Joined: Sat Dec 06, 2003 10:46 pm

Post by omper » Mon Mar 08, 2004 3:16 am

was wondering. how hard would it be to add in a few things.. Like Autofollow. and a Autogroup.. ie

i tell buffbitch to join after i invite..


if you could help me in that respect i would love..


thanks

omper

omper
a ghoul
a ghoul
Posts: 110
Joined: Sat Dec 06, 2003 10:46 pm

Post by omper » Mon Mar 08, 2004 3:21 am

was wondering. how hard would it be to add in a few things.. Like Autofollow. and a Autogroup.. ie

i tell buffbitch to join after i invite..


if you could help me in that respect i would love..


thanks

omper