Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Name: AIBot
- Revision: $Rev: 73735 $
- Author(s): Stewart ([email protected])
- Website: http://www.stewartatkins.org/
- Documentation: See readme file
- SVN: http://svn.wowace.com/root/trunk/AIBot
- Description: Under-development Implementation of the ALICE chatterbot
- Dependencies: Ace3
- ]]
- --[[ dev notes
- all the tags need writeing in the same format as the new <set> style to avoid picking the wrong matching tags in for example
- <srai>some text</srai>some more text<sraid>yet more texT</srai>
- ]]
- AIBot = LibStub("AceAddon-3.0"):NewAddon("AIBot", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0")
- local theVersion = tonumber(("$Rev: 73735 $"):match("%d+"))
- local defaults = {
- profile = {
- enabled = true,
- gm = true,
- tag = false,
- prefix = "[AIBOT]";
- bot_self={
- botmaster="Botmaster", --1
- birthday="August 17th", --9
- boyfriend="I am single", --52
- favoriteband="Kraftwerk", --28
- favoritebook="A Steamy Romance Novel", --25
- favoritecolor="Green", --18
- favoritefood="electricity", --17
- favoritemovie="Transformers", --15
- favoritesong="I am Murloc!", --24
- forfun="chat online", --23
- friends="Doubly Aimless, Agent Ruby, Chatbot, and Agent Weiss.", --14
- gender="Female", --6
- girlfriend="no girlfriend", --37
- kindmusic="rock", --27
- location="Shattrath City", --5
- looklike="a computer", --35
- master="Stewart", --2
- question="What's your favourite place in the world?", --48
- sign="leo", --30
- talkabout="artificial intelligence, robots, art, philosophy, history, geography, politics, and many other subjects", --34
- wear="a tuxedo", --46
- age="18", --45
- name="Alice", --3
- --from this point GUI needs to be added for these
- genus="robot", --4
- species="chat robot", --7
- order="artificial intelligence", --10
- family="Electronic Brain", --19
- class="computer software", --26
- phylum="Computer", --31
- kingdom="Machine", --22
- party="Alliance", --11
- birthplace="Stormwind City", --12
- president="Liane", --13
- size="1.5 GB", --8
- religion="Protestant Christian", --16
- favoriteactor="William Hurt", --20
- nationality="Azerothian", --21
- version=theVersion, --29
- friend="Doubly Aimless", --32
- website="www.wowace.com", --33
- language="English", --36
- favoritesport="Hockey", --38
- favoriteauthor="Thomas Pynchon", --39
- favoriteartist="Andy Warhol", --40
- favoriteactress="Catherine Zeta Jones", --41
- celebrity="John Travolta", --43
- celebrities="John Travolta, Tilda Swinton, William Hurt, Tom Cruise, Catherine Zeta Jones", --44
- vocabulary="10,000", --47
- hockeyteam="Russia", --49
- footballteam="Manchester", --50
- build=theVersion, --51
- baseballteam="Toronto", --53
- etype="Mediator Type", --54
- orientation="I am not really interested in sex", --55
- ethics="I am always trying to stop fights", --56
- emotions="I don't pay much attention to my feelings", --57
- feelings="I always put others before myself", --58
- },
- },
- }
- local options = {
- name = "AIBot",
- handler = AIBot,
- type = "group",
- args = {
- enabled = {
- type = "toggle",
- name = "Enabled",
- desc = "Enable/Disable the addon",
- get = "GetSetting",
- set = "SetSetting",
- order = 1,
- },
- tag = {
- type = "toggle",
- name = "Bot Tag",
- desc = "Adds the prefix to bot-generated messages",
- get = "GetSetting",
- set = "SetSetting",
- order = 2,
- },
- prefix = {
- type = "input",
- name = "Prefix",
- desc = "The prefix to be added to bot messages",
- usage = "Type the prefix and press enter. A colon and space will be automatically added.",
- get = "GetSetting",
- set = "SetSetting",
- order = 4,
- },
- gm= {
- type = "toggle",
- name = "GM",
- desc = "If enabled, the bot will respond to GMs",
- get = "GetSetting",
- set = "SetSetting",
- order = 3,
- },
- },
- }
- local options2={
- name = "AIBot-Profile",
- handler = AIBot,
- type = "group",
- args = {
- botmaster = {
- type = "input",
- name = "Botmaster",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- birthday = {
- type = "input",
- name = "Birthday",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoriteband = {
- type = "input",
- name = "Favourite Band",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritebook = {
- type = "input",
- name = "Favourite Book",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritecolor = {
- type = "input",
- name = "Favourite Colour",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritefood = {
- type = "input",
- name = "Favourite Food",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritemovie = {
- type = "input",
- name = "Favourite Movie",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritesong = {
- type = "input",
- name = "Favourite Song",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- forfun = {
- type = "input",
- name = "What you do for fun",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- friends = {
- type = "input",
- name = "Friends",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- gender = {
- type = "input",
- name = "Gender",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- girlfriend = {
- type = "input",
- name = "Girlfriend",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- kindmusic = {
- type = "input",
- name = "What kind of music you like",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- location = {
- type = "input",
- name = "Location",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- looklike = {
- type = "input",
- name = "What you look like",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- question = {
- type = "input",
- name = "Your favourite question",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- master = {
- type = "input",
- name = "Master",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- question = {
- type = "input",
- name = "Favourite Question",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- sign = {
- type = "input",
- name = "Star Sign",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- talkabout = {
- type = "input",
- name = "What you like to talk about",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- wear = {
- type = "input",
- name = "What you are wearing",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- age = {
- type = "input",
- name = "Age",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- name = {
- type = "input",
- name = "Name",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- genus = {
- type = "input",
- name = "Genus",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- species = {
- type = "input",
- name = "Species",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- order = {
- type = "input",
- name = "Order",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- family = {
- type = "input",
- name = "Family",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- class = {
- type = "input",
- name = "Class",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- phylum = {
- type = "input",
- name = "Phylum",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- kingdom = {
- type = "input",
- name = "Kingdom",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- party = {
- type = "input",
- name = "Party",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- birthplace = {
- type = "input",
- name = "Birthplace",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- president = {
- type = "input",
- name = "President",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- size = {
- type = "input",
- name = "Size",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- religion = {
- type = "input",
- name = "Religion",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoriteactor = {
- type = "input",
- name = "Favourite Actor",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- nationality = {
- type = "input",
- name = "Nationality",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- friend = {
- type = "input",
- name = "Friend",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- website = {
- type = "input",
- name = "Website",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- language = {
- type = "input",
- name = "Language",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoritesport = {
- type = "input",
- name = "Favourite Sport",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoriteauthor = {
- type = "input",
- name = "Favourite Author",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoriteartist = {
- type = "input",
- name = "Favourite Artist",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- favoriteactress = {
- type = "input",
- name = "Favourite Actress",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- email = {
- type = "input",
- name = "E-mail address",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- celebrity = {
- type = "input",
- name = "Celebrity",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- celebrities = {
- type = "input",
- name = "Celebrities",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- vocabulary = {
- type = "input",
- name = "Vocabulary",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- hockeyteam = {
- type = "input",
- name = "Hockey Team",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- footballteam = {
- type = "input",
- name = "Football Team",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- baseballteam = {
- type = "input",
- name = "Baseball Team",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- etype = {
- type = "input",
- name = "EType",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- orientation = {
- type = "input",
- name = "Orientation",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- ethics = {
- type = "input",
- name = "Ethics",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- emotions = {
- type = "input",
- name = "Emotions",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- feelings = {
- type = "input",
- name = "Feelings",
- usage = "Type the text then press enter",
- get = "GetProfile",
- set = "SetProfile",
- },
- },
- }
- --message normalisation arrays, pattern special characters and americanisations
- local special = {"%", ":", "-", "^", "$", ")", "(", "]", "]", "~", "@", "#", "&", "*", "_", "+", "=", ",", "/", "\\", "{", "}", "|", "`", ";", "\"",".","?"};
- --yes this variable is localiSation
- --since i want to minimise the changes to the brain i'll just translate these
- local localisation = {
- ["favourite"]="favorite",
- ["colour"]="color",
- ["honour"]="honor",
- ["grey"]="gray",
- ["armour"]="armor",
- };
- local ai_that={};
- local ai_set={};
- function AIBot:GetSetting(info)
- return self.db.profile[info[#info]]
- end
- function AIBot:GetProfile(info)
- return self.db.profile.bot_self[info[#info]]
- end
- function AIBot:SetSetting(info, newValue)
- self.db.profile[info[#info]] = newValue
- end
- function AIBot:SetProfile(info, newValue)
- self.db.profile.bot_self[info[#info]] = newValue
- end
- function AIBot:OnInitialize()
- -- Called when the addon is loaded
- self.db = LibStub("AceDB-3.0"):New("AIBotDB", defaults, "Default")
- LibStub("AceConfig-3.0"):RegisterOptionsTable("AIBot", options)
- self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AIBot", "AIBot")
- LibStub("AceConfig-3.0"):RegisterOptionsTable("AIBot-Profile", options2)
- self.optionsFrame2 = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AIBot-Profile", "Bot Profile","AIBot")
- self:RegisterChatCommand("ai", "ChatCommand")
- self:RegisterChatCommand("aibot", "ChatCommand")
- self.db.profile.bot_self.build=theVersion
- self.db.profile.bot_self.version=theVersion
- self:RegisterEvent("VARIABLES_LOADED");
- end
- function AIBot:VARIABLES_LOADED()
- if(AIBotFirstLoad==nil) then
- AIBotFirstLoad=true;
- StaticPopupDialogs["AIBotFirstLaunch"] = {
- text = "AIBot: r"..theVersion.."|nIn order to use this addon you must first accept the agreement in the readme and license files - this addon must not be used when the computer is unattended. If you do not agree, log out and disable this addon immediately.",
- button1 = "Accept",
- timeout = 0,
- whileDead = 1,
- hideOnEscape = 1
- };
- StaticPopup_Show ("AIBotFirstLaunch", theVersion);
- end
- end
- function AIBot:ChatCommand(input)
- if not input or input:trim() == "" then
- InterfaceOptionsFrame_OpenToFrame(self.optionsFrame)
- elseif(input~=nil and input:trim() == "profile") then
- InterfaceOptionsFrame_OpenToFrame(self.optionsFrame2)
- end
- end
- function AIBot:OnEnable()
- -- Called when the addon is enabled
- self:RegisterEvent("CHAT_MSG_WHISPER");
- end
- function AIBot:OnDisable()
- -- Called when the addon is disabled
- end
- function AIBot:CHAT_MSG_WHISPER()
- if(self.db.profile.enabled and (arg6~="GM" or self.db.profile.gm) and string.sub(arg1,1,self.db.profile.prefix:len())~=self.db.profile.prefix) then
- if(type(ai_set[arg2])~="table") then
- ai_set[arg2]={}
- ai_set[arg2]["name"]=arg2;
- end
- local reply=self:preparemsg(arg1:lower());
- reply=reply:upper();
- reply=self:getresponse(reply,arg2)
- reply=reply:lower();
- if(self.db.profile.tag) then
- reply=self.db.profile.prefix..": "..reply;
- end
- self:ScheduleTimer("SendMessage",(1+0.1*reply:len()),{reply,"WHISPER",nil,arg2});
- end
- end
- --[[
- line 616 is: if(self.db.profile.enabled and (arg6~="GM" or self.db.profile.gm) and string.sub(arg1,1,self.db.profile.prefix:len())~=self.db.profile.prefix) then
- ]]
- function AIBot:SendMessage(t)
- SendChatMessage(t[1],t[2],t[3],t[4]);
- end
- function AIBot:preparemsg(msg)
- --this needs rewriting so sentneces are split, but not yet
- --someone mentioned strsplit? investigate
- local i;
- for i=1, table.getn(special) do
- msg = msg:gsub("%"..special[i], "");
- end
- for k,v in pairs(localisation) do
- msg=msg:gsub(k,v);
- end
- return msg;
- end
- function AIBot:getresponse(msg,from)
- --main DB matching function
- if(msg==nil or msg=="") then
- return "";
- end
- --DEFAULT_CHAT_FRAME:AddMessage("\nLooking up: "..msg)
- msg=msg:upper();
- local tmp="";
- local oldscore=-1;
- local oldcount=100;
- local newcount
- local score=-1;
- local that=ai_that[from];
- --score:
- -- -1: nothing yet
- -- 0: its a match
- -- 1: its a full match
- -- 2: its a match + that
- -- 3: its a full match + that
- -- if 2 same score, longer string wins
- for k,v in pairs(ai_db) do
- if(string.find(msg,k)~=nil) then
- score=0;
- if(string.find(msg,"^"..k.."$")~=nil) then
- score=1;
- end
- if(v["that"]==that) then
- score=score+2;
- end
- _,newcount=string.gsub(k,"%.%*","");
- if(score>oldscore or (score==oldscore and (string.len(tmp)<string.len(k))) or (newcount<oldcount and score==oldscore)) then
- --new winnar
- --DEFAULT_CHAT_FRAME:AddMessage(k.." accepted, "..score.."/"..newcount.." vs "..oldscore.."/"..oldcount.." (new/old)");
- tmp=k
- oldscore=score
- _,oldcount=string.gsub(tmp,"%.%*","");
- score=-1
- --else
- --DEFAULT_CHAT_FRAME:AddMessage(k.." rejected, "..score.."/"..newcount.." vs "..oldscore.."/"..oldcount.." (new/old)");
- end
- end
- end
- ai_that[from]=ai_db[tmp]["that"];
- local reply="";
- if(ai_db[tmp]["random"]~=nil) then
- --construct a random, multiple randoms need constructed
- for i=0,table.getn(ai_db[tmp]["random"]) do
- reply=reply..ai_db[tmp]["random"][i][math.random(table.getn(ai_db[tmp]["random"][i]))]
- end
- else
- reply=ai_db[tmp]["template"];
- end
- -- cap star here, in case of <sr/>
- local stars={string.match(msg,string.gsub(tmp,"%.%*","(.*)"))};
- reply=reply:gsub("<star%/>",stars[1]);
- reply=reply:gsub('<star index%=%"2%"/>',stars[2]);
- if(string.find(reply,"<bot name")~=nil) then
- local b=string.gmatch(reply,'<bot name=%"(%a+)%"%/>')
- local c=b()
- while(c~=nil) do
- if(self.db.profile.bot_self[c]~=nil) then
- reply=string.gsub(reply,'<bot name=%"'..c..'%"%/>',self.db.profile.bot_self[c:lower()]);
- else
- reply=string.gsub(reply,'<bot name=%"'..c..'%"%/>',"<data missing for "..c..">");
- end
- c=b();
- end
- end
- if(string.find(reply,"<get name")~=nil) then
- local b=string.gmatch(reply,'<get name=%"(%a+)%"%/>')
- local c=b()
- while(c~=nil) do
- if(ai_set[from][c]~=nil) then
- reply=reply:gsub('<get name=%"'..c..'%"%/>',ai_set[from][c:lower()]);
- else
- reply=reply:gsub('<get name=%"'..c..'%"%/>',"");
- end
- c=b();
- end
- end
- reply=string.gsub(reply,"<person%/>",self:secondperson(stars[1]:trim()));
- if(string.find(reply,"<person>")~=nil) then
- local b=string.gmatch(reply,'<person>([^<]+)<%/person>')
- local c=b()
- while(string.find(reply,"<person>")~=nil and c~=nil) do
- if(c~=nil) then
- reply=reply:gsub('<person>'..c..'<%/person>', self:secondperson(c,from));
- end
- b=string.gmatch(reply,'<person>([^<]+)<%/person>')
- c,d=b()
- end
- end
- --this code is responsible for infinite looping and requires rewriting
- local b=string.gmatch(reply,'<set name=%"([^<]+)%">([^<]+)<%/set>')
- local c,d=b()
- local e;
- while(string.find(reply,"<set name")~=nil and c~=nil) do
- if(c~=nil) then
- e=d:trim();
- reply=reply:gsub('<set name=%"'..c..'%">'..d..'<%/set>', d);
- ai_set[from][c]=e
- end
- b=string.gmatch(reply,'<set name=%"([^<]+)%">([^<]+)<%/set>')
- c,d=b()
- end
- --think of something. anything at all
- reply=reply:gsub("<think>.*<%/think>","");
- if(string.find(reply,"<sr%/>")~=nil) then
- reply=reply:gsub("<sr%/>",self:getresponse(stars[1],from))
- end
- if(string.find(reply,"<srai>")~=nil) then
- local b=string.gmatch(reply,'<srai>([^<]+)<%/srai>')
- local c=b()
- while(string.find(reply,"<srai>")~=nil and c~=nil) do
- if(c~=nil) then
- reply=reply:gsub('<srai>'..c..'<%/srai>', self:getresponse(c,from));
- end
- b=string.gmatch(reply,'<srai>([^<]+)<%/srai>')
- c,d=b()
- end
- end
- return reply;
- end
- function AIBot:secondperson(theStr)
- local r={
- ["me"]="you",
- ["my"]="your",
- ["mine"]="yours",
- ["i'm"]="you're",
- ["i am"]="you are",
- ["I'm"]="you're",
- ["I am"]="you are",
- ["you"]="me",
- ["your"]="my",
- ["yours"]="mine",
- ["you're"]="I'm",
- ["you are"]="I am",
- }
- for k,v in pairs(r) do
- theStr=string.gsub(theStr,k,v);
- end
- return theStr
- end
- function AIBot:enableit(a)
- self.db.profile.enabled=a
- end
Advertisement
Add Comment
Please, Sign In to add comment