Skip to content

Instantly share code, notes, and snippets.

@jmhobbs
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jmhobbs/9b28d7991ae2346cec43 to your computer and use it in GitHub Desktop.
Save jmhobbs/9b28d7991ae2346cec43 to your computer and use it in GitHub Desktop.
A Points Tracker for Hubot
# Description:
#
# A plugin to track points awarded for good jokes.
#
# Hubot takes transaction fees though.
#
#
# Dependencies:
# A Redis brain is recommended.
#
# Configuration:
# None
#
# Commands:
# hubot: +50 to John Henry
# hubot: -50 from John Henry
# hubot: scoreboard
# hubot: give it all to John Henry
#
# Author:
# jmhobbs
PLUS_ONE_GIFS = [
"http://www.reactiongifs.us/wp-content/uploads/2013/04/thumbs_down_gladiator.gif"
]
# This is how many points a user gets when first seen by Hubot
DEFAULT_AMOUNT_OF_POINTS = 5000
# It is possible to give Hubot all the points. The MASTER user gets access to the "cash out" command. ONLY TO BE USED FOR GOOD, NOT EVIL.
MASTER = "Hobbs"
module.exports = (robot) ->
get_points = (username) ->
if 'undefined' == typeof robot.brain.data.internet_points[username]
robot.brain.data.internet_points[username] = DEFAULT_AMOUNT_OF_POINTS
parseInt(robot.brain.data.internet_points[username], 10)
add_points = (username, points) ->
robot.brain.data.internet_points[username] = get_points(username) + points
parseInt(robot.brain.data.internet_points[username], 10)
subtract_points = (username, points) ->
robot.brain.data.internet_points[username] = get_points(username) - points
parseInt(robot.brain.data.internet_points[username], 10)
get_low_and_high = () ->
high_user = ''
high_score = 0
low_user = ''
low_score = 999999
for name, points of robot.brain.data.internet_points || {}
if points > high_score
high_user = name
high_score = points
if points < low_score
low_user = name
low_score = points
return {'low': {'points': low_score, 'name': low_user}, 'high': {'points': high_score, 'name': high_user}}
robot.brain.on 'loaded', =>
robot.brain.data.internet_points ?= {}
robot.respond /(give it )?all to (.*)/i, (msg) ->
username = msg.match[2]
username = username.replace(/\W*$/, '')
users = robot.usersForFuzzyName(username)
if users.length is 1
user = users[0]
if msg.message.user.name == user.name
msg.send "NOP"
return
sender_points = get_points(msg.message.user.name)
if 0 >= sender_points
msg.send "You can't give what you don't have."
return
subtract_points(msg.message.user.name, sender_points)
new_receiver_points = add_points(user.name, sender_points)
msg.send "Gave #{sender_points} points to #{user.name}. New total #{new_receiver_points}. Much generous."
else if users.length > 1
msg.send "Too many users named like that."
else
msg.send "I don't know anyone named #{username}."
# This regex is horrific. Don't try to grok it.
robot.respond /-([0-9]+) from ((.*?) (for|to|so|because|since) .*|(.*))/i, (msg) ->
username = msg.match[3]
if 'undefined' == typeof(msg.match[3])
username = msg.match[2]
username = username.replace(/\W*$/, '')
users = robot.usersForFuzzyName(username)
if users.length is 1
user = users[0]
attack_points = parseInt(msg.match[1], 10)
attacker_debit = attack_points * 2
attackers_points = get_points(msg.message.user.name)
victims_points = get_points(user.name)
if user.name == robot.name
msg.send "Bite me."
return
if attacker_debit > attackers_points
msg.send "You must be willing to sacrifice #{attacker_debit} to take #{attack_points} from #{user.name}."
else if attack_points > victims_points
msg.send "Sorry, #{user.name} doesn't have #{attack_points} to take away."
else
subtract_points(msg.message.user.name, attacker_debit)
subtract_points(user.name, attack_points)
add_points(robot.name, attack_points + attacker_debit)
msg.send "Took #{attack_points} from #{user.name}"
else
msg.send "I don't know anyone named #{username}."
robot.respond /cash out/i, (msg) ->
if msg.message.user.name == MASTER
robot_points = get_points(robot.name)
subtract_points(robot.name, robot_points)
add_points(MASTER, robot_points)
msg.send "Of course, master."
# Again, don't try to grok this mess.
robot.respond /\+([0-9]+) to ((.*?) (for|to|so|because|since) .*|(.*))/i, (msg) ->
username = msg.match[3]
if 'undefined' == typeof(msg.match[3])
username = msg.match[2]
username = username.replace(/\W*$/, '')
users = robot.usersForFuzzyName(username)
if users.length is 1
user = users[0]
sending_points = parseInt(msg.match[1], 10)
transfer_fee = 5 + Math.ceil(sending_points/10)
jackpot_dice = Math.floor(Math.random() * 15) + 1
commie_dice = Math.floor(Math.random() * 15) + 1
if msg.message.user.name == user.name
msg.send "No giving yourself points, gold digger."
return
sender_points = get_points(msg.message.user.name)
if sender_points <= 0
msg.send "You don't have anything to give."
return
if sending_points == 0
msg.send "Don't waste my time."
return
if sender_points >= sending_points
if sender_points < sending_points + transfer_fee
msg.send "Sorry #{msg.message.user.name}, you don't have enough to cover the #{transfer_fee} point transfer fee. It's 5 points + 10% of the transaction."
else
new_sender_points = subtract_points(msg.message.user.name, sending_points + transfer_fee)
new_receiver_points = add_points(user.name, sending_points)
add_points(robot.name, transfer_fee)
msg.send "Gave #{sending_points} points to #{user.name}. New total #{new_receiver_points}. You have #{new_sender_points} remaining."
if sending_points == 1
msg.send msg.random PLUS_ONE_GIFS
# Only use special features for "real" points transfers.
if sending_points >= 100
if 3 == commie_dice
high_low = get_low_and_high()
if robot.name != high_low.low.name
transfer_amount = Math.floor(high_low.high.points/2)
subtract_points(high_low.high.name, transfer_amount)
add_points(high_low.low.name, transfer_amount)
msg.send "COMMUNISM! Taking #{transfer_amount} from #{high_low.high.name} to give to #{high_low.low.name}! THANKS OBAMA!"
# Chill out. It's a joke.
if 3 == jackpot_dice and robot.name != user.name
robot_points = get_points(robot.name)
share_points = Math.floor(robot_points / 2)
subtract_points(robot.name, share_points * 2)
add_points(user.name, share_points)
add_points(msg.message.user.name, share_points)
msg.send "You hit the JACKPOT! Giving #{share_points} to both of you!"
else
msg.send "Sorry #{msg.message.user.name}, you only have #{sender_points}."
else if users.length > 1
msg.send "Too many users named like that."
else
msg.send "I don't know anyone named #{username}."
robot.respond /score ?board/i, (msg) ->
scores = []
for name, points of robot.brain.data.internet_points || {}
scores.push({'name': name, 'points': points})
scores.sort (a,b) ->
return if a.points >= b.points then 1 else -1
output = "\n[Current Points Score Board]"
for score in scores
output += "\n#{score.name} -> #{score.points}"
msg.send output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment