Files
stroopwafel/Points.py
T
2019-06-06 21:54:05 +02:00

272 lines
11 KiB
Python

import asyncio
import discord
from discord.ext import commands
from pprint import pprint
import time
import numpy as np
import random
from datetime import datetime
class Points(object):
"""Geef elkaar punten!"""
def __init__(self, bot):
self.bot = bot
self.voice_states = {}
self.BANK_ID = 42
def __check(self, ctx):
return True
@commands.command(pass_context=True, hidden=False)
@asyncio.coroutine
def geefpunten(self, ctx, user, points: int):
"""Wees eens lief. Geef iemand wat punten.
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 self.sendErrorDm(ctx, "Daar hebben we de !neempunten functie voor. Voor meer info typ: ```!help neempunten```")
return
if user[0:2] != "<@":
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(">", "")) )
if userObj.id == ctx.author.id:
yield from ctx.channel.send("Nee. Je mag niet jezelf punten geven.")
time.sleep(0.6)
yield from ctx.channel.send("Gekkie.")
return
if not self.isUserOnList(userObj):
yield from ctx.channel.send("Nee. Die krijgt geen punten.")
return
if self.getUserBalance(ctx.author) < points:
yield from ctx.channel.send("Daar heb jij niet genoeg puntjes voor. :bell:")
return
# 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):
"""Hoeveel punten heeft iedereen?
"""
message = "**De puntentelling:** \n```"
pointsCount = np.load('pointscount.npy').item()
pointsCountSorted = sorted(pointsCount.items(), key=lambda i: i[1]['points'], reverse=True)
for user in pointsCountSorted:
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, fromUserId, toUserId, points):
pointsCount = np.load('pointscount.npy').item()
pointsCount[fromUserId]["points"] -= points
pointsCount[toUserId]["points"] += points
np.save("pointscount.npy", pointsCount)
# Do we know this user?
def isUserOnList(self, user):
pointsCount = np.load('pointscount.npy').item()
return user.id in pointsCount.keys()
# Get a user's point balance
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):
p = str(points)
if points == 1:
grammarFixer = {"suffixGb":"", "suffixNl":"", "zijnOfIs": "is"}
else:
grammarFixer = {"suffixGb":"s", "suffixNl":"en", "zijnOfIs": "zijn"}
messages = [
p + " punt" + grammarFixer["suffixNl"] + " voor " + userNameTo + ".",
userNameTo + " krijgt " + p + " punt" + grammarFixer["suffixNl"] + ".",
userNameTo + " krijgt " + p + " punt" + grammarFixer["suffixNl"] + " van " + userNameFrom,
p + " POINT" + grammarFixer["suffixGb"].upper() + " TO GRYFFINDO.. oh.. " + userNameTo + ".",
userNameTo + ", jij krijgt " + p + " puntje" + grammarFixer["suffixGb"] + " van " + userNameFrom + ". Lief he? :heart:",
"+" + p + " punt" + grammarFixer["suffixNl"] + " voor " + userNameTo + "! Highscore!",
userNameTo + ", alsjeblieft, " + p + " punt" + grammarFixer["suffixNl"] + ".",
"Hier " + grammarFixer["zijnOfIs"] + " " + p + " punt" + grammarFixer["suffixNl"] + ", " + userNameTo + ". Don't spend it all in one place...",
"Jij kan wel " + p + " punt" + grammarFixer["suffixNl"] + " gebruiken, " + userNameTo + ".",
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):
# Check if points file exists:
try:
pointsCount = np.load('pointscount.npy').item()
except FileNotFoundError:
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, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20181231"}
np.save("pointscount.npy", pointsCount)