Files
stroopwafel/Points.py
mark f8db215b31 Replaces asyncio coroutines with native async
Replaces @asyncio.coroutine decorator with async
Replaces yield from with await
2022-12-18 02:03:46 +01:00

285 lines
11 KiB
Python

import discord
from discord.ext import commands
from pprint import pprint
import time
import numpy as np
import random
import os
from datetime import datetime
class Points(commands.Cog):
"""Geef elkaar punten!"""
def __init__(self, bot):
self.bot = bot
self.voice_states = {}
self.BANK_ID = 42
self.init()
self.pointsCount = {}
self.reloadPointsCount()
def __check(self, ctx):
return True
@commands.command(pass_context=True, hidden=False)
async 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.)
"""
self.reloadPointsCount()
if points == 0:
await ctx.channel.send("0 punten? Gul hoor.")
return
if points < 0:
await self.sendErrorDm(ctx, "Daar hebben we de !neempunten functie voor. Voor meer info typ: ```!help neempunten```")
return
if user[0:2] != "<@":
await self.sendErrorDm(ctx, "Je moet iemand taggen om punten te geven. :)")
#TODO ook userId oid toestaan?
return
userObj = ctx.message.mentions[0]
if userObj.id == ctx.author.id:
await ctx.channel.send("Nee. Je mag niet jezelf punten geven.")
time.sleep(0.6)
await ctx.channel.send("Gekkie.")
return
if not self.isUserOnList(userObj):
await ctx.channel.send("Nee. Die krijgt geen punten.")
return
if self.getUserBalance(ctx.author) < points:
await ctx.channel.send("Daar heb jij niet genoeg puntjes voor. :bell:")
return
# Execute the transaction:
self.execute_geefpunten(ctx.author.id, userObj.id, points)
self.savePointsCount()
message = self.getMessageForAwardingPoints(ctx.author.name, userObj.name, points)
await ctx.channel.send(message)
def execute_geefpunten(self, giverId, recieverId, points):
# First, try to give away (at most 10) bankpoints
areBeingGivenFromBank = min(points, self.getUsersRemainingBankPointsToGiveAwayToday(giverId))
areBeingGivenFromBank = min(areBeingGivenFromBank, self.getBankBalance())
if areBeingGivenFromBank > 0:
self.transferPoints(self.BANK_ID, recieverId, areBeingGivenFromBank)
self.increaseUsersBankPointGivenAwayToday(giverId, areBeingGivenFromBank)
remainingPointsToGive = points - areBeingGivenFromBank
else:
remainingPointsToGive = points
# The remaining points come out of your own pocket
if remainingPointsToGive > 0:
self.transferPoints(giverId, recieverId, remainingPointsToGive)
@commands.command(pass_context=True, hidden=False)
async 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.
"""
self.reloadPointsCount()
if points < 1:
await ctx.channel.send("Volgens mij snap je het niet.")
return
if points > 10:
await 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
await self.sendErrorDm(ctx, "Je mag vandaag nog maar " + str(remainingToTakeAway) + " punten wegnemen.")
return
if user[0:2] != "<@":
await self.sendErrorDm(ctx, "Je moet iemand taggen. :)")
return
userObj = ctx.message.mentions[0]
if not self.isUserOnList(userObj):
await ctx.channel.send("Nee.")
return
if self.getUserBalance(userObj) < points:
await ctx.channel.send(userObj.name + " mag niet rood staan.")
return
# Execute the transaction:
self.execute_neempunten(ctx.author.id, userObj.id, points);
self.savePointsCount()
message = self.getMessageForTakingPoints(userObj.name, ctx.author.name, points)
await ctx.channel.send(message)
def execute_neempunten(self, takerId, victimId, points):
self.increaseUsersPointTakenOnDate(takerId, points)
self.transferPoints(victimId, self.BANK_ID, points)
@commands.command(pass_context=True, hidden=False)
async def puntentelling(self, ctx):
"""Hoeveel punten heeft iedereen?
"""
self.reloadPointsCount()
message = "**De puntentelling:** \n```"
pointsCountSorted = sorted(self.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(self.pointsCount[self.BANK_ID]["points"]).rjust(4) + " " + self.pointsCount[self.BANK_ID]["name"] + "```"
await ctx.channel.send(message)
# No public shaming. Send somebody a direct correction message.
async def sendErrorDm(self, ctx, message):
try:
await ctx.message.delete()
except:
print("No permission to delete message")
try:
await ctx.message.author.send(message)
except:
print("No permission to send DM")
# Get the points count object from the file
def reloadPointsCount(self):
self.pointsCount = np.load('pointscount.npy', allow_pickle=True).item()
# Save the points count to the file
def savePointsCount(self):
np.save("pointscount.npy", self.pointsCount)
# Transfer points form one user to another
def transferPoints(self, fromUserId, toUserId, points):
self.pointsCount[fromUserId]["points"] -= points
self.pointsCount[toUserId]["points"] += points
# Do we know this user?
def isUserOnList(self, user):
return user.id in self.pointsCount.keys()
# Get a user's point balance
def getUserBalance(self, user):
return self.pointsCount[user.id]["points"]
# Get the balance of the bank
def getBankBalance(self):
return self.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):
currentDateStr = datetime.now().strftime("%Y%m%d")
if self.pointsCount[userId]["theDate"] != currentDateStr:
self.pointsCount[userId]["theDate"] = currentDateStr
self.pointsCount[userId]["pointTakenOnDate"] = 0
self.pointsCount[userId]["bankPointsGivenOnDate"] = 0
return self.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):
self.pointsCount[userId]["pointTakenOnDate"] += points
# Increase the number of bank points this user has given today
# Warning: assumes you executed refreshDateVarsAndReturnUserVars()
def increaseUsersBankPointGivenAwayToday(self, userId, points):
self.pointsCount[userId]["bankPointsGivenOnDate"] += points
# 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', allow_pickle=True).item()
except FileNotFoundError:
np.save("pointscount.npy", {})
pointsCount = np.load('pointscount.npy', allow_pickle=True).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:
list_channel = self.bot.get_channel(int(os.getenv('STROOP_CHANNEL_SHITPOST')))
memberList = list_channel.members if list_channel else []
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)