diff --git a/Points.py b/Points.py index 35ef40d..c4d8a42 100644 --- a/Points.py +++ b/Points.py @@ -5,6 +5,7 @@ from pprint import pprint import time import numpy as np import random +from datetime import datetime class Points(object): """Geef elkaar punten!""" @@ -13,8 +14,7 @@ class Points(object): self.bot = bot self.voice_states = {} - #a = discord.get_channel(self.bot.hdChannels["shitpost"]) - #pprint(a) + self.BANK_ID = 42 def __check(self, ctx): return True @@ -26,22 +26,19 @@ class Points(object): Bijvoorbeeld: !geefpunten @ikbenjp 42 Let op: je moet iemand taggen om punten uit te delen + De eerste 10 punten zijn on the house. (Als er genoeg in de bank zit.) """ if points == 0: yield from ctx.channel.send("0 punten? Gul hoor.") return if points < 0: - yield from ctx.channel.send("Doeslief. Je mag (nog) geen punten afnemen.") + yield from self.sendErrorDm(ctx, "Daar hebben we de !neempunten functie voor. Voor meer info typ: ```!help neempunten```") return if user[0:2] != "<@": - try: - yield from ctx.message.delete() - yield from ctx.message.author.send("Je moet iemand taggen om punten te geven. :)") - #TODO ook userId oid toestaan? - except: - print("No permission to delete message or send DM") + yield from self.sendErrorDm(ctx, "Je moet iemand taggen om punten te geven. :)") + #TODO ook userId oid toestaan? return userObj = self.bot.get_user( int(user.replace("<@!", "").replace("<@", "").replace(">", "")) ) @@ -58,12 +55,66 @@ class Points(object): yield from ctx.channel.send("Daar heb jij niet genoeg puntjes voor. :bell:") return - self.transferPoints(ctx.author, userObj, points) + # Execute the transaction: + # First, try to give a away (at most 10) bankpoints + areBeingGivenFromBank = min(points, self.getUsersRemainingBankPointsToGiveAwayToday(ctx.author.id)) + areBeingGivenFromBank = min(areBeingGivenFromBank, self.getBankBalance()) + if areBeingGivenFromBank > 0: + self.transferPoints(self.BANK_ID, userObj.id, areBeingGivenFromBank) + self.increaseUsersBankPointGivenAwayToday(ctx.author.id, areBeingGivenFromBank) + remainingPointsToGive = points - areBeingGivenFromBank + else: + remainingPointsToGive = points + # The remaining points come out of your own pocket + if remainingPointsToGive > 0: + self.transferPoints(ctx.author.id, userObj.id, remainingPointsToGive) message = self.getMessageForAwardingPoints(ctx.author.name, userObj.name, points) yield from ctx.channel.send(message) + @commands.command(pass_context=True, hidden=False) + @asyncio.coroutine + def neempunten(self, ctx, user, points: int): + """Tijd om iemand the shamen. Haal wat punten weg. + Bijvoorbeeld: + !neempunten @mark 5 + Punten gaan naar de bank. Je mag niet meer dan 10 punten per dag afnemen. + Let op: je moet iemand taggen om punten weg te nemen. + """ + + if points < 1: + yield from ctx.channel.send("Volgens mij snap je het niet.") + return + if points > 10: + yield from self.sendErrorDm(ctx, "Je mag niet meer dan 10 punten afnemen.") + return + remainingToTakeAway = self.getUsersRemainingPointsToTakeToday(ctx.author.id) + if points > remainingToTakeAway: # The limit per day is 10 + yield from self.sendErrorDm(ctx, "Je mag vandaag nog maar " + str(remainingToTakeAway) + " punten wegnemen.") + return + + if user[0:2] != "<@": + yield from self.sendErrorDm(ctx, "Je moet iemand taggen. :)") + return + + userObj = self.bot.get_user( int(user.replace("<@!", "").replace("<@", "").replace(">", "")) ) + + if not self.isUserOnList(userObj): + yield from ctx.channel.send("Nee.") + return + if self.getUserBalance(userObj) < points: + yield from ctx.channel.send(userObj.name + " mag niet rood staan.") + return + + # Execute the transaction: + self.increaseUsersPointTakenOnDate(ctx.author.id, points) + self.transferPoints(userObj.id, self.BANK_ID, points) + + message = self.getMessageForTakingPoints(userObj.name, ctx.author.name, points) + yield from ctx.channel.send(message) + + @commands.command(pass_context=True, hidden=False) @asyncio.coroutine def puntentelling(self, ctx): @@ -74,16 +125,30 @@ class Points(object): pointsCount = np.load('pointscount.npy').item() pointsCountSorted = sorted(pointsCount.items(), key=lambda i: i[1]['points'], reverse=True) for user in pointsCountSorted: - message += str(user[1]["points"]).rjust(4) + " " + user[1]["name"] + "\n" - message += "```" + if user[0] != self.BANK_ID: + message += str(user[1]["points"]).rjust(4) + " " + user[1]["name"] + "\n" + message += str(pointsCount[self.BANK_ID]["points"]).rjust(4) + " " + pointsCount[self.BANK_ID]["name"] + "```" + #message += "```" yield from ctx.channel.send(message) + + # No public shaming. Send somebody a direct correction message. + @asyncio.coroutine + def sendErrorDm(self, ctx, message): + try: + yield from ctx.message.delete() + except: + print("No permission to delete message") + try: + yield from ctx.message.author.send(message) + except: + print("No permission to send DM") # Transfer points form one user to another - def transferPoints(self, fromUser, toUser, points): + def transferPoints(self, fromUserId, toUserId, points): pointsCount = np.load('pointscount.npy').item() - pointsCount[fromUser.id]["points"] -= points - pointsCount[toUser.id]["points"] += points + pointsCount[fromUserId]["points"] -= points + pointsCount[toUserId]["points"] += points np.save("pointscount.npy", pointsCount) # Do we know this user? @@ -95,6 +160,49 @@ class Points(object): def getUserBalance(self, user): pointsCount = np.load('pointscount.npy').item() return pointsCount[user.id]["points"] + + # Get the balance of the bank + def getBankBalance(self): + pointsCount = np.load('pointscount.npy').item() + return pointsCount[self.BANK_ID]["points"] + + # To keep track if a user used some points today, we look at when the last time was he/she used them + # If this was in the past: reset + # Also, return the updated object. Why not. + def refreshDateVarsAndReturnUserVars(self, userId): + pointsCount = np.load('pointscount.npy').item() + currentDateStr = datetime.now().strftime("%Y%m%d") + if pointsCount[userId]["theDate"] != currentDateStr: + pointsCount[userId]["theDate"] = currentDateStr + pointsCount[userId]["pointTakenOnDate"] = 0 + pointsCount[userId]["bankPointsGivenOnDate"] = 0 + np.save("pointscount.npy", pointsCount) + return pointsCount[userId] + + # How many points can this user still take away today? + def getUsersRemainingPointsToTakeToday(self, userId): + userInfo = self.refreshDateVarsAndReturnUserVars(userId) + return 10 - userInfo["pointTakenOnDate"] + + # How many bank points can this user still give away? + def getUsersRemainingBankPointsToGiveAwayToday(self, userId): + userInfo = self.refreshDateVarsAndReturnUserVars(userId) + return 10 - userInfo["bankPointsGivenOnDate"] + + # Increase the number of points this user has taken away today. + # Warning: assumes you executed refreshDateVarsAndReturnUserVars() + def increaseUsersPointTakenOnDate(self, userId, points): + pointsCount = np.load('pointscount.npy').item() + pointsCount[userId]["pointTakenOnDate"] += points + np.save("pointscount.npy", pointsCount) + + # Increase the number of bank points this user has given today + # Warning: assumes you executed refreshDateVarsAndReturnUserVars() + def increaseUsersBankPointGivenAwayToday(self, userId, points): + pointsCount = np.load('pointscount.npy').item() + pointsCount[userId]["bankPointsGivenOnDate"] += points + np.save("pointscount.npy", pointsCount) + # Generate a semi-random text to tell somebody they got some shiny new points def getMessageForAwardingPoints(self, userNameFrom: str, userNameTo: str, points: int): @@ -118,6 +226,27 @@ class Points(object): p + " blockchain smartcontract punt" + grammarFixer["suffixNl"] + " voor " + userNameTo + ". :rocket: " ] return messages[random.randint(0, len(messages)-1)] + + # Generate a semi-random text to tell somebody they just lost their precious points + def getMessageForTakingPoints(self, userNameFrom: str, userNameTaker: str, points: int): + p = str(points) + + if points == 1: + grammarFixer = {"suffixGb":"", "suffixNl":"", "gaatOfGaan":"gaat"} + else: + grammarFixer = {"suffixGb":"s", "suffixNl":"en", "gaatOfGaan":"gaan"} + + messages = [ + userNameFrom + " verliest " + p + " punt" + grammarFixer["suffixNl"] + ".", + userNameFrom + " is " + p + " punt" + grammarFixer["suffixNl"] + " kwijt. F.", + userNameTaker + " vindt dat jij " + p + " punt" + grammarFixer["suffixNl"] + " moet kwijtraken, " + userNameFrom + ".", + p + " POINT" + grammarFixer["suffixGb"].upper() + " FROM HUFFELPU.. oh.. " + userNameFrom + ".", + "Je bent " + p + " punt" + grammarFixer["suffixNl"] + " armer geworden, " + userNameFrom + ".", + "Je hebt toch genoeg, " + userNameFrom + ". We halen " + p + " punt" + grammarFixer["suffixNl"] + " weg.", + userNameTaker + " haalt " + p + " punt" + grammarFixer["suffixNl"] + " weg bij " + userNameFrom + ". Wat een lul.", + p + " punt" + grammarFixer["suffixNl"] + " " + grammarFixer["gaatOfGaan"] + " van " + userNameFrom + " naar de bank." + ] + return messages[random.randint(0, len(messages)-1)] def init(self): @@ -128,9 +257,15 @@ class Points(object): np.save("pointscount.npy", {}) pointsCount = np.load('pointscount.npy').item() + # Initialise the bank: + if self.BANK_ID not in pointsCount.keys(): + pointsCount[self.BANK_ID] = {"name": '"De Bank"', "points": 300} + np.save("pointscount.npy", pointsCount) + + # Add new/unknown members: memberList = self.bot.get_channel(self.bot.hdChannels["shitpost"]).members for member in memberList: # Give new members 100 points if member.id not in pointsCount.keys() and not member.bot: - pointsCount[member.id] = {"name": member.name, "points": 100} + pointsCount[member.id] = {"name": member.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20181231"} np.save("pointscount.npy", pointsCount)