Advertisement
Guest User

KekettesBot Source

a guest
Jun 20th, 2017
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.46 KB | None | 0 0
  1. """
  2. subscribers - tier 1 1000, tier 2 2500 tier 3 5000 / semaine
  3. DONE !gamble X : d100 50 -> x/2 gagnés
  4. !versus
  5. !contest
  6. DONE !makeitrain
  7. DONE !doubletrouble
  8. DONE !kekettes pour voir les kekettes
  9. cheer = 1000 points par 100 bits
  10. !addquote
  11. !quotelist
  12.  
  13.  
  14. pseudo 1: !vs "pseudo2" "montant"
  15. bot: pseudo2 vous êtes challengé par "pseudo1"
  16. pseudo2: !vs pseudo1 "montant"
  17. plus on parie plus on a de chances de gagner base montant1=montant2 : 50/50
  18. montant1/(montant1+2)*100 %
  19. """
  20.  
  21. import socket
  22. import twitch
  23. from twitch import TwitchClient
  24. from twitch.api.streams import Streams
  25. import csv
  26. from datetime import datetime
  27. import time
  28. from threading import Thread, RLock
  29. import random as rd
  30. import math
  31.  
  32. lock = RLock()
  33.  
  34. BOT_HAS_STARTED = "KekettesBot is now running !"
  35. NOT_ENOUGH_POINTS = "User {} has not enough kekettes to perform this action."
  36. DISPLAY_POINTS = "User {} has {} kekettes"
  37. USER_CHALLENGED_YOU = "{0}, user {1} has challenged you ! Type !vs {1} *amount* to accept."
  38. DISPLAY_CHALLENGE_ODDS = "{0} has put {1} on the table. {2} has put {3} on the table. {0} has {4}% chances of winning !"
  39. VS_WIN = "You won your duel versus {0}, you win {} kekettes."
  40. VS_LOST = "You lost your duel versus {0}, you lose {} kekettes."
  41. GAMBLE_WON = "{} rolled {} and thus has won {} kekettes !"
  42. GAMBLE_LOST = "{} rolled {} and thus has lost {} kekettes !"
  43. VALUE_ERROR_EXCEPTION = "You entered an incorrect value."
  44. BOT_LEAVING_CHAT = "KekettesBot has left the chat room, goodbye!"
  45. MADE_IT_RAIN = "Woohoo, {} made it rain !"
  46. DOUBLE_TROUBLE_STARTED = "{} has requested double points ! Everyone gets double for 10 minutes !"
  47. DOUBLE_TROUBLE_ENDED = "Double trouble has ended !"
  48. HELP_MESSAGE = "Available Commands: {}"
  49. SOURCE_CODE_MESSAGE = "Here's the source code for this bot : <link>"
  50.  
  51. QUOTES = []
  52. with open("quotes.txt", "r") as f:
  53.     for line in f:
  54.         QUOTES.append(line.rstrip("\n"))
  55.  
  56. next_call = time.time()
  57.  
  58. def sourcecode(users, text, user):
  59.     return
  60.  
  61. def quote(users, text, user):
  62.     return rd.choice(QUOTES), users
  63.  
  64. def denisbrogniart(users, text, user):
  65.     return "HA !", users
  66.  
  67. def helpkekettes(users, text, user):
  68.     return HELP_MESSAGE, users
  69.  
  70. def kekettes(users, text, user):
  71.     return DISPLAY_POINTS.format(user.username.capitalize(), user.current), users
  72.     pass
  73.  
  74. def gamble(users, text, user):
  75.     balance = user.current
  76.     try:
  77.         message = text.split(":")[-1]
  78.         gmbl = message.split()[-1]
  79.         gmbl = int(gmbl)
  80.     except ValueError:
  81.         return VALUE_ERROR_EXCEPTION, users
  82.     if user.may_perform_action(gmbl):
  83.         user.add_points(-gmbl)
  84.     else:
  85.         return NOT_ENOUGH_POINTS.format(user.username.capitalize()), users
  86.     rng = rd.randint(1, 100)
  87.     if rng <50:
  88.         return GAMBLE_LOST.format(user.username.capitalize(), rng, gmbl), users
  89.     else:
  90.         winnings = gmbl*(math.ceil((rng-50)/50*4)+1)
  91.         user.add_points(winnings)
  92.         return GAMBLE_WON.format(user.username.capitalize(), rng, winnings-gmbl), users
  93.     pass
  94.  
  95. def doubletrouble(users, text, user):
  96.     username = username = text.split(":")[1].split("!")[0]
  97.     now = datetime.now().time()
  98.     then = addSecs(now, 600)
  99.     if user.may_perform_action(2000):
  100.         user.add_points(-2000)
  101.     else:
  102.         return NOT_ENOUGH_POINTS.format(user.username.capitalize()), users
  103.     return (then, DOUBLE_TROUBLE_STARTED.format(user.username.capitalize())), users
  104.     pass
  105.  
  106. def versus(users, text, user):
  107.     pass
  108.  
  109. def makeitrain(users, text, user):
  110.     if user.may_perform_action(3000):
  111.         user.add_points(-3000)
  112.     else:
  113.         return NOT_ENOUGH_POINTS.format(user.username.capitalize()), users
  114.     for u in users:
  115.         u.add_points(30)
  116.     return MADE_IT_RAIN.format(user.username.capitalize()), users
  117.     pass
  118.  
  119. def addSecs(tm, secs):
  120.     fulldate = datetime.datetime(100, 1, 1, tm.hour, tm.minute, tm.second)
  121.     fulldate = fulldate + datetime.timedelta(seconds=secs)
  122.     return fulldate.time()
  123.  
  124. class User():
  125.     def __init__(self, row):
  126.         self.fieldnames = ['username', 'user_id', 'current', 'all_time']
  127.         self.row = row
  128.         self._username = row["username"]
  129.         self._user_id = int(row["user_id"])
  130.         self._current = int(row["current"])
  131.         self._all_time = int(row['all_time'])
  132.        
  133.     def _get_username(self):
  134.         return self._username
  135.     def _set_username(self, new_username):
  136.         self._username = str(new_username)
  137.     def _get_user_id(self):
  138.         return self._user_id
  139.     def _set_user_id(self, id_):
  140.         self._user_id = id_
  141.     def _get_current(self):
  142.         return self._current
  143.     def _set_current(self, new_current):
  144.         delta = int(self._all_time) - int(new_current)
  145.         if delta >0:
  146.             self._all_time = int(self._all_time) + int(delta)
  147.         self._current = int(new_current)
  148.     def _get_all_time(self):
  149.         return int(self._all_time)
  150.     def _set_all_time(self, new_all_time):
  151.         self._all_time = int(new_all_time)
  152.     username = property(_get_username, _set_username)
  153.     user_id = property(_get_user_id, _set_user_id)
  154.     current = property(_get_current, _set_current)
  155.     all_time = property(_get_all_time, _set_all_time)
  156.    
  157.     def add_points(self, points_to_add):
  158.         self.current += points_to_add
  159.     def may_perform_action(self, cost):
  160.         return self.current-cost >=0
  161.     def __repr__(self):
  162.         return "{}:{}, {}/{}".format(self.username, self.user_id, self.current, self.all_time)
  163.  
  164. class KeketteBot(Thread):
  165.     def __init__(self, commands):
  166.         Thread.__init__(self)
  167.         self.stop = False
  168.         #CONFIG
  169.         self.channel_name = 'misterteamot'
  170.         self.channel_oauth = '<redacted>' #teamot oauth
  171.         self.max_messages = 100 #/30 sec
  172.         self.max_joins = 50 #/15 sec
  173.         self.base_drop_rate = 2 #per minute
  174.         self.points_multiplier = 1
  175.         self.csv_filename = "points.csv"
  176.         #IRC CONFIG
  177.         self.server = 'irc.chat.twitch.tv'
  178.         self.port = 6667
  179.         self.nickname = 'kekettesbot'
  180.         self.password = '<redacted>' #oauth token for the bot
  181.         self.commands = commands
  182.         self.given_to_subs = False
  183.         self.end_doubletrouble = datetime.now().time()
  184.         self.doubletroublechanged = False
  185.         self.time_start_daemon = time.time()
  186.         self.points_not_given = True
  187.         self.joined_users = []
  188.        
  189.         #Loader for csv data
  190.         fields = ['username', 'user_id', 'current', 'all_time']
  191.         #self.users = {'username':[], 'user_id':[], 'current':[], 'all_time':[]}
  192.         self.users = []
  193.         with open(self.csv_filename, "r") as csvfile:
  194.             reader = csv.DictReader(csvfile, fieldnames=fields)
  195.             i = 0
  196.             for row in reader:
  197.                 i+=1
  198.                 if i>1:
  199.                     self.users.append(User(row))
  200.                     #for f in fields:
  201.                     #   self.users[f].append(row[f])
  202.         print(self.users)
  203.         #IRC STUFF
  204.         self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #defines the socket
  205.         # Connect
  206.         #self.irc.bind((self.server, self.port))
  207.         self.irc.connect((self.server, self.port))
  208.         self.irc.setblocking(False)
  209.         self.irc.send("PASS {}\n".format(self.password).encode())
  210.         self.irc.send("NICK {}\n".format(self.nickname).encode())
  211.         self.irc.send("JOIN #{}\n".format(self.channel_name).encode())
  212.         self.irc.send("PRIVMSG #{} :{}\n".format(self.channel_name, BOT_HAS_STARTED).encode())
  213.         self.irc.send("CAP REQ :twitch.tv/membership\n".encode())
  214.         self.irc.send("CAP REQ :twitch.tv/tags\n".encode())
  215.         #TWITCH API STUFF
  216.         self.client_id = 'iaqh3hzv031qgn4182ardxfaeqiyzt'
  217.         self.client = TwitchClient(self.client_id, self.channel_oauth)
  218.         #self.channel = self.client.channels.get()
  219.         current_offset = 0
  220.         self.subscribers = []
  221.         self.subscribers_twitch = []
  222.         #while self.client.channels.get_subscribers(self.channel._id, limit=100, offset=current_offset):
  223.         #   self.subscribers.extend(self.client.channels.get_subscribers(self.channel_oauth, limit=100, offset=current_offset))
  224.         #   current_offset += 100
  225.    
  226.     def run(self):
  227.         while not self.stop:
  228.             with lock:
  229.                 if datetime.now().time() > self.end_doubletrouble and self.doubletroublechanged:
  230.                     self.points_multiplier = 1
  231.                     self.irc.send('PRIVMSG #{} :{}\n'.format(self.channel_name, DOUBLE_TROUBLE_ENDED).encode())
  232.                     self.doubletroublechanged = False
  233.                 if int(time.time()-self.time_start_daemon)%120==0 and self.points_not_given:#datetime.now().minute%2 == 0 and datetime.now().second == 1: #donne des kekettes toutes les 2 minutes
  234.                     self.points_not_given = False
  235.                     for user in self.joined_users: #TODO: les viewers qui n'ont pas encore de kekettes (les nouveaux)
  236.                         user.add_points(self.base_drop_rate*self.points_multiplier)
  237.                         """index = self.users["user_id"].index(self.joined_users[i][1])
  238.                         current = self.users["current"][index]
  239.                         current = int(current)
  240.                         current += self.base_drop_rate * self.points_multiplier
  241.                         self.users["current"][index] = str(current)"""
  242.                 if not self.points_not_given and int(time.time()-self.time_start_daemon)%121==0:
  243.                     self.points_not_given = True
  244.                 if datetime.now().weekday() == 0 and not self.given_to_subs: #Monday #Donne 1000 kekettes aux subs par semaine
  245.                     self.given_to_subs = True
  246.                     for sub in self.subscribers:
  247.                         sub.add_points(1000)
  248.                         #i = self.users["user_id"].index(str(sub.id_))
  249.                         #self.users["current"][i] += 1000
  250.                 try:
  251.                     text=self.irc.recv(4096).decode()
  252.                     print(text)
  253.                     # Prevent Timeout
  254.                     if text.find('PING') != -1:
  255.                         self.irc.send('PONG {}\r\n'.format(text.split()[1]).encode())
  256.                         print('PONG {}\r\n'.format(text.split()[1]))
  257.                     elif text.find("JOIN") != -1:
  258.                         username = text[:1].split("!")[0]
  259.                         user_id = str(self.client.users.translate_usernames_to_ids(list(username))[0])
  260.                         #self.joined_users.append((username, user_id))
  261.                         if user_id not in [x.user_id for x in self.users]:
  262.                             row={'username':username, 'user_id':user_id, 'current':0, 'all_time':0}
  263.                             self.users.append(User(row))
  264.                             self.joined_users.append(self.users[-1])
  265.                         else:
  266.                             i = [x.user_id for x in self.users].index(user_id)
  267.                             self.joined_users.append(self.users[i])
  268.                             #self.users['user_id'].append(user_id)
  269.                             #self.users['current'].append('0')
  270.                             #self.users['all_time'].append('0')
  271.                     #If message received
  272.                     elif text.find('PRIVMSG') != -1:
  273.                         if "!quit" in text and "mod" in text.split("user-type=")[1].split(":")[0]:
  274.                             self.quit()
  275.                         for command, handle in self.commands.items():
  276.                             if text.find(command) != -1:
  277.                                 print("Command found !")
  278.                                 username = text.split(":")[1].split("!")[0]
  279.                                 user_id = text.split("user-id=")[1].split(";")[0]
  280.                                 index = [x.user_id for x in self.users].index(int(user_id))
  281.                                 user = self.users[index]
  282.                                 print((username, user_id))
  283.                                 output, self.users = handle(self.users, text, user)
  284.                                 print(output)
  285.                                 if type(output) == type(str()):
  286.                                     self.irc.send('PRIVMSG #{} :{}\n'.format(self.channel_name, output).encode())
  287.                                 elif type(output) == type(tuple()):
  288.                                     self.points_multiplier += 1
  289.                                     self.end_doubletrouble = output[0]
  290.                                     self.doubletroublechanged = True
  291.                                     self.irc.send('PRIVMSG #{} :{}\n'.format(self.channel_name, output[1]).encode())
  292.                 except Exception as e:
  293.                     if "10035" not in repr(e):
  294.                         print("{} : {}".format(type(e), e))
  295.                     continue
  296.    
  297.     def quit(self):
  298.         self.irc.send('PRIVMSG #{} :{}\n'.format(self.channel_name, BOT_LEAVING_CHAT).encode())
  299.         self.irc.send('PART'.encode())
  300.         self.irc.close()
  301.         self.stop = True
  302.         with open(self.csv_filename, 'w') as csvfile:
  303.             fieldnames = ['username', 'user_id', 'current', 'all_time']
  304.             writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
  305.             writer.writeheader()
  306.             for i in range(len(self.users['username'])):
  307.                 writer.writerow({
  308.                 'username': self.users["username"][i],
  309.                 'user_id': self.users["user_id"][i],
  310.                 'current': self.users["current"][i],
  311.                 'all_time': self.users["all_time"][i]
  312.                 })
  313.    
  314.        
  315. def main():
  316.     commands = {'!kekettes':kekettes, #displays the amount of points the user has
  317.                 '!gamble':gamble, #gamble a set amount of points
  318.                 '!makeitrain':makeitrain, #gives each user 30 points
  319.                 '!doubletrouble':doubletrouble, #double the drop-rate of points for 30 minutes
  320.                 '!versus':versus, # challenge un autre viewer a un versus
  321.                 '!helpkekettes':helpkekettes, #Affiche l'aide
  322.                 '!quote':quote, #affiche une quote de teamot
  323.                 '!denisbrogniart': denisbrogniart #AH !
  324.                 }
  325.     cmds = [str(k) for k in commands.keys()]
  326.     cmd_str = ""
  327.     for i in cmds:
  328.         cmd_str += i+", "
  329.     cmd_str.rstrip(", ")
  330.     print(cmd_str)
  331.     HELP_MESSAGE.format(cmd_str)
  332.     #Most normal chat commands like /timeout, /ban, /clear are sent with periods
  333.     #in place of the forward slash. For example, to ban the user "xangold", you
  334.     #would send ".ban xangold" to the server (minus the quotes).
  335.     bot = KeketteBot(commands)
  336.     print('KekettesBot is now running !')
  337.     bot.start()
  338.    
  339.  
  340. if __name__ == '__main__':
  341.     main()
  342.     pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement