|
Good bots are never simple to make, and even when you think you've learned everything, or done everything with the program, you find out something else you can do with it. Furbot is designed with a simplicity in mind which can lead to complex interaction with the user (either the dream or the person whispering the bot), and the design system is laid out to facilitate this.
Lets start something from the beginning, assuming a blank bot. The first thing we want in the bot is a database to hold people authorized to generate a banish command, this is a simple table we're going to use where if the name is in the table, they are authorized to use the bot to banish, or temp-banish the "offender". (If you are already using a database, you might just want to use that database name instead and this will add the table to that database.) Trigger Name: Connect DB Creation Connection establishes No Additional Conditions. THEN: $DATABASE: Open database {[scriptdir]members.mdb} to filenumber {1}
Trigger Name: Connect DB Authorization Table Connection establishes AND: $DATABASE: If table {banishers} doesn't exist in database {1} THEN: $DATABASE: Create table {banishers} in database {1}
Trigger Name: Connect DB Banished Table Connection establishes AND: $DATABASE: If table {banished} doesn't exist in database {1} THEN: $DATABASE: Create table {banished} in database {1} The variable referred to in the first command Connect DB Creation by the name of [scriptdir] is a internal variable which uses the location of the botscript file for the database, obviously, before running this bot it would be best to save the botscript file before connecting the bot, otherwise you will waste your time with adding people to the banishers table. One additional connect command is needed, there must be at least one person hard wired into the code who can add or remove people from the banishers table: Trigger Name: Set Owner Variable Program starts No Additional Conditions. THEN: Store {Your|Name|Here} to variable {[botowner]} Ok, now we save this and open up the Actions part of the bot, (we'll be jumping about the different sections of the bot as we go along, again, dual nature of the bot and not everything can go in one section, ...) Action Name: Add Banisher Error Check Stop Action Search if TRUE If {*} Whispers me {add banisher *} AND: if variable {[player]} is the same as {[botowner]} (text comparison) $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[word3]} THEN: Whisper back {[word3] is already authorized to banish people.}
Action Name: Add Banisher Valid Stop Action Search if TRUE If {*} Whispers me {add banisher *} AND: if variable {[player]} is the same as {[botowner]} (text comparison) THEN: $DATABASE: Add record named {[word3]} to table {banishers} _ in database {1} Whisper back {[word3] is now authorized to banish people.}
Action Name: Get Banisher List Stop Action Search if TRUE If {*} Whispers me {banishers} No Additional Conditions. THEN: $DATABASE: List all IDs from database {1} table {banishers} _ which start with {*} to variable {[banishers]} Whisper back {Current Banishers: [banishers]} The last action, Get Banisher List, is termed a public command for there is no restrictions on who can access that part of the program, if you don't want John Public to be able to find out who can banish people, you may want to add restrictions to that, like perhaps only you, in which case you would duplicate: if variable {[player]} is the same as {[botowner]} (text comparison) to that command, or other banishers: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} Or perhaps only to people who are members of your dream, in which case you need another database for them, ...
Anyway, we will also want a means to remove someone from the banishers table: Action Name: Remove Banisher Error Check Stop Action Search if TRUE If {*} Whispers me {remove banisher *} AND: if variable {[player]} is the same as {[botowner]} (text comparison) $DATABASE: if there is not a record in table {banishers} _ in database {1} where ID is {[word3]} THEN: Whisper back {[word3] is not in my authorization list.}
Action Name: Remove Banisher Valid Stop Action Search if TRUE If {*} Whispers me {remove banisher *} AND: if variable {[player]} is the same as {[botowner]} (text comparison) THEN: $DATABASE: Remove record from database {1} table {banishers} _ where ID is {[word3]} Whisper back {[word3] is no longer authorized to use me to _ banish people.} And finally, the action to cause the bot to execute the banish, or tempbanish command, plus checks on whether it happened or not, so to speak: Action Name: Banish Someone If {*} Whispers me {banish *} AND: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} $DATABASE: if there is not a record in table {banished} _ in database {1} where ID is {[word2]} THEN: Banish {[word2]} from the uploader's dreams $DATABASE: Add record named {[word2]} to table {banished} _ in database {1} Whisper back {[word2] has been added to the banish list.} Store {[player]} to variable {[reportbanishto]}
Action Name: UnBanish Someone Stop Action Search if TRUE If {*} Whispers me {unbanish *} AND: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} THEN: Banish off for {[word2]}, leave blank for banish-off-all $DATABASE: Remove record from database {1} table {banished} _ where ID is {[word2]} Whisper back {[word2] has been removed from the banish list} Store {[player]} to variable {[reportbanishto]} The variable [reportbanishto] will be used by the program in the trigger which detects that the server sends a banish command back to the bot and reports the server's response to the banish command. Note: Currently, and I knew this all along, the bot only directly deals with the banish command, will build a bot which handles the tempbanish command, for a work around, you can use: Say {tempbanish [word2]} And it should work just as well.
Before we do head back to the triggers, and the optional timer system which deals with people logging off before they can get banished, we should add two more (or three, depending on your syntax preferences) commands to the list: Action Name: Banish DB List Stop Action Search if TRUE If {*} Whispers me {banished} AND: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} THEN: $DATABASE: List all IDs from database {1} table {banished} _ which start with {*} to variable {[banished]} Whisper back {DB Banish List: [banished]}
Action Name: Banish List A Stop Action Search if TRUE If {*} Whispers me {banish list} AND: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} THEN: Store {[player]} to variable {[reportbanishto]} Banish list, retrieve the list of banished names
Action Name: Banish List B Stop Action Search if TRUE If {*} Whispers me {banish-list} AND: $DATABASE: if there is a record in table {banishers} in database {1} _ where ID is {[player]} THEN: Store {[player]} to variable {[reportbanishto]} Banish list, retrieve the list of banished names The first command retrieves the list of names in the database, the next two are just to handle that some people may whisper the bot banish list instead of banish-list.
Now, back to the triggers and we will add a command to return the server's response to the banish commands back to the triggering player, that's why we needed to put their name into a specific variable: Trigger Name: Detect Banish Replies Banish reply is detected AND: if variable {[reportbanishto]} is not the same as {[botname]} _ (text comparison) THEN: Whisper {[reportbanishto]} the message {[banishact]} Store {[botname]} to variable {[reportbanishto]} And that almost wraps up the basics, now for the bit of complex, namely, how do you banish someone who logs off before the banish can be acted on? That's why we have a table for the banished, and why we are going to add a timer to the system. To make an online check system for the bot, we are going to have to dive a bit into wolfscript because we need to make a custom command and loop system work with a timer: Timer Name: Banish Offline Check When {60} seconds has passed No Additional Conditions. THEN: $ Begin Wolfscript: (1) // trigger online check &setvar onlinecheck FALSE &newvar #which &getvar(onlineindex) &dbopen 1 {select * from banished &dbmovefirst 1 &newvar #count &dbrecordcount(1) &ifn #count > 0 &dbmovelast 1 &dbmovefirst 1 &set #count &dbrecordcount(1) &ifn #which >= #count &set #which 0 &setvar onlineindex #which &endif &dbmoveto 1 #which &newvar #name {#onln } &join #name &dbtostr(&dbf(1 ID)) &say #name &endif $ End Wolfscript: (1) This will, every 60 seconds, generate an online check for anyone in the banished table, if there's no names, nothing happens, otherwise it will take the name, and create an online check command for the bot to send to the server. To detect the status of this online check will require two more triggers for detecting the specific server command which informs the system of the status of the name. You could use a time period faster than 60 seconds, but for this system, it's not that terribly more efficient to do so, we can add yet one more command to the botscript to handle cases where the persone logs back in, and gets into the dream, before the banish takes effect. But first, the specific command triggers: Trigger Name: Online Catch Furcadia sends command {]%*} No Additional Conditions. THEN: $ Begin Wolfscript: (1) // online checking &newvar #message &getvar(message) &newvar #online &mid(#message 3 1) &newvar #name &mid(#message 4) &newvar #sql {select * from banished where ID like '} &join #sql &getvar(onlinename) &join #sql {' order by ID}
&dbopen 1 #sql // if the darn thing comes back empty, name error &newvar #check &dbrecordcount(1) &ifn #check > 0 &ifn #online = 1 // then name is online, banish them and remove them from the DB &newvar #banish {banish } &join #banish #name &say #banish &setvar removename TRUE &setvar banishname #name &exitwolf &endif &endif
&newvar #which &getvar(onlineindex) &add #which 1 &setvar onlineindex #which $ End Wolfscript: (1)
Trigger Name: Online Catch Banished Furcadia sends command {]%*} AND: if variable {[removename]} is the same as {TRUE} (text comparison) THEN: $DATABASE: Remove record from database {`} table {banished} _ where ID is {[banishname]} There is a means to execute the removal with the wolfscript so you can dispense with the second command, but that's getting really geeky with wolfscript: Trigger Name: Online Catch Furcadia sends command {]%*} No Additional Conditions. THEN: $ Begin Wolfscript: (1) // online checking &newvar #message &getvar(message) &newvar #online &mid(#message 3 1) &newvar #name &mid(#message 4) &newvar #sql {select * from banished where ID like '} &join #sql &getvar(onlinename) &join #sql {' order by ID}
&dbopen 1 #sql // if the darn thing comes back empty, name error &newvar #check &dbrecordcount(1) &ifn #check > 0 &ifn #online = 1 // then name is online, banish them and remove them from the DB &newvar #banish {banish } &join #banish #name &say #banish &set #sql sprintf({DELETE FROM banished WHERE ID='%1'} #name) &dbexecute 1 #sql &exitwolf &endif &endif
&newvar #which &getvar(onlineindex) &add #which 1 &setvar onlineindex #which $ End Wolfscript: (1) Note that with either means of removing the name from the table, we don't advance the index to the table because that would skip a record from the list.
And finally, we can also use a WhoIs check to pop people who have not made it into the server's banish list, but are still scheduled to be banished: WhoIs Name: Detect Banished Name Entry If {*} Comes to the map AND: $DATABASE: if there is a record in table {banished} in database {1} _ where ID is {[player]} THEN: Banish {[player]} from the uploader's dreams TaDa! Of course, you may want to dispense with the whole timer system and online name checking triggers, in which case, if the offending person logs off before the (temp)banish takes place, when they do log on, the instant they enter the dream, bam! They're done for. :cat-devious:
The botscript is available here.
Footnote: Not tested, built this sucker as I was writing this post, ... |