summaryrefslogtreecommitdiff
path: root/plugins/manaboy.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/manaboy.py')
-rw-r--r--plugins/manaboy.py1390
1 files changed, 1390 insertions, 0 deletions
diff --git a/plugins/manaboy.py b/plugins/manaboy.py
new file mode 100644
index 0000000..127ddd0
--- /dev/null
+++ b/plugins/manaboy.py
@@ -0,0 +1,1390 @@
+# -*- coding: utf-8 -*-
+import time
+import net.mapserv as mapserv
+import net.charserv as charserv
+import net.stats as stats
+import commands
+import walkto
+import logicmanager
+import status
+import plugins
+import itemdb
+import random
+from collections import deque
+from net.inventory import get_item_index, get_storage_index
+from utils import extends
+from actor import find_nearest_being
+from chat import send_whisper as whisper
+
+from net.onlineusers import OnlineUsers
+
+__all__ = [ 'PLUGIN', 'init' ]
+
+def preloadArray(nfile):
+ try:
+ file = open(nfile, "r")
+ array=[]
+ for x in file.readlines():
+ x = x.replace("\n", "")
+ x = x.replace("\r", "")
+ array.append(x)
+ file.close()
+ return array
+ except:
+ print "preloadArray: File " + nfile + " not found!"
+
+joke_answers = preloadArray("bot/jokes.txt")
+ignored_players = preloadArray("bot/ignored.txt")
+disliked_players = preloadArray("bot/disliked.txt")
+admins = preloadArray("bot/admins.txt")
+friends = preloadArray("bot/friends.txt")
+
+# ====================== XCOM =============
+XCOMList = preloadArray("bot/XCOM.txt")
+XCOMServerStatInterested = [] #List of nicks interested in server status change
+XCOMBroadcastPrefix = "##B##G "
+
+
+def online_list_update(curr,prev):
+ for x in curr:
+ found = False
+ for y in prev:
+ if x==y: found = True
+ if found == False: #detected change
+ for nicks in XCOMList: #For every XCOM user...
+ if nicks in online_users.online_users: #That's online...
+ if nicks in XCOMServerStatInterested: #If XCOM player is interested
+ if x in XCOMList: #An XCOM user connected?
+ XCOMDelay() #Share its status
+ whisper(nicks, "##W" + x + " is now online [XCOM]")
+ else: #Is a regular server player
+ if x not in XCOMList:
+ XCOMDelay() #Share its status
+ whisper(nicks, "##W" + x + " is now online")
+
+ for x in prev:
+ found = False
+ for y in curr:
+ if x==y: found = True
+ if found == False:
+ for nicks in XCOMList: #For every XCOM user...
+ if nicks in online_users.online_users: #That's online...
+ if nicks in XCOMServerStatInterested: #If XCOM player is interested
+ if x in XCOMList: #An XCOM user connected?
+ XCOMDelay() #Share its status
+ whisper(nicks, "##L" + x + " is now offline [XCOM]")
+ else: #Is a regular server player
+ if x not in XCOMList:
+ XCOMDelay() #Share its status
+ whisper(nicks, "##L" + x + " is now offline")
+
+online_users = OnlineUsers(online_url=' https://server.themanaworld.org/online-old.txt', update_interval=20, refresh_hook=online_list_update)
+
+def XCOMOnlineList(nick, message, is_whisper, match):
+ XCOMDelay()
+ msg=""
+ for nicks in XCOMList:
+ if nicks in online_users.online_users:
+ msg = msg + nicks + " | "
+ XCOMDelay()
+ whisper(nick, msg)
+
+def XCOMPrintStat():
+ pOnline=0
+ xOnline=0
+ for p in online_users.online_users:
+ pOnline=pOnline+1
+ if p in XCOMList:
+ xOnline=xOnline+1
+ return "%(xOnline)d/%(pOnline)d"%{"pOnline": pOnline, "xOnline": xOnline,}
+
+def XCOMDelay():
+ time.sleep(0.1)
+
+def XCOMBroadcast(message):
+ for nicks in XCOMList:
+ if nicks in online_users.online_users:
+ if nicks not in ignored_players:
+ XCOMDelay()
+ whisper(nicks, message)
+
+def XCOMCommunicate(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ if message[0]=="!":
+ return
+ if message.startswith("*AFK*:"): # AFK bug workaround
+ return
+ if nick in XCOMList:
+ for nicks in XCOMList:
+ if nicks in online_users.online_users:
+ if nick==nicks:
+ pass
+ else:
+ XCOMDelay()
+ whisper(nicks, "##B##LXCOM[" + XCOMPrintStat() + "]##l " + nick + ": ##b" + message)
+ else:
+ whisper(nick, XCOMBroadcastPrefix + "XCOM is not enabled (Use !xcon)")
+
+def XCOMSilentInvite(nick, message, is_whisper, match):
+ XCOMDelay()
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ if nick in admins:
+ XCOMList.append(match.group(1))
+ if match.group(1) not in ignored_players:
+ whisper(nick, "##W--- " + nick + " silently invited " + match.group(1) + " on XCOM ---")
+ else:
+ whisper(nick, "##W" + match.group(1) + " has been ignored by bot and cannot be added to XCOM.")
+
+def XCOMInvite(nick, message, is_whisper, match):
+ XCOMDelay()
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ if nick in admins:
+ XCOMList.append(match.group(1))
+ XCOMBroadcast("##W--- " + nick + " (Admin) invited " + match.group(1) + " on XCOM ---" + XCOMBroadcastPrefix + match.group(1) + " XCOM enabled! Use !xcoff to disable, use !xclist to see XCOM online list")
+ else:
+ if nick in ignored_players:
+ whisper(nick, "You cannot invite banned players.")
+ else:
+ whisper(match.group(1), "##W--- " + nick + " invited you on XCOM --- Answer !xcon to join.")
+ XCOMDelay()
+ whisper(nick, "Invited " + match.group(1) + " to join XCOM. Waiting for his/her reply...")
+
+def XCOMEnable(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ #search array
+ if nick in XCOMList:
+ whisper(nick, XCOMBroadcastPrefix + nick + " XCOM already enabled")
+ else:
+ XCOMList.append(nick)
+ XCOMBroadcast("##W--- " + nick + " is online on XCOM ---" + XCOMBroadcastPrefix + nick + " XCOM enabled! Use !xcoff or !xcom off to disable, use !xclist to see XCOM online list")
+
+def XCOMDisable(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ #search array
+ if nick in XCOMList:
+ XCOMBroadcast("##L--- " + nick + " disabled XCOM ---")
+ XCOMList.remove(nick)
+ else:
+ whisper(nick, XCOMBroadcastPrefix + nick + " XCOM already disabled")
+
+def XCOMServerInterestEnable(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ #search array
+ if nick in XCOMList:
+ whisper(nick, XCOMBroadcastPrefix + "Server online status notifications enabled!")
+ XCOMServerStatInterested.append(nick)
+
+def XCOMServerInterestDisable(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return #or say something
+ #search array
+ if nick in XCOMList:
+ whisper(nick, XCOMBroadcastPrefix + "Server online status notifications disabled!")
+ XCOMServerStatInterested.remove(nick)
+
+def XCOMBan(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in admins:
+ #search array
+ if match.group(1) in ignored_players:
+ whisper(nick, "Already banned.")
+ else:
+ ignored_players.append(match.group(1))
+ XCOMList.remove(match.group(1))
+ #FIXME array need to be saved!!!
+ XCOMBroadcast(XCOMBroadcastPrefix + match.group(1) + " is now banned from XCOM")
+ else:
+ whisper(nick, "Admins only.")
+
+def XCOMUnBan(nick, message, is_whisper, match):
+ XCOMDelay()
+ #accept only whispers
+ if not is_whisper:
+ return
+ if nick in admins:
+ #search array
+ if match.group(1) in ignored_players:
+ XCOMList.append(match.group(1))
+ ignored_players.remove(match.group(1))
+ #FIXME array need to be saved!!!
+ XCOMBroadcast(XCOMBroadcastPrefix + match.group(1) + " is now unbanned from XCOM")
+ whisper(match.group(1), "You are now unbanned from XCOM. Don't make it happen again.")
+ else:
+ whisper(nick, "Already banned.")
+ else:
+ whisper(nick, "Admins only.")
+
+# =============================================
+
+greetings = {
+ "Hi {0}!" : 4,
+ "Hey {0}" : 3,
+ "Yo {0}" : 2,
+ "{0}!!!!" : 1,
+ "{0}!!!" : 1,
+ "{0}!!" : 1,
+ "Hello {0}!!!" : 5,
+ "Hello {0}!" : 5,
+ "Welcome back {0}!" : 3,
+ "Hello {0}! You are looking lovely today!" : 1,
+ "Hello {0}! I'm the bot that you can trust: I want your money!" : 1,
+ "{0} is back!!" : 1,
+ "Hello and welcome to the Aperture Science \
+computer-aided enrichment center." : 1,
+}
+
+drop_items = [
+ "a bomb", "a bowl of petunias", "a cake", "a candy", "a chocobo",
+ "a coin", "a cookie", "a drunken pirate", "a freight train",
+ "a fruit", "a mouboo", "an angry cat",
+ "an angry polish spelling of a rare element with the atomic number 78",
+ "an anvil", "an apple", "an iten", "a magic eightball", "a GM",
+ "a whale", "an elephant", "a piano", "a piece of moon rock", "a pin",
+ "a rock", "a tub", "a wet mop", "some bass", "Voldemort", "a sandworm",
+ "a princess", "a prince", "an idea", "Luvia", "a penguin",
+ "The Hitchhiker's Guide to the Galaxy",
+]
+
+dropping_other = [
+ "Hu hu hu.. {0} kicked me!",
+ "Ouch..",
+ "Ouchy..",
+ "*drops dead*",
+ "*sighs*",
+ "Leave me alone.",
+ "Whoa, dammit!",
+]
+
+explain_sentences = {
+ "livio" : "He created Liviobot.",
+ "party" : "Is a group of players with their chat tab and they can share exp, items and HP status. See [[@@https://wiki.themanaworld.org/index.php/Legacy:Party_Skill|Party Wiki@@] for more informations.",
+}
+
+dropping_special = {
+ "ShaiN2" : "*drops a nurse on {0}*",
+ "Shainen" : "*drops a nurse on {0}*",
+ "Silent Dawn" : "*drops a box of chocolate on {0}*",
+ "veryape" : "*drops a chest of rares on {0}*",
+ "veryapeGM" : "*drops a chest of rares on {0}*",
+ "Ginaria" : "*drops a bluepar on {0}*",
+ "Rift Avis" : "*drops an acorn on {0}*",
+}
+
+die_answers = [
+ "Avada Kedavra!",
+ "Make me!",
+ "Never!!",
+ "You die, {0}!",
+ "You die, {0}!",
+ "You die, {0}!",
+ "You die, {0}!",
+ "No!",
+ "In a minute..",
+ "Suuure... I'll get right on it",
+]
+
+healme_answers = [
+ "Eat an apple, they're good for you.",
+ "If I do it for you, then I have to do it for everybody.",
+ "Oh, go drink a potion or something.",
+ "Whoops! I lost my spellbook.",
+ "No mana!",
+]
+
+whoami_answers = [
+ "An undercover GM.",
+ "An exiled GM.",
+ "I'm not telling you!",
+ "I'm a bot! I'll be level 135 one day! Mwahahahaaha!!!111!",
+ "Somebody said I'm a Chinese copy of Confused Tree",
+ "I am your evil twin.",
+ "I don't remember anything after I woke up! What happened to me?",
+ "I don't know. Why am I here??",
+ "Who are you?",
+ "On the 8th day, God was bored and said 'There will be bots'. \
+So here I am.",
+ "♪ I'm your hell, I'm your dream, I'm nothing in between ♪♪",
+ "♪♪ Aperture Science. We do what we must, because.. we can ♪",
+ "I'm just a reincarnation of a copy.",
+]
+
+burn_answers = [
+ "*curses {0} and dies %%c*",
+ "Help! I'm on fire!",
+ "Oh hot.. hot hot!",
+ "*is glowing*",
+ "*is flaming*",
+ "ehemm. where are firefighters? I need them now!",
+ "*is so hot!*",
+]
+
+noidea_answers = [
+ "What?", "What??", "Whatever...", "Hmm...", "Huh?", "*yawns*",
+ "Wait a minute...", "What are you talking about?",
+ "Who are you?", "What about me?",
+ "I don't know what you are talking about",
+ "Excuse me?", "Very interesting", "Really?",
+ "Go on...", "*Scratches its leafy head*",
+ "*feels a disturbance in the force*",
+ "*senses a disturbance in the force*",
+ "*humming*", "I'm bored..", "%%j", "%%U", "%%[",
+]
+
+pain_answers = [ "Ouch..", "Ouchy..", "Argh..", "Eckk...", "*howls*",
+ "*screams*", "*groans*", "*cries*", "*faints*", "%%k",
+ "Why.. What did I do to you? %%i" ]
+
+hurt_actions = [ "eat", "shoot", "pluck", "torture", "slap", "poison",
+ "break", "stab", "throw", "drown" ]
+
+like_answers = [
+ "Yay it's",
+ "You are the sunshine in this beautiful land",
+ "Can't do this because I like you",
+]
+
+dislike_answers = [
+ "Oh, no! It's you!",
+ "Go away!!!",
+ "I don't want to see!",
+ "Your face makes onions cry.",
+ "You look like I need another drink…",
+ "Mayas were right...",
+]
+
+bye_answers = [
+ "See you soon!",
+ "Come back anytime!!!",
+ "See ya!",
+ "Hope to see you again!",
+ "More beer for me."
+]
+
+
+dislikebye_answers = [
+ "Finally!",
+ "Go away!!!",
+ "Don't come back!",
+ "Whew...",
+ "I need another drink…"
+]
+
+attack_answers = [
+ "Attack!!!",
+ "Whoa, dammit!",
+ "Alright!!!",
+ "I have some pain to deliver.",
+ "Fire at will!!!",
+ "...I'm all out of gum.",
+ "His name is: JOHN CENA!!!",
+ "Target acquired!",
+ "Puah!",
+ "Grr!!!",
+ "Eat this!",
+ "Ha!",
+ "Come on!",
+ "Party time!!!",
+ "I will burn you down.",
+ "The show begins...",
+ "I'm better than makeup artists, prepare yourself!!!",
+]
+
+notattack_answers = [
+ "Nope!",
+ "*picking his nose*",
+ "Do it yourself.",
+ "Meh.",
+ "I will attack you instead.",
+ "What about my reward?",
+]
+
+story_introductions = [
+ "I was with",
+ "Yesterday I got bored and called",
+ "With none else around I've asked",
+]
+
+story_action_fail = [
+ "failed at it",
+ "stomped on the soul menhir",
+ "slipped on a terranite ore",
+ "got interrupted by phone call",
+]
+
+# FIXME Unused
+story_actions = [
+ "jumping on",
+ "speaking with",
+ "attacking",
+ "poking",
+ "playing cards",
+]
+
+# -----------------------------------------------------------------------------
+def say_greeting(nick, _, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+
+ total_weight = 0
+ for w in greetings.itervalues():
+ total_weight += w
+
+ random_weight = random.randint(0, total_weight)
+ total_weight = 0
+ random_greeting = 'Hi {0}'
+ for g, w in greetings.iteritems():
+ if total_weight >= random_weight:
+ random_greeting = g
+ break
+ total_weight += w
+ if nick in disliked_players:
+ mapserv.cmsg_chat_message(random.choice(dislike_answers))
+ else:
+ mapserv.cmsg_chat_message(random_greeting.format(nick))
+ time.sleep(1)
+
+def say_goodbye(nick, _, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+
+ total_weight = 0
+ for w in greetings.itervalues():
+ total_weight += w
+
+ random_weight = random.randint(0, total_weight)
+ total_weight = 0
+ random_greeting = 'Hi {0}'
+ for g, w in greetings.iteritems():
+ if total_weight >= random_weight:
+ random_greeting = g
+ break
+ total_weight += w
+ if nick in disliked_players:
+ mapserv.cmsg_chat_message(random.choice(dislikebye_answers))
+ else:
+ mapserv.cmsg_chat_message(random.choice(bye_answers))
+ time.sleep(1)
+
+
+def drop_on_head(nick, _, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+
+ answer = 'yeah'
+ if nick in dropping_special:
+ answer = dropping_special[nick]
+ else:
+ r = random.randint(0, len(drop_items) + len(dropping_other))
+ if r < len(drop_items):
+ answer = "*drops {} on {}'s head*".format(drop_items[r], nick)
+ else:
+ answer = random.choice(dropping_other)
+
+ mapserv.cmsg_chat_message(answer.format(nick))
+
+
+def answer_threat(nick, _, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+
+ answer = random.choice(die_answers)
+ mapserv.cmsg_chat_message(answer.format(nick))
+
+
+# -----------------------------------------------------------------------------
+def admin_additem(nick, _, is_whisper, match):
+ if not is_whisper:
+ return
+
+ if nick not in tree_admins:
+ return
+
+ item = match.group(1)
+ if item not in drop_items:
+ drop_items.append(item)
+
+ send_whisper(nick, "Added item '{}' to drop list".format(item))
+
+
+def admin_addjoke(nick, _, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in tree_admins:
+ return
+
+ joke = match.group(1)
+ if joke not in joke_answers:
+ joke_answers.append(joke)
+
+ send_whisper(nick, "Added joke")
+
+
+# -----------------------------------------------------------------------------
+
+PLUGIN = {
+ 'name': 'manaboy',
+ 'requires': ('chatbot', 'npc', 'autofollow'),
+ 'blocks': (),
+}
+
+npcdialog = {
+ 'start_time': -1,
+ 'program': [],
+}
+
+_times = {
+ 'follow': 0,
+ 'where' : 0,
+ 'status' : 0,
+ 'inventory' : 0,
+ 'say' : 0,
+ 'zeny' : 0,
+ 'storage' : 0,
+}
+
+allowed_drops = [535, 719, 513, 727, 729, 869]
+allowed_sells = [531, 521, 522, 700, 1201]
+
+npc_owner = ''
+history = deque(maxlen=10)
+storage_is_open = False
+bugs = deque(maxlen=100)
+
+
+def set_npc_owner(nick):
+ global npc_owner
+ # if plugins.npc.npc_id < 0:
+ npc_owner = nick
+
+
+@extends('smsg_being_remove')
+def bot_dies(data):
+ if data.id == charserv.server.account:
+ mapserv.cmsg_player_respawn()
+
+
+@extends('smsg_player_chat')
+def player_chat(data):
+ if not npc_owner:
+ return
+
+ whisper(npc_owner, data.message)
+
+
+@extends('smsg_npc_message')
+@extends('smsg_npc_choice')
+@extends('smsg_npc_close')
+@extends('smsg_npc_next')
+@extends('smsg_npc_int_input')
+@extends('smsg_npc_str_input')
+def npc_activity(data):
+ npcdialog['start_time'] = time.time()
+
+
+@extends('smsg_npc_message')
+def npc_message(data):
+ if not npc_owner:
+ return
+
+ npc = mapserv.beings_cache.findName(data.id)
+ m = '[npc] {} : {}'.format(npc, data.message)
+ whisper(npc_owner, m)
+
+
+@extends('smsg_npc_choice')
+def npc_choice(data):
+ if not npc_owner:
+ return
+
+ choices = filter(lambda s: len(s.strip()) > 0,
+ data.select.split(':'))
+
+ whisper(npc_owner, '[npc][select] (use !input <number> to select)')
+ for i, s in enumerate(choices):
+ whisper(npc_owner, ' {}) {}'.format(i + 1, s))
+
+
+@extends('smsg_npc_int_input')
+@extends('smsg_npc_str_input')
+def npc_input(data):
+ if not npc_owner:
+ return
+
+ t = 'number'
+ if plugins.npc.input_type == 'str':
+ t = 'string'
+
+ whisper(npc_owner, '[npc][input] (use !input <{}>)'.format(t))
+
+
+@extends('smsg_storage_status')
+def storage_status(data):
+ global storage_is_open
+ storage_is_open = True
+ _times['storage'] = time.time()
+ if npc_owner:
+ whisper(npc_owner, '[storage][{}/{}]'.format(
+ data.used, data.max_size))
+
+
+@extends('smsg_storage_items')
+def storage_items(data):
+ if not npc_owner:
+ return
+
+ items_s = []
+ for item in data.storage:
+ s = itemdb.item_name(item.id, True)
+ if item.amount > 1:
+ s = str(item.amount) + ' ' + s
+ items_s.append(s)
+
+ for l in status.split_names(items_s):
+ whisper(npc_owner, l)
+
+
+@extends('smsg_storage_equip')
+def storage_equipment(data):
+ if not npc_owner:
+ return
+
+ items_s = []
+ for item in data.equipment:
+ s = itemdb.item_name(item.id, True)
+ items_s.append(s)
+
+ for l in status.split_names(items_s):
+ whisper(npc_owner, l)
+
+
+@extends('smsg_storage_close')
+def storage_close(data):
+ global storage_is_open
+ storage_is_open = False
+ _times['storage'] = 0
+
+
+@extends('smsg_player_arrow_message')
+def arrow_message(data):
+ if npc_owner:
+ if data.code == 0:
+ whisper(npc_owner, "Equip arrows")
+
+
+def cmd_where(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ msg = status.player_position()
+ whisper(nick, msg)
+
+
+def cmd_goto(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ try:
+ x = int(match.group(1))
+ y = int(match.group(2))
+ except ValueError:
+ return
+
+ set_npc_owner(nick)
+ plugins.autofollow.follow = ''
+ mapserv.cmsg_player_change_dest(x, y)
+
+
+def cmd_goclose(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+
+ x = mapserv.player_pos['x']
+ y = mapserv.player_pos['y']
+
+ if message.startswith('!left'):
+ x -= 1
+ elif message.startswith('!right'):
+ x += 1
+ elif message.startswith('!up'):
+ y -= 1
+ elif message.startswith('!down'):
+ y += 1
+
+ set_npc_owner(nick)
+ plugins.autofollow.follow = ''
+ mapserv.cmsg_player_change_dest(x, y)
+
+
+def cmd_pickup(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ commands.pickup()
+
+
+def cmd_drop(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+
+ try:
+ amount = int(match.group(1))
+ item_id = int(match.group(2))
+ except ValueError:
+ return
+
+ if nick not in admins:
+ if item_id not in allowed_drops:
+ return
+
+ index = get_item_index(item_id)
+ if index > 0:
+ mapserv.cmsg_player_inventory_drop(index, amount)
+
+
+def cmd_item_action(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ try:
+ itemId = int(match.group(1))
+ except ValueError:
+ return
+
+ index = get_item_index(itemId)
+ if index <= 0:
+ return
+
+ if message.startswith('!equip'):
+ mapserv.cmsg_player_equip(index)
+ elif message.startswith('!unequip'):
+ mapserv.cmsg_player_unequip(index)
+ elif message.startswith('!use'):
+ mapserv.cmsg_player_inventory_use(index, itemId)
+
+
+def cmd_emote(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ try:
+ emote = int(match.group(1))
+ except ValueError:
+ return
+
+ mapserv.cmsg_player_emote(emote)
+
+
+def cmd_attack(nick, message, is_whisper, match):
+# if not is_whisper:
+# return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ mapserv.cmsg_chat_message(random.choice(notattack_answers))
+ return
+
+ target_s = match.group(1)
+
+ try:
+ target = mapserv.beings_cache[int(target_s)]
+ except (ValueError, KeyError):
+ target = find_nearest_being(name=target_s,
+ ignored_ids=walkto.unreachable_ids)
+
+ if target in ignored_players:
+ return
+
+ if target is not None:
+ set_npc_owner(nick)
+ plugins.autofollow.follow = ''
+ if target_s=="Bee":
+ mapserv.cmsg_chat_message("Forget it " + nick + "!!!")
+ elif target_s=="Pink Flower":
+ mapserv.cmsg_chat_message("Yeah, I love those.")
+ elif target_s=="Squirrel":
+ mapserv.cmsg_chat_message("Die, you rodent!!!")
+ mapserv.cmsg_player_emote(5)
+ walkto.walkto_and_action(target, 'attack', mapserv.player_attack_range)
+ time.sleep(5)
+ mapserv.cmsg_chat_message("Go to squirrel's heaven.")
+ elif target_s in friends:
+ mapserv.cmsg_chat_message(random.choice(like_answers)+ " " + target_s + "!")
+ time.sleep(5)
+ mapserv.cmsg_player_emote(32)
+ else:
+ mapserv.cmsg_chat_message(random.choice(attack_answers))
+ time.sleep(1)
+ walkto.walkto_and_action(target, 'attack', mapserv.player_attack_range)
+ time.sleep(5)
+ mapserv.cmsg_chat_message(random.choice(attack_answers))
+ else:
+ mapserv.cmsg_chat_message(random.choice(noidea_answers))
+
+def cmd_come(nick, message, is_whisper, match):
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ mapserv.cmsg_chat_message(random.choice(notattack_answers))
+ return
+
+ target_s = match.group(1)
+
+ try:
+ target = mapserv.beings_cache[int(nick)]
+ except (ValueError, KeyError):
+ target = find_nearest_being(name=nick,
+ ignored_ids=walkto.unreachable_ids)
+
+ if target is not None:
+ set_npc_owner(nick)
+ plugins.autofollow.follow = ''
+ walkto.walkto_and_action(target, '', mapserv.player_attack_range)
+ mapserv.cmsg_chat_message(random.choice(attack_answers))
+ else:
+ mapserv.cmsg_chat_message(random.choice(noidea_answers))
+
+def say_explain(nick, msg, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+
+ if msg.split(' ',1)[1].lower() in explain_sentences:
+ mapserv.cmsg_chat_message(explain_sentences[msg.split(' ',1)[1].lower()])
+ mapserv.cmsg_player_emote(3)
+ else:
+ mapserv.cmsg_chat_message(random.choice(noidea_answers))
+# mapserv.cmsg_chat_message(msg.split(' ',1)[1].lower())
+
+def say_think(nick, msg, is_whisper, match):
+ if is_whisper:
+ return
+
+ if nick in ignored_players:
+ return
+ random_weight = random.randint(0, 2)
+ if random_weight == 0:
+ mapserv.cmsg_chat_message(random.choice(noidea_answers))
+ if random_weight == 1:
+ mapserv.cmsg_chat_message("Maybe " + nick + " " + random.choice(hurt_actions) + " " + msg.split(' ')[-1][:-1]+"?")
+ if random_weight == 2:
+ mapserv.cmsg_chat_message(nick + " I have to check the wiki.")
+# mapserv.cmsg_chat_message(msg.split(' ')[-1][:-1])
+
+def make_story(self):
+ return "asd"
+
+def say_story(nick, msg, is_whisper, match):
+ if nick in ignored_players:
+ return
+ # ~ random_weight = random.randint(0, 2)
+ # ~ if random_weight == 0:
+ # ~ mapserv.cmsg_chat_message(random.choice(noidea_answers))
+ # ~ if random_weight == 1:
+ # ~ mapserv.cmsg_chat_message("Maybe " + nick + " " + random.choice(hurt_actions) + " " + msg.split(' ')[-1][:-1]+"?")
+ # ~ if random_weight == 2:
+ # ~ mapserv.cmsg_chat_message(nick + " I have to check the wiki.")
+ players = []
+ for being in mapserv.beings_cache.itervalues():
+ if ((being.type == 'player' or being.type == 'npc') and len(being.name) > 1):
+ players.append(being.name)
+ monsters = ["monster"]
+ for being in mapserv.beings_cache.itervalues():
+ if being.type == 'monster' and len(being.name) > 1:
+ monsters.append(being.name)
+ mapserv.cmsg_chat_message(random.choice(story_introductions) + " " + random.choice(players) + " to " + random.choice(hurt_actions) + " a " + random.choice(monsters) + " with " + random.choice(drop_items) + " but " + random.choice(story_action_fail) +" and said: \"" + random.choice(pain_answers) + "\". Then the " + random.choice(monsters) + " said: \"" + random.choice(noidea_answers) + "\". But " + random.choice(players) +" replied: \"" + random.choice(attack_answers) + "\"")
+ #mapserv.cmsg_chat_message()
+
+# Doesn't work.
+def cmd_say(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ set_npc_owner(nick)
+ msg = message.group(1)
+ mapserv.cmsg_chat_message(msg)
+
+
+def cmd_sit(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ plugins.autofollow.follow = ''
+ mapserv.cmsg_player_change_act(0, 2)
+
+
+def cmd_turn(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ commands.set_direction('', message[6:])
+
+
+def cmd_follow(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ if plugins.autofollow.follow == nick:
+ plugins.autofollow.follow = ''
+ else:
+ set_npc_owner(nick)
+ plugins.autofollow.follow = nick
+
+
+def cmd_lvlup(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ stat = match.group(1).lower()
+ stats = {'str': 13, 'agi': 14, 'vit': 15,
+ 'int': 16, 'dex': 17, 'luk': 18}
+
+ skills = {'mallard': 45, 'brawling': 350, 'speed': 352,
+ 'astral': 354, 'raging': 355, 'resist': 353}
+
+ if stat in stats:
+ mapserv.cmsg_stat_update_request(stats[stat], 1)
+ elif stat in skills:
+ mapserv.cmsg_skill_levelup_request(skills[stat])
+
+#FIXME it fails: leads bot to spam
+def cmd_invlist(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ ls = status.invlists(50)
+ for l in ls:
+ whisper(nick, l)
+ time.delay(2)
+
+#FIXME it fails
+def cmd_inventory(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ ls = status.invlists2(255)
+ for l in ls:
+ whisper(nick, l)
+ time.delay(2)
+
+
+def cmd_status(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ all_stats = ('stats', 'hpmp', 'weight', 'points',
+ 'zeny', 'attack', 'skills')
+
+ sr = status.stats_repr(*all_stats)
+ whisper(nick, ' | '.join(sr.values()))
+
+
+def cmd_zeny(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ whisper(nick, 'I have {} GP'.format(mapserv.player_stats[stats.MONEY]))
+
+
+def cmd_nearby(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ btype = message[8:]
+ if btype.endswith('s'):
+ btype = btype[:-1]
+
+ ls = status.nearby(btype)
+ for l in ls:
+ whisper(nick, l)
+
+
+def cmd_talk2npc(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ npc_s = match.group(1).strip()
+ jobs = []
+ name = ''
+ try:
+ jobs = [int(npc_s)]
+ except ValueError:
+ name = npc_s
+
+ b = find_nearest_being(name=name, type='npc', allowed_jobs=jobs)
+ if b is None:
+ whisper(nick, '[error] NPC not found: {}'.format(npc_s))
+ return
+
+ set_npc_owner(nick)
+ plugins.autofollow.follow = ''
+ plugins.npc.npc_id = b.id
+ mapserv.cmsg_npc_talk(b.id)
+
+
+def cmd_input(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ plugins.npc.cmd_npcinput('', match.group(1))
+
+
+def cmd_close(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ if storage_is_open:
+ reset_storage()
+ else:
+ plugins.npc.cmd_npcclose()
+
+
+def cmd_history(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ for user, cmd in history:
+ whisper(nick, '{} : {}'.format(user, cmd))
+
+
+def cmd_store(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ if not storage_is_open:
+ return
+
+ try:
+ amount = int(match.group(1))
+ item_id = int(match.group(2))
+ except ValueError:
+ return
+
+ index = get_item_index(item_id)
+ if index > 0:
+ mapserv.cmsg_move_to_storage(index, amount)
+
+
+def cmd_retrieve(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ if nick not in admins:
+ return
+ if not storage_is_open:
+ return
+
+ try:
+ amount = int(match.group(1))
+ item_id = int(match.group(2))
+ except ValueError:
+ return
+
+ index = get_storage_index(item_id)
+ if index > 0:
+ mapserv.cmsg_move_from_storage(index, amount)
+
+
+def cmd_sell(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+ try:
+ amount = int(match.group(1))
+ item_id = int(match.group(2))
+ npc_s = match.group(3).strip()
+ except ValueError:
+ return
+
+ if item_id not in allowed_sells:
+ return
+
+ index = get_item_index(item_id)
+ if index < 0:
+ return
+
+ jobs = []
+ name = ''
+ try:
+ jobs = [int(npc_s)]
+ except ValueError:
+ name = npc_s
+
+ b = find_nearest_being(name=name, type='npc', allowed_jobs=jobs)
+ if b is None:
+ return
+
+ mapserv.cmsg_npc_buy_sell_request(b.id, 1)
+ mapserv.cmsg_npc_sell_request(index, amount)
+
+
+def cmd_help(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+
+ m = ('[@@https://forums.themanaworld.org/viewtopic.php?f=12&t=19673|Forum@@]'
+ '[@@https://bitbucket.org/rumly111/manachat|Sources@@] '
+ 'Try !commands for list of commands')
+ whisper(nick, m)
+
+
+def cmd_commands(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+
+ c = []
+ for cmd in manaboy_commands:
+ if cmd.startswith('!('):
+ br = cmd.index(')')
+ c.extend(cmd[2:br].split('|'))
+ elif cmd.startswith('!'):
+ c.append(cmd[1:].split()[0])
+
+ c.sort()
+ whisper(nick, ', '.join(c))
+
+
+def cmd_report_bug(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+
+ bug_s = match.group(1)
+ bugs.append((nick, bug_s))
+ whisper(nick, 'Thank you for your bug report')
+
+
+def cmd_check_bugs(nick, message, is_whisper, match):
+ if not is_whisper:
+ return
+ if nick in ignored_players:
+ return
+
+ if nick not in admins:
+ return
+
+ for user, bug in bugs:
+ whisper(nick, '{} : {}'.format(user, bug))
+
+ bugs.clear()
+
+
+def reset_storage():
+ mapserv.cmsg_storage_close()
+ mapserv.cmsg_npc_list_choice(plugins.npc.npc_id, 6)
+
+
+# =========================================================================
+def manaboy_logic(ts):
+
+ def reset():
+ global npc_owner
+ npc_owner = ''
+ npcdialog['start_time'] = -1
+ plugins.npc.cmd_npcinput('', '6')
+ # plugins.npc.cmd_npcclose()
+
+ if storage_is_open and ts > _times['storage'] + 150:
+ reset_storage()
+
+ if npcdialog['start_time'] <= 0:
+ return
+
+ if not storage_is_open and ts > npcdialog['start_time'] + 30.0:
+ reset()
+
+# =========================================================================
+manaboy_commands = {
+ '!where' : cmd_where,
+ '!goto (\d+) (\d+)' : cmd_goto,
+ '!(left|right|up|down)' : cmd_goclose,
+ '!pickup' : cmd_pickup,
+ '!drop (\d+) (\d+)' : cmd_drop,
+ '!equip (\d+)' : cmd_item_action,
+ '!unequip (\d+)' : cmd_item_action,
+ '!use (\d+)' : cmd_item_action,
+ '!emote (\d+)' : cmd_emote,
+ '!attack (.+)' : cmd_attack,
+ '!say ((@|#).+)' : cmd_say,
+ '!sit' : cmd_sit,
+ '!turn' : cmd_turn,
+ '!follow' : cmd_follow,
+ '!lvlup (\w+)' : cmd_lvlup,
+ '!inventory' : cmd_inventory,
+ '!invlist' : cmd_invlist,
+ '!status' : cmd_status,
+ '!zeny' : cmd_zeny,
+ '!nearby' : cmd_nearby,
+ '!talk2npc (.+)' : cmd_talk2npc,
+ '!input (.+)' : cmd_input,
+ '!close' : cmd_close,
+ '!store (\d+) (\d+)' : cmd_store,
+ '!retrieve (\d+) (\d+)' : cmd_retrieve,
+ '!sell (\d+) (\d+) (.+)' : cmd_sell,
+ '!(help|info)' : cmd_help,
+ '!commands' : cmd_commands,
+ '!history' : cmd_history,
+ '!bug (.+)' : cmd_report_bug,
+ '!bugs' : cmd_check_bugs,
+ '!xcon' : XCOMEnable,
+ '!xcom' : XCOMEnable,
+ '!xcoff' : XCOMDisable,
+ '!xcom off' : XCOMDisable,
+ '!xclist' : XCOMOnlineList,
+ '!xci (.*)' : XCOMInvite,
+ '!xcsi (.*)' : XCOMSilentInvite,
+ '!xcb (.*)' : XCOMBan,
+ '!xcu (.*)' : XCOMUnBan,
+ '!xcsion' : XCOMServerInterestEnable,
+ '!xcsioff' : XCOMServerInterestDisable,
+ r'(.*)' : XCOMCommunicate,
+ r'^(?i)explain (.*)': say_explain,
+ r'^(?i)(hello|hi|hey|heya|hiya|yo) (?i)(livio|liviobot)' : say_greeting,
+ r'^(?i)(hello|hi|hey|heya|hiya) (?i)(all|everybody|everyone)(.*)' : say_greeting,
+ r'\*(?i)?((shake|kick)s?) (?i)(livio|liviobot)' : drop_on_head,
+ r'\*(?i)?(bye|cya|gtg)' : say_goodbye,
+ r'(?i)(die|go away|\*?((nuke|kill)s?)) (?i)(livio|liviobot)' : answer_threat,
+ r'^(?i)(livio|liviobot) (?i)Will (.*)' : noidea_answers,
+ r'^(?i)heal me([ ,]{1,2})(livio|liviobot)' : healme_answers,
+ r'^(?i)(who|what) are you([ ,]{1,3})(livio|liviobot)' : whoami_answers,
+ r'^!additem (.*)' : admin_additem,
+ r'^!addjoke (.*)' : admin_addjoke,
+ r'\*(?i)?(burn(s?)) (livio|liviobot)' : burn_answers,
+ r'\*(?i)?(come) (livio|liviobot)' : cmd_come,
+ r'\*(?i)?(' + '|'.join(hurt_actions) + ')s?(?i)(livio|liviobot)' : pain_answers,
+ r'^(?i)what do you think about(.*)' : say_think,
+ '!story': say_story,
+ '!joke' : joke_answers,
+}
+
+
+def chatbot_answer_mod(func):
+ '''modifies chatbot.answer to remember last 10 commands'''
+
+ def mb_answer(nick, message, is_whisper):
+ if is_whisper:
+ history.append((nick, message))
+ return func(nick, message, is_whisper)
+
+ return mb_answer
+
+def init(config):
+
+ online_users.start()
+
+ for cmd, action in manaboy_commands.items():
+ plugins.chatbot.add_command(cmd, action)
+ plugins.chatbot.answer = chatbot_answer_mod(plugins.chatbot.answer)
+
+ logicmanager.logic_manager.add_logic(manaboy_logic)