#! /usr/bin/env python## Copyright (C) 2009 by Filip Brcic <brcha@gna.org>## eRepublik bot using python irclib## This program is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>.#from ircbot import SingleServerIRCBotfrom irclib import nm_to_n, nm_to_h, irc_lower, ip_numstr_to_quad, ip_quad_to_numstr, is_channelfrom eRepublik import Citizenfrom time import time, sleep, ctimeimport shelvefrom cStringIO import StringIOfrom pprint import pprintfrom math import floorclass ERepBot(SingleServerIRCBot): def __init__(self, db, channels, nickname, server, port=6667): SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) self.initial_channels = channels self.stfu_channels = [] self.user_req_times = dict() self.measured_time = 60 # seconds = 1 minute self.time_quota = 20 # reqs in measured_time self.banned_users = [ 'gloryvts', 'v_force', 'bokee88' ] self.authorized = [ 'gojko_bozic', 'shumor', 'aexil_kong', 'kuda_kako', 'pegica1', 'hostilian', 'desert_hamster', ] self.db = db def on_nicknameinuse(self, c, e): c.nick(c.get_nickname() + "_") def on_welcome(self, c, e): # Identify with the server c.privmsg('NickServ', 'identify qwerty') # Wait for identification to be actualized sleep(1) # 1 seconds for ch in self.initial_channels: c.join('#' + ch) def on_privmsg(self, c, e): self.do_command(e, e.arguments()[0]) def on_pubmsg(self, c, e): a = e.arguments()[0].split(":", 1) if len(a) > 1 and irc_lower(a[0]) == irc_lower(self.connection.get_nickname()): self.do_command(e, a[1].strip()) elif e.arguments()[0].startswith('!'): self.do_command(e, e.arguments()[0]) return def on_dccmsg(self, c, e): c.privmsg("You said: " + e.arguments()[0]) def on_dccchat(self, c, e): if len(e.arguments()) != 2: return args = e.arguments()[1].split() if len(args) == 4: try: address = ip_numstr_to_quad(args[2]) port = int(args[3]) except ValueError: return self.dcc_connect(address, port) def do_command(self, e, cmd): nick = nm_to_n(e.source()) c = self.connection t = e.target() if not is_channel(t): t = nick # Implement quota here current_time = time() if self.user_req_times.has_key(nick): self.user_req_times[nick] = \ filter(lambda x: current_time - x > self.measured_time, self.user_req_times[nick]) if len(self.user_req_times[nick]) > self.time_quota:# c.notice(nick, 'Cool down, you are over quota.') if not nick.lower().startswith('hostilian'): c.notice(nick, 'Prekoracio si kvotu') return else: self.user_req_times[nick] = [] self.user_req_times[nick].append(current_time) if nick.lower() in self.banned_users: c.notice(nick, 'Banovan si i ne mozes vise da koristis Domara.') return if cmd == "disconnect" and nick.lower().startswith('hostilian'): self.disconnect() elif cmd == "die" and nick.lower().startswith('hostilian'): self.die() elif cmd == 'stfu' and nick.lower().startswith('hostilian') and is_channel(t): if not t in self.stfu_channels: self.stfu_channels.append(t) elif cmd == 'speak' and nick.lower().startswith('hostilian') and is_channel(t): if t in self.stfu_channels: self.stfu_channels.remove(t) elif is_channel(t) and t in self.stfu_channels: return elif cmd == "stats": for chname, chobj in self.channels.items(): c.notice(nick, "--- Channel statistics ---") c.notice(nick, "Channel: " + chname) users = chobj.users() users.sort() c.notice(nick, "Users: " + ", ".join(users)) opers = chobj.opers() opers.sort() c.notice(nick, "Opers: " + ", ".join(opers)) voiced = chobj.voiced() voiced.sort() c.notice(nick, "Voiced: " + ", ".join(voiced)) elif cmd.startswith('!s '): user = cmd.split(' ')[1].strip() chans = [] for chname, chobj in self.channels.items(): if user.lower() in [ x.lower() for x in chobj.users() ]: chans.append(chname) if len(chans) == 0: c.privmsg(t, 'I have no idea where ' + user + ' is right now :(') else: c.privmsg(t, user + ' is currently on channels: ' + ' , '.join(chans)) elif cmd.startswith('join'): c.join(cmd.split(' ')[1]) elif cmd.startswith('info') or cmd.startswith('!info'): name = ' '.join(cmd.split(' ')[1:]) cit = Citizen().loadByName(name) if cit == None: cit = Citizen().loadById(name) if cit == None: c.privmsg(t, 'Citizen "' + name + '" doesn\'t exist!') return c.privmsg(t, cit.toString()) elif cmd.startswith('fight') or cmd.startswith('!fight'): name = ' '.join(cmd.split(' ')[1:]) if name.lower() == 'vukovi': # racunaj udar vukova total_cur = [0,0,0,0,0,0] total_max = [0,0,0,0,0,0] cit = Citizen() for vuk_name in self.db['vukovi']: vuk = self.db[vuk_name] wellness = vuk['wellness'] strength = vuk['strength'] rankAsNumber = vuk['rankAsNumber'] fights = int(floor((wellness - 40) / 10)) for f in range(fights): current = cit.fightCalc(wellness=wellness, rankAsNumber=rankAsNumber, strength=strength) wellness -= 10 for i in range(6): total_cur[i] += current[i] wellness = 100 for f in range(5): current = cit.fightCalc(wellness=wellness, rankAsNumber=rankAsNumber, strength=strength) wellness -= 10 for i in range(6): total_max[i] += current[i] res = '' for i in range(6): res += 'Q%s: %s, ' % (str(i), str(total_cur[i])) c.privmsg(t, 'Vukovi (cur.well): ' + res[:-2]) res = '' for i in range(6): res += 'Q%s: %s, ' % (str(i), str(total_max[i])) c.privmsg(t, 'Vukovi (100%): ' + res[:-2]) return cit = Citizen().loadByName(name) if cit == None: cit = Citizen().loadById(name) if cit == None: c.privmsg(t, nick + ', citizen "' + name + '" doesn\'t exist!') return c.privmsg(t, (cit.getName() + ' at ' + str(cit.getWellness()) + '%: ' + str(cit.fightCalcStr(cit.getWellness())))) c.privmsg(t, (cit.getName() + ' at 100.0%: ' + str(cit.fightCalcStr(100.0)))) elif cmd.startswith('link') or cmd.startswith('!link'): name = ' '.join(cmd.split(' ')[1:]) cit = Citizen().loadByName(name) if cit == None: cit = Citizen().loadById(name) if cit == None: c.privmsg(t, nick + ', citizen "' + name + '" doesn\'t exist!') return c.privmsg(t, ('http://www.erepublik.com/en/citizen/profile/' + str(cit.getId()))) elif cmd.startswith('donate') or cmd.startswith('!donate'): name = ' '.join(cmd.split(' ')[1:]) cit = Citizen().loadByName(name) if cit == None: cit = Citizen().loadById(name) if cit == None: c.privmsg(t, nick + ', citizen "' + name + '" doesn\'t exist!') return c.privmsg(t, ('http://www.erepublik.com/en/citizen/donate/items/' + str(cit.getId()))) elif cmd.startswith('manu') or cmd.startswith('!manu'): if t.lower() != '#vukovi': return manu = [ # 'http://www.erepublik.com/en/company/pavicevic-weapon-202709', # 'http://www.erepublik.com/en/company/pistolji-na-vodu-2-198907', 'http://www.erepublik.com/en/company/pistolji-na-vodu-197483 (Q5)', 'Rad u Q5 je obavezan, nakon rada se javiti nekome da evidentira', 'neko = {kuda kako, gojko bozic, aexil, pegica, kukee, shumor}', ] map(lambda x: c.privmsg(t, x), manu) elif cmd.startswith('land') or cmd.startswith('!land'): if t.lower() != '#vukovi': return land = [ 'http://www.erepublik.com/en/company/valjevska-pivara-198739', 'http://www.erepublik.com/en/company/iron-q4-2-lic-high-194682', ] map(lambda x: c.privmsg(t, x), land) elif cmd == '!naredjenje' and t.lower() == '#vukovi': c.privmsg(t, 'Naredjenje je: ' + self.db['naredjenje']) elif cmd.startswith('setnaredjenje'): if nick.lower() in self.authorized: self.db['naredjenje'] = cmd.replace('setnaredjenje ', '').strip() elif cmd.startswith('!slap'): c.notice(t, 'slaps ' + cmd.replace('!slap ', '')) elif cmd.startswith('!lick'): c.notice(t, 'licks ' + cmd.replace('!lick ', '')) elif cmd.startswith('!add'): if nick.lower() in self.authorized: who = cmd.replace('!add ', '') cit = Citizen().loadByName(who) if cit == None: cit = Citizen().loadById(who) if cit == None: c.privmsg(t, 'Citizen "' + who + '" doesn\'t exist!') return if cit.getName() in self.db['vukovi']: c.privmsg(t, cit.getName() + ' je vec u Vukovima!') return self.db[cit.getName()] = cit.toDict() vukovi = self.db['vukovi'] vukovi.append(cit.getName()) self.db['vukovi'] = vukovi c.privmsg(t, cit.getName() + ' je dodat u Vukove.') elif cmd.startswith('!del'): if nick.lower() in self.authorized: who = cmd.replace('!del ', '') cit = Citizen().loadByName(who) if cit == None: cit = Citizen().loadById(who) if cit == None: c.privmsg(t, 'Citizen "' + name + '" doesn\'t exist!') return if cit.getName() in self.db['vukovi']: del self.db[cit.getName()] vukovi = self.db['vukovi'] vukovi.remove(cit.getName()) self.db['vukovi'] = vukovi c.privmsg(t, cit.getName() + ' je izbacen iz Vukova.') else: c.privmsg(t, cit.getName() + ' nije u Vukovima!') elif cmd == '!update': if nick.lower() in self.authorized: dmgSinceLastUpdate = dict() for name in self.db['vukovi']: cit_old = self.db[name] cit = Citizen().loadByName(name) dmgSinceLastUpdate[name] = cit.getDamage() - cit_old['damage'] self.db[name] = cit.toDict() last_update = self.db['last_update'] self.db['last_update'] = time() c.privmsg(t, 'Od ' + ctime(last_update) + ' do sada su napravljeni sledeci dmg-ovi:') stream = StringIO() pprint(dmgSinceLastUpdate, stream=stream, width=70) stream.reset() out = stream.readlines() for line in out: c.privmsg(t, line) totalDmg = sum(dmgSinceLastUpdate.values()) c.privmsg(t, 'Ukupni dmg od ' + ctime(last_update) + ' je ' + str(totalDmg)) self.db['totalDmg'] = totalDmg elif cmd == '!vukovidmg': if t.lower() == '#vukovi': c.privmsg(t, 'Vukovi su juce napravili ' + str(self.db['totalDmg']) + ' dmg')def main(): import sys if len(sys.argv) < 4: print 'Usage: erepbot <server[:port]> <nickname> <channel> [<channel>+]' sys.exit(1) s = sys.argv[1].split(":", 1) server = s[0] if len(s) == 2: try: port = int(s[1]) except ValueError: print "Error: Erroneous port." sys.exit(1) else: port = 6667 nickname = sys.argv[2] channels = sys.argv[3:] db = shelve.open('vukovi.db') bot = ERepBot(db, channels, nickname, server, port) try: bot.start() finally: db.close()if __name__ == "__main__": main()