Misc updates
This commit is contained in:
parent
d5ec1aa9a2
commit
67bfd29e4f
|
@ -1,5 +0,0 @@
|
||||||
minBet: .01
|
|
||||||
lobbyIdleSeconds: 15
|
|
||||||
channelWhitelistOn: True
|
|
||||||
channelWhitelist:
|
|
||||||
- test
|
|
|
@ -1,4 +0,0 @@
|
||||||
host: 127.0.0.1
|
|
||||||
username: root
|
|
||||||
password: root
|
|
||||||
port: 22555
|
|
|
@ -1,7 +0,0 @@
|
||||||
hintDelay: 15
|
|
||||||
delayNext: 5
|
|
||||||
maxHints: 5
|
|
||||||
abortAfterNoGuesses: 2
|
|
||||||
winAmount: 0.1
|
|
||||||
categoryduration: 2
|
|
||||||
decreaseFactor: 0.83
|
|
|
@ -1,5 +1,4 @@
|
||||||
hintDelay: 15
|
hintDelay: 15
|
||||||
delayNext: 5
|
delayNext: 5
|
||||||
maxHints: 5
|
maxHints: 5
|
||||||
abortAfterNoGuesses: 5
|
abortAfterNoGuesses: 5
|
||||||
decreaseFactor: 0.83
|
|
|
@ -70,7 +70,17 @@ class PyIRCBot(asynchat.async_chat):
|
||||||
|
|
||||||
def found_terminator(self):
|
def found_terminator(self):
|
||||||
" A complete command was pushed through, so clear the buffer and process it."
|
" A complete command was pushed through, so clear the buffer and process it."
|
||||||
self.process_data(self.getBuf().decode("UTF-8"))
|
line = None
|
||||||
|
buf = self.getBuf()
|
||||||
|
try:
|
||||||
|
line = buf.decode("UTF-8")
|
||||||
|
except UnicodeDecodeError as ude:
|
||||||
|
self.log.error("found_terminator(): could not decode input as UTF-8")
|
||||||
|
self.log.error("found_terminator(): data: %s" % line)
|
||||||
|
self.log.error("found_terminator(): repr(data): %s" % repr(line))
|
||||||
|
self.log.error("found_terminator(): error: %s" % str(ude))
|
||||||
|
return
|
||||||
|
self.process_data(line)
|
||||||
|
|
||||||
def handle_close(self):
|
def handle_close(self):
|
||||||
" called on socket shutdown "
|
" called on socket shutdown "
|
||||||
|
|
|
@ -17,36 +17,71 @@ class BotRPC(Thread):
|
||||||
self.server.register_function( self.unloadModule )
|
self.server.register_function( self.unloadModule )
|
||||||
self.server.register_function( self.reloadModule )
|
self.server.register_function( self.reloadModule )
|
||||||
self.server.register_function( self.redoModule )
|
self.server.register_function( self.redoModule )
|
||||||
self.server.register_function( self.getTraceback )
|
self.server.register_function( self.getLoadedModules )
|
||||||
|
self.server.register_function( self.pluginCommand )
|
||||||
|
self.server.register_function( self.setPluginVar )
|
||||||
|
self.server.register_function( self.getPluginVar )
|
||||||
|
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.server.serve()
|
self.server.serve()
|
||||||
|
|
||||||
|
|
||||||
def importModule(self, moduleName):
|
def importModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling importModule(%s)"%moduleName)
|
||||||
return self.bot.importmodule(moduleName)
|
return self.bot.importmodule(moduleName)
|
||||||
|
|
||||||
def deportModule(self, moduleName):
|
def deportModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling deportModule(%s)"%moduleName)
|
||||||
self.bot.deportmodule(moduleName)
|
self.bot.deportmodule(moduleName)
|
||||||
|
|
||||||
def loadModule(self, moduleName):
|
def loadModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling loadModule(%s)"%moduleName)
|
||||||
return self.bot.loadmodule(moduleName)
|
return self.bot.loadmodule(moduleName)
|
||||||
|
|
||||||
def unloadModule(self, moduleName):
|
def unloadModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling unloadModule(%s)"%moduleName)
|
||||||
self.bot.unloadmodule(moduleName)
|
self.bot.unloadmodule(moduleName)
|
||||||
|
|
||||||
def reloadModule(self, moduleName):
|
def reloadModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling reloadModule(%s)"%moduleName)
|
||||||
self.bot.unloadmodule(moduleName)
|
self.bot.unloadmodule(moduleName)
|
||||||
return self.bot.loadmodule(moduleName)
|
return self.bot.loadmodule(moduleName)
|
||||||
|
|
||||||
def redoModule(self, moduleName):
|
def redoModule(self, moduleName):
|
||||||
|
self.log.info("RPC: calling redoModule(%s)"%moduleName)
|
||||||
return self.bot.redomodule(moduleName)
|
return self.bot.redomodule(moduleName)
|
||||||
|
|
||||||
def getTraceback(self):
|
def getLoadedModules(self):
|
||||||
tb = str(traceback.format_exc())
|
self.log.info("RPC: calling getLoadedModules()")
|
||||||
print(tb)
|
return list(self.bot.moduleInstances.keys())
|
||||||
return tb
|
|
||||||
|
|
||||||
|
def pluginCommand(self, pluginName, methodName, argList):
|
||||||
|
plugin = self.bot.getmodulebyname(pluginName)
|
||||||
|
if not plugin:
|
||||||
|
return (False, "Plugin not found")
|
||||||
|
method = getattr(plugin, methodName)
|
||||||
|
if not method:
|
||||||
|
return (False, "Method not found")
|
||||||
|
self.log.info("RPC: calling %s.%s(%s)" % (pluginName, methodName, argList))
|
||||||
|
return (True, method(*argList))
|
||||||
|
|
||||||
|
def getPluginVar(self, pluginName, pluginVarName):
|
||||||
|
plugin = self.bot.getmodulebyname(pluginName)
|
||||||
|
if pluginName == "_core":
|
||||||
|
plugin = self.bot
|
||||||
|
if not plugin:
|
||||||
|
return (False, "Plugin not found")
|
||||||
|
self.log.info("RPC: getting %s.%s" % (pluginName, pluginVarName))
|
||||||
|
return (True, getattr(plugin, pluginVarName))
|
||||||
|
|
||||||
|
def setPluginVar(self, pluginName, pluginVarName, value):
|
||||||
|
plugin = self.bot.getmodulebyname(pluginName)
|
||||||
|
if pluginName == "_core":
|
||||||
|
plugin = self.bot
|
||||||
|
if not plugin:
|
||||||
|
return (False, "Plugin not found")
|
||||||
|
self.log.info("RPC: setting %s.%s = %s )" % (pluginName, pluginVarName, value))
|
||||||
|
setattr(plugin, pluginVarName, value)
|
||||||
|
return (True, "Var set")
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ class AttributeStorage(ModuleBase):
|
||||||
# self.getAttribute('xMopxShell', 'name')
|
# self.getAttribute('xMopxShell', 'name')
|
||||||
# self.setAttribute('xMopxShell', 'name', 'dave')
|
# self.setAttribute('xMopxShell', 'name', 'dave')
|
||||||
|
|
||||||
|
# SELECT `i`.`id`, `i`.`item`, `a`.`attribute`, `v`.`value` FROM `items` `i` INNER JOIN `values` `v` on `v`.`itemid`=`i`.`id` INNER JOIN `attribute` `a` on `a`.`id`=`v`.`attributeid` ORDER BY `i`.`id` ASC, `a`.`id` ASC LIMIT 1000 ;
|
||||||
|
|
||||||
def getItem(self, name):
|
def getItem(self, name):
|
||||||
c = self.db.connection.query("""SELECT
|
c = self.db.connection.query("""SELECT
|
||||||
|
|
|
@ -1,315 +0,0 @@
|
||||||
#!/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
|
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#!/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"]))
|
|
|
@ -1,258 +0,0 @@
|
||||||
#!/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()
|
|
|
@ -1,164 +0,0 @@
|
||||||
#!/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,63 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from modulebase import ModuleBase,ModuleHook
|
||||||
|
import re
|
||||||
|
from time import time
|
||||||
|
from urllib import request
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from bs4.element import Tag as bs_type_tag
|
||||||
|
|
||||||
|
class NyanThread(ModuleBase):
|
||||||
|
def __init__(self, bot, moduleName):
|
||||||
|
ModuleBase.__init__(self, bot, moduleName);
|
||||||
|
self.hooks=[ModuleHook("PRIVMSG", self.check)]
|
||||||
|
self.lastrun = 0
|
||||||
|
self.pagepattern = re.compile(r'<a class="navPages" href="https:\/\/bitcointalk\.org\/index\.php\?topic=403335\.([0-9]+)">([0-9]+)</a>')
|
||||||
|
self.messagepattern = re.compile(r'<span style="color: RED;">([^<]+)</span>', flags=re.IGNORECASE)
|
||||||
|
self.linkmessage = re.compile(r'<a href="https:\/\/bitcointalk\.org\/index\.php\?topic=403335\.msg([0-9]+)#msg([0-9]+)">')
|
||||||
|
|
||||||
|
def check(self, args, prefix, trailing):
|
||||||
|
if not args[0][0]=="#":
|
||||||
|
return
|
||||||
|
cmd = self.bot.messageHasCommand(".story", trailing)
|
||||||
|
if cmd:
|
||||||
|
if time() - self.lastrun < 10:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log.info("Nyanthread: fetching story...")
|
||||||
|
prefixObj = self.bot.decodePrefix(prefix)
|
||||||
|
page = request.urlopen("https://bitcointalk.org/index.php?topic=403335").read()
|
||||||
|
pages = self.pagepattern.findall(page.decode("ISO-8859-1"))
|
||||||
|
lastpage = pages[-1]
|
||||||
|
lastpagelink = "https://bitcointalk.org/index.php?topic=403335.%s" % lastpage[0]
|
||||||
|
self.log.info("Nyanthread: last page is %s" % lastpagelink)
|
||||||
|
page = request.urlopen(lastpagelink).read()
|
||||||
|
|
||||||
|
bs = BeautifulSoup(page)
|
||||||
|
|
||||||
|
body = bs.find('div', id="bodyarea")
|
||||||
|
thread = body.find('form', id="quickModForm")
|
||||||
|
posttable = thread.find('table', class_="bordercolor")
|
||||||
|
|
||||||
|
postTrs = []
|
||||||
|
for item in posttable:
|
||||||
|
postTrs.append(item)
|
||||||
|
|
||||||
|
postTrs.reverse()
|
||||||
|
|
||||||
|
for item in postTrs:
|
||||||
|
if type(item) == bs_type_tag:
|
||||||
|
message = item.find('div', class_="post")
|
||||||
|
if message:
|
||||||
|
redContent = self.messagepattern.findall(message.decode_contents())
|
||||||
|
if len(redContent)>0:
|
||||||
|
linkmessage = self.linkmessage.findall(item.decode_contents())
|
||||||
|
lastpagelink = "https://bitcointalk.org/index.php?topic=403335.msg%s#msg%s"%(linkmessage[0][0],linkmessage[0][0])
|
||||||
|
if len(linkmessage)>75:
|
||||||
|
continue
|
||||||
|
self.bot.act_PRIVMSG(args[0], "%s: %s - %s" % (prefixObj.nick, redContent[0], lastpagelink))
|
||||||
|
self.lastrun = time()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.bot.act_PRIVMSG(args[0], "%s: failed to read thread :(" % (prefixObj.nick))
|
||||||
|
self.lastrun = time()
|
||||||
|
return
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from modulebase import ModuleBase,ModuleHook
|
||||||
|
import sqlite3
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Seen(ModuleBase):
|
||||||
|
def __init__(self, bot, moduleName):
|
||||||
|
ModuleBase.__init__(self, bot, moduleName)
|
||||||
|
self.hooks=[ModuleHook("PRIVMSG", self.lastSeen)]
|
||||||
|
self.loadConfig()
|
||||||
|
# if the database doesnt exist, it will be created
|
||||||
|
sql = self.getSql()
|
||||||
|
c=sql.cursor()
|
||||||
|
# check if our table exists
|
||||||
|
c.execute("SELECT * FROM SQLITE_MASTER WHERE `type`='table' AND `name`='seen'")
|
||||||
|
if len(c.fetchall())==0:
|
||||||
|
self.log.info("Seen: Creating database")
|
||||||
|
# if no, create it.
|
||||||
|
c.execute("CREATE TABLE `seen` (`nick` VARCHAR(32), `date` INTEGER, PRIMARY KEY(`nick`))");
|
||||||
|
self.x = "asdf"
|
||||||
|
|
||||||
|
def lastSeen(self, args, prefix, trailing):
|
||||||
|
# using a message to update last seen, also, the .seen query
|
||||||
|
prefixObj = self.bot.decodePrefix(prefix)
|
||||||
|
nick = prefixObj.nick
|
||||||
|
sql=self.getSql()
|
||||||
|
c = sql.cursor()
|
||||||
|
# update or add the user's row
|
||||||
|
datest=str( time.time()+(int(self.config["add_hours"])*60*60))
|
||||||
|
c.execute("REPLACE INTO `seen` (`nick`, `date`) VALUES (?, ?)", (nick.lower(), datest ))
|
||||||
|
self.log.info("Seen: %s on %s" % (nick.lower(), datest))
|
||||||
|
sql.commit()
|
||||||
|
if trailing.startswith(".seen"):
|
||||||
|
cmdargs = trailing.split(" ");
|
||||||
|
# query the DB for the user
|
||||||
|
if len(cmdargs)>=2:
|
||||||
|
searchnic = cmdargs[1].lower();
|
||||||
|
c.execute("SELECT * FROM `seen` WHERE `nick`= ? ", [searchnic])
|
||||||
|
rows = c.fetchall()
|
||||||
|
if len(rows)==1:
|
||||||
|
self.bot.act_PRIVMSG(args[0], "I last saw %s on %s (%s)."% (cmdargs[1], time.strftime("%m/%d/%y at %I:%M %p", time.localtime(rows[0]['date'])), self.config["timezone"]));
|
||||||
|
else:
|
||||||
|
self.bot.act_PRIVMSG(args[0], "Sorry, I haven't seen %s!" % cmdargs[1])
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
def getSql(self):
|
||||||
|
# return a SQL reference to the database
|
||||||
|
path = self.getFilePath('database.sql3')
|
||||||
|
sql = sqlite3.connect(path);
|
||||||
|
sql.row_factory = self.dict_factory
|
||||||
|
return sql
|
||||||
|
|
||||||
|
def dict_factory(self, cursor, row):
|
||||||
|
# because Lists suck for database results
|
||||||
|
d = {}
|
||||||
|
for idx, col in enumerate(cursor.description):
|
||||||
|
d[col[0]] = row[idx]
|
||||||
|
return d
|
||||||
|
|
||||||
|
def test(self, arg):
|
||||||
|
print("TEST: %s" % arg)
|
||||||
|
print("self.x = %s" % self.x)
|
||||||
|
return arg
|
||||||
|
|
Loading…
Reference in New Issue