diff options
Diffstat (limited to 'plugins/manaboy.py')
-rw-r--r-- | plugins/manaboy.py | 1390 |
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) |