Include more modules

dave/xdcc
Dave Pedu 9 years ago
parent 67bfd29e4f
commit 25718d8b77
  1. 21
      data/config/CryptoWalletRPC.yml
  2. 6
      data/config/DogeDice.yml
  3. 4
      data/config/DogeRPC.yml
  4. 2
      data/config/Seen.yml
  5. 50
      data/data/DogeScramble/us_states.txt
  6. 217
      pyircbot/modules/CryptoWallet.py
  7. 125
      pyircbot/modules/CryptoWalletRPC.py
  8. 315
      pyircbot/modules/DogeDice.py
  9. 66
      pyircbot/modules/DogeRPC.py
  10. 258
      pyircbot/modules/DogeScramble.py
  11. 164
      pyircbot/modules/DogeWallet.py
  12. 83
      pyircbot/modules/NickUser.py

@ -0,0 +1,21 @@
types:
LTC:
name: Litecoin
abbr: LTC
host: 127.0.0.1
username: user
password: pass
port: 12893
precision: 8
reserve: .01
link: https://litecoin.org/
BTC:
name: Bitcoin
abbr: BTC
host: 127.0.0.1
username: user
password: pass
port: 48191
precision: 8
reserve: .001
link: http://bitcoin.org/

@ -0,0 +1,6 @@
minBet: .01
lobbyIdleSeconds: 15
channelWhitelistOn: True
channelWhitelist:
- dogegamestest
- test

@ -0,0 +1,4 @@
host: 127.0.0.1
username: wallet_rpc_user
password: wallet_rpc_pass
port: 22555

@ -0,0 +1,2 @@
timezone: EST
add_hours: 0

@ -1,50 +0,0 @@
Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
New Hampshire
New Jersey
New Mexico
New York
North Carolina
North Dakota
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode Island
South Carolina
South Dakota
Tennessee
Texas
Utah
Vermont
Virginia
Washington
West Virginia
Wisconsin
Wyoming

@ -0,0 +1,217 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
import time
import hashlib
class CryptoWallet(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.gotmsg)]
def gotmsg(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
# Ignore channel messages
pass
else:
self.handlePm(args, prefix, trailing)
def getMods(self):
return (self.bot.getBestModuleForService("attributes"), self.bot.getBestModuleForService("login"), self.bot.getBestModuleForService("bitcoinrpc"))
def handle_setaddr(self, args, prefix, trailing, cmd):
usage = ".setaddr <currency> <address>"
attr,login,rpc = self.getMods()
# Check login
if not login.check(prefix.nick, prefix.hostname):
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: Please .login to use this command.")
return
# Check for args
if not len(cmd.args)==2:
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: usage: %s" % usage)
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: usage: .setaddr BTC 1xyWx6X5EABprhe3s9XduNxLn5NCtpSNB")
return
# Check if currency is known
if not rpc.isSupported(cmd.args[0]):
supportedStr = ', '.join(rpc.getSupported())
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: '%s' is not a supported currency. Supported currencies are: %s" % (cmd.args[0], supportedStr))
return
if len(cmd.args[1])<16 or len(cmd.args[1])>42:
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: '%s' appears to be an invalid address." % (cmd.args[1]))
return
# Just make sure they have a wallet
self.checkUserHasWallet(prefix.nick, cmd.args[0])
# Set their address
attr.setAttribute(prefix.nick, "cryptowallet-%s-address"%cmd.args[0].lower(), cmd.args[1])
self.bot.act_PRIVMSG(prefix.nick, ".setaddr: Your address has been saved as: %s. Please verify that this is correct or your coins could be lost." % (cmd.args[1]))
def handle_getbal(self, args, prefix, trailing, cmd):
usage = ".getbal <currency>"
attr,login,rpc = self.getMods()
# Check login
if not login.check(prefix.nick, prefix.hostname):
self.bot.act_PRIVMSG(prefix.nick, ".getbal: Please .login to use this command.")
return
# Check for args
if not len(cmd.args)==1:
self.bot.act_PRIVMSG(prefix.nick, ".getbal: usage: %s" % usage)
self.bot.act_PRIVMSG(prefix.nick, ".getbal: usage: .getbal BTC")
return
# Check if currency is known
if not rpc.isSupported(cmd.args[0]):
supportedStr = ', '.join(rpc.getSupported())
self.bot.act_PRIVMSG(prefix.nick, ".getbal: '%s' is not a supported currency. Supported currencies are: %s" % (cmd.args[0], supportedStr))
return
# Just make sure they have a wallet
self.checkUserHasWallet(prefix.nick, cmd.args[0])
# fetch RPC and tell them the balance
walletname = attr.getAttribute(prefix.nick, "cryptowallet-account-%s"%cmd.args[0].lower())
amount = 0.0
if walletname:
client = rpc.getRpc(cmd.args[0].lower())
amount = client.getBal(walletname)
self.bot.act_PRIVMSG(prefix.nick, "Your balance is: %s %s" % (amount, cmd.args[0].upper()))
def handle_withdraw(self, args, prefix, trailing, cmd):
usage = ".withdraw <currency> <amount>"
attr,login,rpc = self.getMods()
# Check login
if not login.check(prefix.nick, prefix.hostname):
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: Please .login to use this command.")
return
# Check for args
if not len(cmd.args)==2:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: usage: %s" % usage)
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: usage: .getbal BTC 0.035")
return
# Check if currency is known
if not rpc.isSupported(cmd.args[0]):
supportedStr = ', '.join(rpc.getSupported())
self.bot.act_PRIVMSG(prefix.nick, ".getbal: '%s' is not a supported currency. Supported currencies are: %s" % (cmd.args[0], supportedStr))
return
# Just make sure they have a wallet
self.checkUserHasWallet(prefix.nick, cmd.args[0])
# check that they have a withdraw addr
withdrawaddr = attr.getAttribute(prefix.nick, "cryptowallet-%s-address"%cmd.args[0].lower())
if withdrawaddr == None:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: You need to set a withdraw address before withdrawing. Try .setaddr")
return
# fetch RPC and check balance
walletname = attr.getAttribute(prefix.nick, "cryptowallet-account-%s"%cmd.args[0].lower())
balance = 0.0
client = rpc.getRpc(cmd.args[0].lower())
balance = client.getBal(walletname)
withdrawamount = float(cmd.args[1])
if balance < withdrawamount or withdrawamount<0:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: You don't have enough %s to withdraw %s" % (cmd.args[0].upper(), withdrawamount))
return
if not client.reserve == 0 and balance - client.reserve < withdrawamount:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: Withdrawing that much would put you below the reserve (%s %s)." % (client.reserve, cmd.args[0].upper()))
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: The reserve is to cover network transaction fees. To recover it you must close your account. (Talk to an admin)")
return
# Check if the precision is wrong
if not client.checkPrecision(withdrawamount):
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: %s has maximum %s decimal places" % (cmd.args[0].upper(), client.precision))
return
# Create a transaction
txn = client.send(walletname, withdrawaddr, withdrawamount)
if txn:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: %s DOGE sent to %s. Transaction ID: %s"% (withdrawamount, withdrawaddr, txn))
else:
self.bot.act_PRIVMSG(prefix.nick, ".withdraw: Transaction create failed. Maybe the transaction was too large for the network? Try a smaller increment.")
def handle_getaddr(self, args, prefix, trailing, cmd):
attr,login,rpc = self.getMods()
usage = ".getaddr <currency>"
attr,login,rpc = self.getMods()
# Check login
if not login.check(prefix.nick, prefix.hostname):
self.bot.act_PRIVMSG(prefix.nick, ".getaddr: Please .login to use this command.")
return
# Check for args
if not len(cmd.args)==1:
self.bot.act_PRIVMSG(prefix.nick, ".getaddr: usage: %s" % usage)
self.bot.act_PRIVMSG(prefix.nick, ".getaddr: usage: .getaddr BTC")
return
# Check if currency is known
if not rpc.isSupported(cmd.args[0]):
supportedStr = ', '.join(rpc.getSupported())
self.bot.act_PRIVMSG(prefix.nick, ".getaddr: '%s' is not a supported currency. Supported currencies are: %s" % (cmd.args[0], supportedStr))
return
# Just make sure they have a wallet
self.checkUserHasWallet(prefix.nick, cmd.args[0])
walletaddr = attr.getAttribute(prefix.nick, "cryptowallet-depoaddr-%s"%cmd.args[0].lower())
self.bot.act_PRIVMSG(prefix.nick, "Your %s deposit address is: %s" % (cmd.args[0].upper(), walletaddr))
def handle_curinfo(self, args, prefix, trailing, cmd):
attr,login,rpc = self.getMods()
usage = ".curinfo [<currency>]"
attr,login,rpc = self.getMods()
# Check for args
if len(cmd.args)==0:
self.bot.act_PRIVMSG(prefix.nick, ".curinfo: supported currencies: %s. Use '.curinfo BTC' to see details. " % ', '.join([x.upper() for x in rpc.getSupported()]))
return
else:
if not rpc.isSupported(cmd.args[0]):
self.bot.act_PRIVMSG(prefix.nick, ".curinfo: '%s' is not a supported currency. Supported currencies are: %s" % (cmd.args[0], ', '.join([x.upper() for x in rpc.getSupported()])))
return
else:
info = rpc.getInfo(cmd.args[0])
self.bot.act_PRIVMSG(prefix.nick, ".curinfo: %s - %s. More info: %s" % (args[0], info["name"], info["link"]))
def checkUserHasWallet(self, username, currency):
# Ensure the user has a wallet in the client
attr,login,rpc = self.getMods()
currency = currency.lower()
if attr.getAttribute(username, "cryptowallet-account-%s"%currency)==None:
randName = self.md5(str(time.time()))[0:16]
attr.setAttribute(username, "cryptowallet-account-%s"%currency, randName)
# Generate a deposit addr to nudge the wallet
wallet = rpc.getRpc(currency.lower())
address = wallet.getAcctAddr(randName)
attr.setAttribute(username, "cryptowallet-depoaddr-%s"%currency, address)
elif attr.getAttribute(username, "cryptowallet-depoaddr-%s"%currency)==None:
walletName = attr.getAttribute(username, "cryptowallet-account-%s"%currency)
wallet = rpc.getRpc(currency.lower())
address = wallet.getAcctAddr(walletName)
attr.setAttribute(username, "cryptowallet-depoaddr-%s"%currency, address)
def handlePm(self, args, prefix, trailing):
prefix = self.bot.decodePrefix(prefix)
cmd = self.bot.messageHasCommand(".setaddr", trailing)
if cmd:
self.handle_setaddr(args, prefix, trailing, cmd)
cmd = self.bot.messageHasCommand(".getbal", trailing)
if cmd:
self.handle_getbal(args, prefix, trailing, cmd)
cmd = self.bot.messageHasCommand(".withdraw", trailing)
if cmd:
self.handle_withdraw(args, prefix, trailing, cmd)
cmd = self.bot.messageHasCommand(".getaddr", trailing)
if cmd:
self.handle_getaddr(args, prefix, trailing, cmd)
cmd = self.bot.messageHasCommand(".curinfo", trailing)
if cmd:
self.handle_curinfo(args, prefix, trailing, cmd)
def md5(self, data):
m = hashlib.md5()
m.update(data.encode("ascii"))
return m.hexdigest()

@ -0,0 +1,125 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
from bitcoinrpc.authproxy import AuthServiceProxy
from math import floor
from threading import Thread
from time import sleep
class CryptoWalletRPC(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[]
self.services=["bitcoinrpc"]
self.loadConfig()
self.rpcservices={}
self.loadrpcservices()
def loadrpcservices(self):
# Create a dict of abbreviation=>BitcoinRPC objcet relation
self.log.info("CryptoWalletRPC: loadrpcservices: connecting to RPCs")
count = len(list(self.config["types"].keys()))
num = 0
for key in self.config["types"]:
self.rpcservices[key.lower()]=BitcoinRPC(self, key, self.config["types"][key]["host"], self.config["types"][key]["port"], self.config["types"][key]["username"], self.config["types"][key]["password"], self.config["types"][key]["precision"], self.config["types"][key]["reserve"])
num+=1
def getRpc(self, currencyAbbr):
# Return the rpc for the currency requested
# self.getRpc("LTC") -> returns a litecoin rpc instance
currencyAbbr = currencyAbbr.lower()
if currencyAbbr in self.rpcservices:
return self.rpcservices[currencyAbbr]
return None
def getSupported(self):
# return a list of (appreviatons of) supported currencies
return list(self.rpcservices.keys())
def isSupported(self, abbr):
# true/false if currency is supported
supported = self.getSupported()
return abbr.lower() in supported
def getInfo(self, abbr):
# return the coin's info from config
if self.isSupported(abbr):
return self.config["types"][abbr.upper()]
class BitcoinRPC:
def __init__(self, parent, name, host, port, username, password, precision, reserve):
# Store info and connect
self.master = parent
self.name = name
self.host = host
self.port = port
self.username = username
self.password = password
self.precision = precision
self.reserve = reserve
self.log = self.master.log
# AuthServiceProxy (json client) stored here
self.con = None
# Connect
Thread(target=self.ping).start()
def getBal(self, acct):
# get a balance of an address or an account
return self.getAcctBal(acct)
def getAcctAddr(self, acct):
# returns the address for an account. creates if necessary
self.ping()
addrs = self.con.getaddressesbyaccount(acct)
if len(addrs)==0:
return self.con.getnewaddress(acct)
return addrs[0]
def getAcctBal(self, acct):
# returns an account's balance
self.ping()
return float(self.con.getbalance(acct))
def canMove(self, fromAcct, toAcct, amount):
# true or false if fromAcct can afford to give toAcct an amount of coins
balfrom = self.getAcctBal(fromAcct)
return balfrom >= amount
def move(self, fromAcct, toAcct, amount):
# move coins from one account to another
self.ping()
if self.canMove(fromAcct, toAcct, amount):
return self.con.move(fromAcct, toAcct, amount)
return False
def send(self, fromAcct, toAddr, amount):
# send coins to an external addr
self.ping()
if self.canMove(fromAcct, toAddr, amount):
return self.con.sendfrom(fromAcct, toAddr, amount)
return False
def checkPrecision(self, amount):
return amount == round(amount, self.precision)
def ping(self):
# internal. test connection and connect if necessary
try:
self.con.getinfo()
except:
self.connect()
def connect(self):
# internal. connect to the service
self.log.debug("CryptoWalletRPC: %s: Connecting to %s:%s" % (self.name, self.host,self.port))
try:
self.con = AuthServiceProxy("http://%s:%s@%s:%s" % (self.username, self.password, self.host, self.port))
except Exception as e:
self.log.debug("CryptoWalletRPC: %s: Could not connect to %s:%s: %s" % (self.name, self.host, self.port, str(e)))
return
self.log.debug("CryptoWalletRPC: %s: Connected to %s:%s" % (self.name, self.host, self.port))

@ -0,0 +1,315 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
import random
import yaml
import os
import time
import math
import hashlib
from threading import Timer
class DogeDice(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.gotMsg)]
self.loadConfig()
# Load attribute storage
self.attr = self.bot.getBestModuleForService("attributes")
# Load doge RPC
self.doge = self.bot.getBestModuleForService("dogerpc")
# Dict of #channel -> game object
self.games = {}
def gotMsg(self, args, prefix, trailing):
prefixObj = self.bot.decodePrefix(prefix)
# Ignore messages from users not logged in
loggedinfrom = self.attr.getAttribute(prefixObj.nick, "loggedinfrom")
if loggedinfrom==None:
# Send them a hint?
return
elif prefixObj.hostname == loggedinfrom:
if args[0][0] == "#":
# create a blank game obj if there isn't one (and whitelisted ? )
if not args[0] in self.games and (not self.config["channelWhitelistOn"] or (self.config["channelWhitelistOn"] and args[0][1:] in self.config["channelWhitelist"]) ):
self.games[args[0]]=gameObj(self, args[0])
# Channel message
self.games[args[0]].gotMsg(args, prefix, trailing)
else:
# Private message
#self.games[args[0].gotPrivMsg(args, prefix, trailing)
pass
else:
# Ignore potential spoofing
pass
def removeGame(self, channel):
del self.games[channel]
def ondisable(self):
self.log.info("DogeDice: Unload requested, ending games...")
while len(self.games)>0:
first = list(self.games.keys())[0]
self.games[first].gameover()
class gameObj:
def __init__(self, master, channel):
self.master = master
self.channel = channel
# Game state
# 0 = waiting for players
# - advertise self?
# - players must be registered and have enough doge for current bet
# 1 = enough players, countdown
# - Last warning to pull out
# 2 = locked in / game setup
# - Move doge from player's wallets to table wallet. kick players if they can't afford
# 3 = start of a round
# - Each player's turn to roll
# 4 = determine winner, move doge
# - if > 10 doge, house fee?
self.step = 0
# Bet amount
self.bet = 0.0
# players list
self.players = []
# min players
self.minPlayers = 2
# max players
self.maxPlayers = 4
# Lobby countdown timer
self.startCountdownTimer = None
# pre-result timer
self.endgameResultTimer = None
# in-game timeout
self.playTimeout = None
# Wallet for this game
self.walletName = None
def getPlayer(self, nick):
for player in self.players:
if player.nick == nick:
return player
return None
def gotPrivMsg(self, args, prefix, trailing):
prefix = self.master.bot.decodePrefix(prefix)
pass
def gotMsg(self, args, prefix, trailing):
prefix = self.master.bot.decodePrefix(prefix)
if self.step == 0 or self.step == 1:
# Join game
cmd = self.master.bot.messageHasCommand(".join", trailing)
if cmd:
if len(self.players)-1 < self.maxPlayers:
if self.getPlayer(prefix.nick)==None:
userWallet = self.master.attr.getAttribute(prefix.nick, "dogeaccountname")
if userWallet == None:
self.master.bot.act_PRIVMSG(self.channel, "%s: You don't have enough DOGE!" % (prefix.nick))
return
balance = self.master.doge.getBal(userWallet)
# check if the room is 'opened' already:
if len(self.players)==0:
# require an amount
if len(cmd.args)==1:
# Check if they have enough coins
try:
bet = float(cmd.args[0])
except:
return
if bet < self.master.config["minBet"]:
self.master.bot.act_PRIVMSG(self.channel, "%s: Minimum bet is %s DOGE!" % (prefix.nick, self.master.config["minBet"]))
return
if balance>=bet:
newPlayer = playerObj(self, prefix.nick)
newPlayer.dogeWalletName = userWallet
self.players.append(newPlayer)
self.bet = bet
self.master.bot.act_PRIVMSG(self.channel, "%s: You have joined!" % (prefix.nick))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: You don't have enough DOGE!" % (prefix.nick))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: You need to specify a bet amount: .join 10" % (prefix.nick))
else:
# no amount required
if balance>=self.bet:
newPlayer = playerObj(self, prefix.nick)
newPlayer.dogeWalletName = userWallet
self.players.append(newPlayer)
self.master.bot.act_PRIVMSG(self.channel, "%s: You have joined!" % (prefix.nick))
if self.canStart() and self.startCountdownTimer == None:
self.initStartCountdown()
self.master.bot.act_PRIVMSG(self.channel, "The game will start in %s seconds! Bet is %s DOGE each!" % (self.master.config["lobbyIdleSeconds"], self.bet))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: You don't have enough DOGE!" % (prefix.nick))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: you're already in the game. Quit with .leave" % (prefix.nick))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: the game is full (%s/%)! Cannot join." % (prefix.nick, len(self.players), self.maxPlayers))
# Leave game
cmd = self.master.bot.messageHasCommand(".leave", trailing)
if cmd:
if self.getPlayer(prefix.nick)==None:
self.master.bot.act_PRIVMSG(self.channel, "%s: You're not in the game." % (prefix.nick))
else:
self.removePlayer(prefix.nick)
self.master.bot.act_PRIVMSG(self.channel, "%s: You have left the game!" % (prefix.nick))
if not self.canStart() and self.startCountdownTimer:
self.clearTimer(self.startCountdownTimer)
self.startCountdownTimer = None
self.master.bot.act_PRIVMSG(self.channel, "Game start aborted." )
self.step = 0
elif self.step == 2:
pass
elif self.step == 3:
# Ignore cmds from people outside the game
player = self.getPlayer(prefix.nick)
if not player:
return
# handle a .roll
cmd = self.master.bot.messageHasCommand(".roll", trailing)
if cmd and not player.hasRolled:
roll1 = random.randint(1,6)
roll2 = random.randint(1,6)
self.master.bot.act_PRIVMSG(self.channel, "%s rolls %s and %s!" % (prefix.nick, roll1, roll2))
player.hasRolled = True
player.rollValue = roll1+roll2
# Check if all players have rolled
for player in self.players:
if not player.hasRolled:
return
# start endgame timer
self.step = 4
self.endgameResultTimer = Timer(2, self.endgameResults)
self.endgameResultTimer.start()
elif self.step == 4:
pass
#senderIsOp = self.master.attr.getAttribute(prefix.nick, "op")=="yes"
def clearTimer(self, timer):
if timer:
timer.cancel()
timer = None
def removePlayer(self, playerNick):
pos = -1
for i in range(0, len(self.players)):
if self.players[i].nick == playerNick:
pos = i
break
if pos >= 0:
self.players.pop(pos)
def canStart(self):
# Return true if the step is 'lobby' mode and player count is OK
return self.step == 0 and len(self.players)>=self.minPlayers
def initStartCountdown(self):
# Start the game-start countdown
self.startCountdownTimer = Timer(self.master.config["lobbyIdleSeconds"], self.lobbyCountdownDone)
self.startCountdownTimer.start()
self.step = 1
def lobbyCountdownDone(self):
self.step = 2
self.master.bot.act_PRIVMSG(self.channel, "Collecting DOGE and starting game.. Type .roll !")
# Make a wallet for this game
self.walletName = "DogeDice-"+self.channel
# Generate an address to 'create' a wallet
self.master.doge.getAcctAddr(self.walletName)
# Verify and move funds from each player
for player in self.players:
playerBalance = self.master.doge.getAcctBal(player.dogeWalletName)
if playerBalance < self.bet:
self.master.bot.act_PRIVMSG(self.channel, "%s was dropped from the game!")
self.removePlayer(player.nick)
if len(self.players) <= 1:
self.master.bot.act_PRIVMSG(self.channel, "1 or players left - game over!")
self.resetGame()
return
# Take doges
for player in self.players:
self.master.doge.move(player.dogeWalletName, self.walletName, self.bet)
# Pre-game setup (nothing !)
# Accept game commands
self.step = 3
# Start play timeout
self.playTimeout = Timer(30, self.gamePlayTimeoutExpired)
self.playTimeout.start()
def gamePlayTimeoutExpired(self):
# Time out - return doges
self.master.bot.act_PRIVMSG(self.channel, "Time expired! Returning all doges.")
if self.step == 3:
# In game step. Refund doges
for player in self.players:
self.master.doge.move(self.walletName, player.dogeWalletName, self.bet)
self.resetGame()
def endgameResults(self):
maxRollNames = []
maxRollValue = 0
for player in self.players:
if player.rollValue > maxRollValue:
maxRollNames = []
maxRollNames.append(player.nick)
maxRollValue = player.rollValue
if player.rollValue == maxRollValue:
if not player.nick in maxRollNames:
maxRollNames.append(player.nick)
pot = self.master.doge.getAcctBal(self.walletName)
DOGEeachDec = pot/len(maxRollNames)
DOGEeach = math.floor(DOGEeachDec*100000000) / 100000000
if len(maxRollNames)==1:
self.master.bot.act_PRIVMSG(self.channel, "We have a winner - %s! Winnings are: %s DOGE" % (maxRollNames[0], DOGEeach))
else:
self.master.bot.act_PRIVMSG(self.channel, "We have a tie between %s - The take is %s DOGE each" % (' and '.join(maxRollNames), DOGEeach))
# Pay out
for nick in maxRollNames:
player = self.getPlayer(nick)
self.master.doge.move(self.walletName, player.dogeWalletName, DOGEeach)
# the end!
self.resetGame()
def resetGame(self):
self.clearTimer(self.startCountdownTimer)
self.startCountdownTimer = None
self.clearTimer(self.endgameResultTimer)
self.endgameResultTimer = None
self.clearTimer(self.playTimeout)
self.playTimeout = None
self.master.removeGame(self.channel)
def gameover(self):
self.gamePlayTimeoutExpired()
class playerObj:
def __init__(self, game, nick):
self.game = game
self.nick = nick
# Save the player's wallet name
self.dogeWalletName = None
# Set to true after they roll
self.hasRolled = False
# Sum of their dice
self.rollValue = None

@ -0,0 +1,66 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
from bitcoinrpc.authproxy import AuthServiceProxy
class DogeRPC(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[]
self.services=["dogerpc"]
self.loadConfig()
self.rpc = DogeController(self)
def getBal(self, acct):
" get a balance of an address or an account "
return self.getAcctBal(acct)
def getAcctAddr(self, acct):
" returns the address for an account. creates if necessary "
self.rpc.ping()
addrs = self.rpc.con.getaddressesbyaccount(acct)
if len(addrs)==0:
return self.rpc.con.getnewaddress(acct)
return addrs[0]
def getAcctBal(self, acct):
" returns an account's balance"
self.rpc.ping()
return float(self.rpc.con.getbalance(acct))
def canMove(self, fromAcct, toAcct, amount):
" true or false if fromAcct can afford to give toAcct an amount of coins "
balfrom = self.getAcctBal(fromAcct)
return balfrom >= amount
def move(self, fromAcct, toAcct, amount):
" move coins from one account to another "
self.rpc.ping()
if self.canMove(fromAcct, toAcct, amount):
return self.rpc.con.move(fromAcct, toAcct, amount)
return False
def send(self, fromAcct, toAddr, amount):
" send coins to an external addr "
self.rpc.ping()
if self.canMove(fromAcct, toAddr, amount):
return self.rpc.con.sendfrom(fromAcct, toAddr, amount)
return False
class DogeController:
def __init__(self, master):
self.config = master.config
self.log = master.log
self.con = None
self.ping()
def ping(self):
try:
self.con.getinfo()
except:
self.connect()
def connect(self):
self.log.debug("DogeRPC: Connecting to dogecoind")
self.con = AuthServiceProxy("http://%s:%s@%s:%s" % (self.config["username"], self.config["password"], self.config["host"], self.config["port"]))
self.con.getinfo()
self.log.debug("DogeRPC: Connected to %s:%s" % (self.config["host"], self.config["port"]))

@ -0,0 +1,258 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
import random
import yaml
import os
import time
from threading import Timer
class DogeScramble(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
self.loadConfig()
# Load attribute storage
self.attr = None
serviceProviders = self.bot.getmodulesbyservice("attributes")
if len(serviceProviders)==0:
self.log.error("DogeScramble: Could not find a valid attributes service provider")
else:
self.log.info("DogeScramble: Selecting attributes service provider: %s" % serviceProviders[0])
self.attr = serviceProviders[0]
# Load doge RPC
self.doge = self.bot.getBestModuleForService("dogerpc")
# Per channel games
self.games = {}
def scramble(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
# Ignore messages from users without a dogewallet password
prefixObj = self.bot.decodePrefix(prefix)
if self.attr.getAttribute(prefixObj.nick, "password")==None:
return
if not channel in self.games:
self.games[channel]=scrambleGame(self, channel)
self.games[channel].scramble(args, prefix, trailing)
def ondisable(self):
self.log.info("DogeScramble: Unload requested, ending games...")
for game in self.games:
self.games[game].gameover()
class scrambleGame:
def __init__(self, master, channel):
self.master = master
self.channel = channel
# Running?
self.running = False
# Current word
self.currentWord = None
# Current word, scrambled
self.scrambled = None
# Online?
self.scrambleOn = False
# Count down to hints
self.hintTimer = None
# of hints given
self.hintsGiven = 0
# Cooldown between words
self.nextTimer = None
# How many guesses submitted this round
self.guesses = 0;
# How many games in a row where nobody guessed
self.gamesWithoutGuesses = 0;
# What file are we using
self.category_file = None;
# How many words in this category have been used?
self.category_count = 0
# How long between categories
self.change_category_after_words = self.master.config["categoryduration"]
# Should we change categories at the next pick?
self.should_change_category = True
# Holds the processed category name
self.category_name = None
# list of last picked words
self.lastwords = []
# name of last winner for decreasing return
self.lastwinner = None
self.lastwinvalue = 0
self.delayHint = self.master.config["hintDelay"];
self.delayNext = self.master.config["delayNext"];
self.maxHints = self.master.config["maxHints"];
self.abortAfterNoGuesses = self.master.config["abortAfterNoGuesses"];
def gameover(self):
self.clearTimers();
self.running = False
def clearTimers(self):
self.clearTimer(self.nextTimer)
self.clearTimer(self.hintTimer)
def clearTimer(self, timer):
if timer:
timer.cancel()
def scramble(self, args, prefix, trailing):
prefix = self.master.bot.decodePrefix(prefix)
sender = prefix.nick
senderIsOp = self.master.attr.getAttribute(prefix.nick, "op")=="yes"
cmd = self.master.bot.messageHasCommand(".scramble", trailing)
if cmd and not self.running:
#and senderIsOp
self.running = True
self.startScramble()
return
cmd = self.master.bot.messageHasCommand(".scrambleoff", trailing)
if cmd and senderIsOp and self.running:
self.gameover()
self.running = False
return
if self.currentWord and trailing.strip().lower() == self.currentWord:
# Get winner withdraw address
useraddr = self.master.attr.getAttribute(prefix.nick, "dogeaddr")
userwallet = self.master.attr.getAttribute(prefix.nick, "dogeaccountname")
self.master.bot.act_PRIVMSG(self.channel, "%s got the word - %s!" % (sender, self.currentWord))
if not useraddr:
self.master.bot.act_PRIVMSG(self.channel, "%s: to win DOGE, you must set an wallet address by PMing me \".setdogeaddr\". Next word in %s seconds." % (prefix.nick, self.delayNext))
else:
winamount = float(self.master.config["winAmount"])
if self.lastwinner == prefix.nick:
winamount = self.lastwinvalue * self.master.config["decreaseFactor"]
self.lastwinvalue = winamount
self.lastwinner = prefix.nick
self.master.bot.act_PRIVMSG(self.channel, "%s won %s DOGE! Next word in %s seconds." % (prefix.nick, round(winamount, 8), self.delayNext))
self.master.doge.move('', userwallet, winamount)
self.currentWord = None
self.clearTimers()
self.hintsGiven = 0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
self.guesses=0
self.category_count+=1
self.master.log.debug("DogeScramble: category_count is: %s" % (self.category_count))
if self.category_count >= self.change_category_after_words:
self.should_change_category = True
else:
self.guesses+=1
def startScramble(self):
self.clearTimer(self.nextTimer)
self.nextTimer = Timer(0, self.startNewWord)
self.nextTimer.start()
def startNewWord(self):
self.currentWord = self.pickWord()
self.scrambled = self.scrambleWord(self.currentWord)
self.master.bot.act_PRIVMSG(self.channel, "[Category: %s] Unscramble this: %s " % (self.category_name, self.scrambled))
self.clearTimer(self.hintTimer)
self.hintTimer = Timer(self.delayHint, self.giveHint)
self.hintTimer.start()
def giveHint(self):
self.hintsGiven+=1
if self.hintsGiven>=len(self.currentWord) or self.hintsGiven > self.maxHints:
self.abortWord()
return
blanks = ""
for letter in list(self.currentWord):
if letter == " ":
blanks+=" "
else:
blanks+="_"
partFromWord = self.currentWord[0:self.hintsGiven]
partFromBlanks = blanks[self.hintsGiven:]
hintstr = partFromWord+partFromBlanks
self.master.bot.act_PRIVMSG(self.channel, "Hint: - %s" % (hintstr))
self.clearTimer(self.hintTimer)
self.hintTimer = Timer(self.delayHint, self.giveHint)
self.hintTimer.start()
def abortWord(self):
cur = self.currentWord
self.currentWord = None
self.master.bot.act_PRIVMSG(self.channel, "Word expired - the answer was '%s'. Next word in %s seconds." % (cur, self.delayNext))
self.hintsGiven = 0
self.clearTimer(self.nextTimer)
if self.guesses==0:
self.gamesWithoutGuesses+=1
if self.gamesWithoutGuesses >= self.abortAfterNoGuesses:
self.master.bot.act_PRIVMSG(self.channel, "No one seems to be playing - type .scramble to start again.")
self.gameover()
return
else:
self.gamesWithoutGuesses=0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
def catFileNameToStr(self, s):
s=s.split(".")[0]
s=s.replace("_", " ")
return s.title()
def pickWord(self):
if self.should_change_category:
# clear flags
self.should_change_category = False
self.category_count = 0
# Get the path to word files dir
dirpath = self.master.getFilePath("")
# List dir
files = os.listdir(dirpath)
# choose a random file
random.shuffle(files)
self.category_file = files[0]
self.category_name = self.catFileNameToStr(self.category_file)
# Process the name & announce
self.master.bot.act_PRIVMSG(self.channel, "The category is now: %s " % self.category_name)
# count lines
f = open(self.master.getFilePath(self.category_file), "r")
lines = 0
while True:
lines+=1
if f.readline() == "":
break
f.close()
# change category
picked = ""
while picked == "" or picked in self.lastwords:
skip = random.randint(0, lines)
f = open(self.master.getFilePath(self.category_file), "r")
while skip>=0:
f.readline()
skip-=1
picked = f.readline().strip().lower()
f.close()
self.master.log.debug("DogeScramble: picked %s for %s" % (picked, self.channel))
self.lastwords.append(picked)
if len(self.lastwords) > 5:
self.lastwords.pop(0)
return picked
def scrambleWord(self, word):
scrambled = ""
for subword in word.split(" "):
scrambled+=self.scrambleIndividualWord(subword)+ " "
return scrambled.strip()
def scrambleIndividualWord(self, word):
scrambled = list(word)
random.shuffle(scrambled)
return ''.join(scrambled).lower()

@ -0,0 +1,164 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
import time
import hashlib
class DogeWallet(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.gotmsg)]
# Load attribute storage
self.attr = self.bot.getBestModuleForService("attributes")
# Load doge RPC
self.doge = self.bot.getBestModuleForService("dogerpc")
def gotmsg(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
# Ignore channel messages
pass
else:
self.handlePm(args, prefix, trailing)
def handlePm(self, args, prefix, trailing):
prefix = self.bot.decodePrefix(prefix)
cmd = self.bot.messageHasCommand(".setpass", trailing)
if cmd:
if len(cmd.args)==0:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: usage: \".setpass newpass\" or \".setpass oldpass newpass\"")
else:
oldpass = self.attr.getAttribute(prefix.nick, "password")
if oldpass == None:
self.attr.setAttribute(prefix.nick, "password", cmd.args[0])
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Your password has been set to \"%s\"." % cmd.args[0])
else:
if len(cmd.args)==2:
if cmd.args[0] == oldpass:
self.attr.setAttribute(prefix.nick, "password", cmd.args[1])
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Your password has been set to \"%s\"." % cmd.args[1])
else:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Old password incorrect.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: You must provide the old password when setting a new one.")
cmd = self.bot.messageHasCommand(".setdogeaddr", trailing)
if cmd:
userpw = self.attr.getAttribute(prefix.nick, "password")
if userpw==None:
self.bot.act_PRIVMSG(prefix.nick, ".setdogeaddr: You must first set a password with .setpass")
else:
if len(cmd.args)==2:
if userpw == cmd.args[0]:
self.attr.setAttribute(prefix.nick, "dogeaddr", cmd.args[1])
self.bot.act_PRIVMSG(prefix.nick, ".setdogeaddr: Your doge address has been set to \"%s\"." % cmd.args[1])
# if they don't have a wallet name, we'll make one now
if self.attr.getAttribute(prefix.nick, "dogeaccountname")==None:
randName = self.md5(str(time.time()))[0:10]
self.attr.setAttribute(prefix.nick, "dogeaccountname", randName)
else:
self.bot.act_PRIVMSG(prefix.nick, ".setdogeaddr: incorrect password.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".setdogeaddr: usage: \".setdogeaddr password address\" or \".setdogeaddr mypassword D8VNy3zkMGspffcFSWWqsxx7GrtVsmF2up\"")
cmd = self.bot.messageHasCommand(".getdogebal", trailing)
if cmd:
userpw = self.attr.getAttribute(prefix.nick, "password")
if userpw==None:
self.bot.act_PRIVMSG(prefix.nick, ".getdogebal: You must first set a password with .setpass")
else:
if len(cmd.args)==1:
if userpw == cmd.args[0]:
#################
walletname = self.attr.getAttribute(prefix.nick, "dogeaccountname")
amount = 0.0
if walletname:
amount = self.doge.getBal(walletname)
self.bot.act_PRIVMSG(prefix.nick, ".getdogebal: Your balance is: %s DOGE" % amount)
#################
else:
self.bot.act_PRIVMSG(prefix.nick, ".getdogebal: incorrect password.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".getdogebal: usage: \".getdogebal password\"")
cmd = self.bot.messageHasCommand(".withdrawdoge", trailing)
if cmd:
userpw = self.attr.getAttribute(prefix.nick, "password")
useraddr = self.attr.getAttribute(prefix.nick, "dogeaddr")
if userpw==None:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: You must first set a password with .setpass")
elif useraddr==None:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: You must first set a withdraw address .setdogeaddr")
else:
if len(cmd.args)==2:
if userpw == cmd.args[0]:
#################
walletname = self.attr.getAttribute(prefix.nick, "dogeaccountname")
walletbal = self.doge.getBal(walletname)
desiredAmount = float(cmd.args[1])
if walletbal >= desiredAmount:
txn = self.doge.send(walletname, useraddr, desiredAmount)
if txn:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: %s DOGE sent to %s. Transaction ID: %s"% (desiredAmount, useraddr, txn))
else:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: Unable to create transaction. Please contact an Operator.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: You only have %s DOGE. You cannot withdraw %s DOGE." % (walletbal, desiredAmount))
#################
else:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: incorrect password.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".withdrawdoge: usage: \".withdrawdoge password amount\" - \".withdrawdoge mypassword 5.0\" - ")
cmd = self.bot.messageHasCommand(".getdepositaddr", trailing)
if cmd:
userpw = self.attr.getAttribute(prefix.nick, "password")
if userpw==None:
self.bot.act_PRIVMSG(prefix.nick, ".getdepositaddr: You must first set a password with .setpass")
else:
if len(cmd.args)==1:
if userpw == cmd.args[0]:
#################
walletname = self.attr.getAttribute(prefix.nick, "dogeaccountname")
addr = self.doge.getAcctAddr(walletname)
self.bot.act_PRIVMSG(prefix.nick, ".getdepositaddr: Your deposit address is: %s" % addr)
#################
else:
self.bot.act_PRIVMSG(prefix.nick, ".getdepositaddr: incorrect password.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".getdepositaddr: usage: \".getdepositaddr password\"")
cmd = self.bot.messageHasCommand(".login", trailing)
if cmd:
userpw = self.attr.getAttribute(prefix.nick, "password")
if userpw==None:
self.bot.act_PRIVMSG(prefix.nick, ".login: You must first set a password with .setpass")
else:
if len(cmd.args)==1:
if userpw == cmd.args[0]:
#################
self.attr.setAttribute(prefix.nick, "loggedinfrom", prefix.hostname)
self.bot.act_PRIVMSG(prefix.nick, ".login: You have been logged in from: %s" % prefix.hostname)
#################
else:
self.bot.act_PRIVMSG(prefix.nick, ".login: incorrect password.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".login: usage: \".login password\"")
cmd = self.bot.messageHasCommand(".logout", trailing)
if cmd:
loggedin = self.attr.getAttribute(prefix.nick, "loggedinfrom")
if loggedin == None:
self.bot.act_PRIVMSG(prefix.nick, ".logout: You must first be logged in")
else:
self.attr.setAttribute(prefix.nick, "loggedinfrom", None)
self.bot.act_PRIVMSG(prefix.nick, ".logout: You have been logged out.")
def md5(self, data):
m = hashlib.md5()
m.update(data.encode("ascii"))
return m.hexdigest()

@ -0,0 +1,83 @@
#!/usr/bin/env python
from modulebase import ModuleBase,ModuleHook
import time
import hashlib
class NickUser(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.gotmsg)]
self.services=["login"]
def check(self, nick, hostname):
attr = self.bot.getBestModuleForService("attributes")
loggedin = attr.getAttribute(nick, "loggedinfrom")
if hostname==loggedin:
return True
return False
def ondisable(self):
pass
# TODO: log out all users
def gotmsg(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
# Ignore channel messages
pass
else:
self.handlePm(args, prefix, trailing)
def handlePm(self, args, prefix, trailing):
prefix = self.bot.decodePrefix(prefix)
cmd = self.bot.messageHasCommand(".setpass", trailing)
if cmd:
if len(cmd.args)==0:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: usage: \".setpass newpass\" or \".setpass oldpass newpass\"")
else:
attr = self.bot.getBestModuleForService("attributes")
oldpass = attr.getAttribute(prefix.nick, "password")
if oldpass == None:
attr.setAttribute(prefix.nick, "password", cmd.args[0])
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Your password has been set to \"%s\"." % cmd.args[0])
else:
if len(cmd.args)==2:
if cmd.args[0] == oldpass:
attr.setAttribute(prefix.nick, "password", cmd.args[1])
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Your password has been set to \"%s\"." % cmd.args[1])
else:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: Old password incorrect.")
else:
self.bot.act_PRIVMSG(prefix.nick, ".setpass: You must provide the old password when setting a new one.")
cmd = self.bot.messageHasCommand(".login", trailing)
if cmd:
attr = self.bot.getBestModuleForService("attributes")
userpw = attr.getAttribute(prefix.nick, "password")