Remove yaml, convert all configs to json

This commit is contained in:
dave 2015-11-01 17:40:13 -08:00
parent bdf0081ba8
commit f6404047cf
52 changed files with 1517 additions and 1034 deletions

View File

@ -3,6 +3,10 @@
Module capable of operating Bitcoind-style RPC. Provided as a service.
.. note:: This module requires installation of some :doc:`optional dependencies </setup/dependencies>`:
* bitcoinrpc
Class Reference
---------------

View File

@ -1,7 +1,14 @@
:mod:`DogeRPC` --- A dogecoind RPC service
==========================================
This module provides a service for interacting with dogecoind.
This module provides a service called ``dogerpc`` for interacting with dogecoind.
.. note:: This module requires installation of some :doc:`optional dependencies </setup/dependencies>`:
* bitcoinrpc
A dogecoin daemon is required to use this module. It must be configured to
allow RPC connections.
Class Reference
---------------
@ -10,3 +17,5 @@ Class Reference
:members:
:undoc-members:
:show-inheritance:

View File

@ -2,7 +2,67 @@
=========================================================
This module provides a word scrambling game that rewards winners with small
amounts of Dogecoin
amounts of Dogecoin. Requires a ``dogerpc`` service provider such as
:doc:`DogeRPC </api/modules/dogerpc>`.
Config
------
.. code-block:: json
{
"hintDelay": 15,
"delayNext": 5,
"maxHints": 5,
"abortAfterNoGuesses": 2,
"categoryduration": 10,
"winAmount": 5,
"decreaseFactor": 0.75
}
In addition to the json config above, additional categories of words may be
added by adding additional text files to the DogeScramble data dir.
.. cmdoption:: hintDelay
Seconds between hints if the word is not guessed
.. cmdoption:: delayNext
Delay in seconds between the end of one round and start of the next
.. cmdoption:: maxHints
How many letters will be hinted before the word is thrown away
.. cmdoption:: abortAfterNoGuesses
How many rounds may pass with no players guessing. Once this count is
passed, the game is automatically stopped.
.. cmdoption:: categoryduration
Number of words used from a category before changing the category
.. cmdoption:: winAmount
Amount of dogecoin to send the winner
.. cmdoption:: decreaseFactor
For subsequent wins by the same player, the reward will be the previous
reward multiplied times this number
Commands
--------
.. cmdoption:: .scramble
Start the unscramble game
.. cmdoption:: .scrambleoff
Stop the unscramble game
Class Reference
---------------

View File

@ -1,7 +1,21 @@
:mod:`DuckHunt` --- Duckhunt game
=================================
An animal hunting IRC game
Example usage:
.. code-block:: none
3:15:06 PM <pyircbot3> \_o< Quack!
3:15:08 PM <@dave-irccloud> !shoot
3:15:08 PM <pyircbot3> dave-irccloud fires after 1.73 seconds and misses!
3:15:09 PM <@dave-irccloud> !shoot
3:15:10 PM <pyircbot3> dave-irccloud fires after 3.83 seconds and misses!
3:15:11 PM <@dave-irccloud> !shoot
3:15:11 PM <pyircbot3> dave-irccloud bags a 2.63 lb Duck in 4.92 seconds!
3:15:19 PM <@dave-irccloud> !huntscore
<< in pm >>
3:15:19 PM <pyircbot3> 0 prime catches, 0 runts, 3 bullets used and 2 misses.
3:15:20 PM <pyircbot3> You've shot 1 Ducks for a total weight of 2.63 lbs.
Class Reference
---------------

View File

@ -1,5 +1,21 @@
:mod:`Scramble` --- Module to provide a word scramble game
==========================================================
:mod:`Scramble` --- Word scramble game module
=============================================
Example usage:
.. code-block:: none
3:04:00 PM <@dave-irccloud> .scrambleon
3:04:00 PM <pyircbot3> New word - leppa
3:04:15 PM <pyircbot3> Hint: - a____
3:04:30 PM <pyircbot3> Hint: - ap___
3:04:32 PM <@dave-irccloud> apple
3:04:32 PM <pyircbot3> dave-irccloud guessed the word - apple! dave-irccloud now has 3 points. Next word in 5 seconds.
3:04:35 PM <@dave-irccloud> .scrambleoff
3:04:39 PM <@dave-irccloud> .scramble top
3:04:39 PM <pyircbot3> Top 1: dave-irccloud: 3
Requires a dictionary to pull words from, ``words.txt`` should be placed in: ``./datadir/data/Scramble/``
Class Reference
---------------

View File

@ -1,7 +1,7 @@
Setup Tutorial
==============
Installing and runnig PyIRCBot requires installing the needed dependancies and
Installing and runnig PyIRCBot requires installing the needed dependencies and
providing some environmental information about where the bot is being run.
Contents:
@ -9,6 +9,6 @@ Contents:
.. toctree::
:maxdepth: 8
dependancies.rst
dependencies.rst
initial_config.rst
running.rst

View File

@ -1,5 +1,5 @@
************
Dependancies
Dependencies
************
PyIRCBot is designed to run on Python 3, and is usually tested with 3.4. Python
@ -23,3 +23,10 @@ them.
- **bitcoinrpc** - https://github.com/jgarzik/python-bitcoinrpc
- **pymysql** - https://github.com/dpedu/MySQL-for-Python-3 (needs \
libmysqlclient-dev on your system)
At time of writing there is a bug that will prevent the bitcoinrpc module from
working with Python 3. When pull `#55`_ is merged, the bug will be fixed.
Until then, using my `fork`_ is recommended.
.. _#55: https://github.com/jgarzik/python-bitcoinrpc/pull/55
.. _fork: https://github.com/dpedu/python-bitcoinrpc

View File

@ -0,0 +1,3 @@
{
"cache": 300
}

View File

@ -1 +0,0 @@
cache: 300

View File

@ -0,0 +1,16 @@
{
"allowDelete": true,
"delaySubmit": 0,
"delayCalc": 0,
"delayCalcSpecific": 0,
"delayMatch": 0,
"cmd_calc": [
".calc",
"calc",
".quote"
],
"cmd_match": [
".match",
"match"
]
}

View File

@ -1,12 +0,0 @@
allowDelete: true
delaySubmit: 0
delayCalc: 0
delayCalcSpecific: 0
delayMatch: 0
cmd_calc:
- .calc
- calc
- .quote
cmd_match:
- .match
- match

View File

@ -0,0 +1,26 @@
{
"types": {
"LTC": {
"name": "Litecoin",
"abbr": "LTC",
"host": "127.0.0.1",
"username": "user",
"password": "pass",
"port": 12893,
"precision": 8,
"reserve": 0.01,
"link": "https://litecoin.org/"
},
"BTC": {
"name": "Bitcoin",
"abbr": "BTC",
"host": "127.0.0.1",
"username": "user",
"password": "pass",
"port": 48191,
"precision": 8,
"reserve": 0.001,
"link": "http://bitcoin.org/"
}
}
}

View File

@ -1,21 +0,0 @@
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/

View File

@ -0,0 +1,9 @@
{
"minBet": 0.01,
"lobbyIdleSeconds": 15,
"channelWhitelistOn": true,
"channelWhitelist": [
"dogegamestest",
"test"
]
}

View File

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

View File

@ -0,0 +1,6 @@
{
"host": "127.0.0.1",
"username": "wallet_rpc_user",
"password": "wallet_rpc_pass",
"port": 22555
}

View File

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

View File

@ -0,0 +1,9 @@
{
"hintDelay": 15,
"delayNext": 5,
"maxHints": 5,
"abortAfterNoGuesses": 2,
"categoryduration": 10,
"winAmount": 5,
"decreaseFactor": 0.75
}

View File

@ -0,0 +1,17 @@
{
"delayMin": 5,
"delayMax": 15,
"missChance": 50,
"animal": "\\_o< Quack!",
"animalSpecies": "Duck",
"animalSpeciesPlural": "Ducks",
"animalNameMale": "Duck",
"animalNameFemale": "Duck",
"runtChance": 10,
"primeChance": 5,
"weightMin": 2.5,
"weightMax": 3.5,
"weightRunt": 1.5,
"weightFat": 5,
"activeChannel": "##xmopx"
}

View File

@ -1,15 +0,0 @@
delayMin: 5
delayMax: 15
missChance: 50
animal: "\\_o< Quack!"
animalSpecies: "Duck"
animalSpeciesPlural: "Ducks"
animalNameMale: "Duck"
animalNameFemale: "Duck"
runtChance: 10
primeChance: 5
weightMin: 2.5
weightMax: 3.5
weightRunt: 1.5
weightFat: 5.0
activeChannel: "#xmopx"

View File

@ -0,0 +1,6 @@
{
"channelWhitelistOn": true,
"channelWhitelist": [
"test"
]
}

View File

@ -1,3 +0,0 @@
channelWhitelistOn: True
channelWhitelist:
- test

View File

@ -0,0 +1,13 @@
{
"limit": 25,
"recv_msg": "Oh, thanks, I'll keep %(adjective)s%(item)s safe",
"inv_msg": "\u0000\u0001ACTION is carrying %(itemlist)s\u0000\u0001",
"swap_msg": "\u0000\u0001ACTION takes %(adjective)s%(recv_item)s but drops %(drop_item)s\u0000\u0010",
"dupe_msg": "No thanks, I've already got %(item)s",
"adjectives": [
"some",
"the",
"an",
"these"
]
}

View File

@ -1,10 +0,0 @@
limit: 25
recv_msg: "Oh, thanks, I'll keep %(adjective)s%(item)s safe"
inv_msg: "\x01ACTION is carrying %(itemlist)s\x01"
swap_msg: "\x01ACTION takes %(adjective)s%(recv_item)s but drops %(drop_item)s\x10"
dupe_msg: "No thanks, I've already got %(item)s"
adjectives:
- some
- the
- an
- these

View File

@ -0,0 +1,6 @@
{
"host": "localhost",
"username": "root",
"password": "root",
"database": "pyircbot"
}

View File

@ -1,4 +0,0 @@
host: 10.0.3.14
username: root
password: root
database: pyircbot_dev

View File

@ -0,0 +1,3 @@
{
"cache": 90
}

View File

@ -1 +0,0 @@
cache: 90

View File

@ -0,0 +1,3 @@
{
"limit": 10000
}

View File

@ -1 +0,0 @@
limit: 10000

View File

@ -0,0 +1,4 @@
{
"mytimezone": "US/Pacific",
"precision": 5
}

View File

@ -1,2 +0,0 @@
mytimezone: US/Pacific
precision: 5

View File

@ -0,0 +1,6 @@
{
"hintDelay": 15,
"delayNext": 5,
"maxHints": 5,
"abortAfterNoGuesses": 5
}

View File

@ -1,4 +0,0 @@
hintDelay: 15
delayNext: 5
maxHints: 5
abortAfterNoGuesses: 5

View File

@ -0,0 +1,4 @@
{
"timezone": "EST",
"add_hours": 0
}

View File

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

View File

@ -19,7 +19,7 @@
"ghost_cmd":"ghost %(nick)s %(password)s"
},
"channels":[
"#xmopx"
"##xmopx"
],
"privatechannels":{
"to":"chanserv",

View File

@ -0,0 +1,4 @@
{
"max": 10,
"maxage": 2678400
}

View File

@ -1,2 +0,0 @@
max: 10
maxage: 2678400

View File

@ -0,0 +1,4 @@
{
"apikey": "get an API key at: http://www.wunderground.com/weather/api/ (choose 'anvil')",
"defaultUnit": "c"
}

View File

@ -1,2 +0,0 @@
apikey: "get an API key at: http://www.wunderground.com/weather/api/ (choose \"anvil\")"
defaultUnit: c

View File

@ -0,0 +1,313 @@
Air
Stone
Grass
Dirt
Cobblestone
Wooden Plank
Sapling
Redwood Sapling
Birch Sapling
Bedrock
Water
Lava
Sand
Gravel
Gold Ore
Iron Ore
Coal Ore
Wood
Redwood
Birchwood
Leaves
Redwood Leaves
Birchwood Leaves
Sponge
Glass
Lapis Lazuli Ore
Lapis Lazuli Block
Dispenser
Sandstone
Note Block
Bed Block
Powered Rail
Detector Rail
Sticky Piston
Web
Dead Shrub
Tall Grass
Live Shrub
Dead Shrub
Piston
Piston Head
White Wool
Orange Wool
Magenta Wool
Light Blue Wool
Yellow Wool
Light Green Wool
Pink Wool
Gray Wool
Light Gray Wool
Cyan Wool
Purple Wool
Blue Wool
Brown Wool
Dark Green Wool
Red Wool
Black Wool
Dandelion
Rose
Brown Mushroom
Red Mushroom
Gold Block
Iron Block
Double Stone Slab
Double Sandstone Slab
Double Wooden Slab
Double Cobblestone Slab
Double Brick Slab
Double Stone Brick Slab
Stone Slab
Sandstone Slab
Wooden Slab
Cobblestone Slab
Brick Slab
Stone Brick Slab
Brick
TNT
Bookshelf
Mossy Cobblestone
Obsidian
Torch
Fire
Monster Spawner
Wooden Stairs
Chest
Redstone Wire
Diamond Ore
Diamond Block
Workbench
Wheat Crops
Soil
Furnace
Sign Post
Wooden Door
Ladder
Rails
Cobblestone Stairs
Wall Sign
Lever
Stone Pressure Plate
Iron Door Block
Wooden Pressure Plate
Redstone Ore
Redstone Torch
Stone Button
Snow
Ice
Snow Block
Cactus
Clay
Sugar Cane
Jukebox
Fence
Pumpkin
Netherrack
Soul Sand
Glowstone
Portal
Jack-O-Lantern
Cake Block
Redstone Repeater Block
Locked Chest
Trapdoor
Stone (Silverfish)
Stone Brick
Mossy Stone Brick
Cracked Stone Brick
Red Mushroom Cap
Brown Mushroom Cap
Iron Bars
Glass Pane
Melon Block
Pumpkin Stem
Melon Stem
Vines
Fence Gate
Brick Stairs
Stone Brick Stairs
Mycelium
Lily Pad
Nether Brick
Nether Brick Fence
Nether Brick Stairs
Nether Wart
Iron Shovel
Iron Pickaxe
Iron Axe
Flint and Steel
Apple
Bow
Arrow
Coal
Charcoal
Diamond
Iron Ingot
Gold Ingot
Iron Sword
Wooden Sword
Wooden Shovel
Wooden Pickaxe
Wooden Axe
Stone Sword
Stone Shovel
Stone Pickaxe
Stone Axe
Diamond Sword
Diamond Shovel
Diamond Pickaxe
Diamond Axe
Stick
Bowl
Mushroom Soup
Gold Sword
Gold Shovel
Gold Pickaxe
Gold Axe
String
Feather
Sulphur
Wooden Hoe
Stone Hoe
Iron Hoe
Diamond Hoe
Gold Hoe
Wheat Seeds
Wheat
Bread
Leather Helmet
Leather Chestplate
Leather Leggings
Leather Boots
Chainmail Helmet
Chainmail Chestplate
Chainmail Leggings
Chainmail Boots
Iron Helmet
Iron Chestplate
Iron Leggings
Iron Boots
Diamond Helmet
Diamond Chestplate
Diamond Leggings
Diamond Boots
Gold Helmet
Gold Chestplate
Gold Leggings
Gold Boots
Flint
Raw Porkchop
Cooked Porkchop
Painting
Golden Apple
Sign
Wooden Door
Bucket
Water Bucket
Lava Bucket
Minecart
Saddle
Iron Door
Redstone
Snowball
Boat
Leather
Milk Bucket
Clay Brick
Clay Balls
Sugarcane
Paper
Book
Slimeball
Storage Minecart
Powered Minecart
Egg
Compass
Fishing Rod
Clock
Glowstone Dust
Raw Fish
Cooked Fish
Ink Sack
Rose Red
Cactus Green
Coco Beans
Lapis Lazuli
Purple Dye
Cyan Dye
Light Gray Dye
Gray Dye
Pink Dye
Lime Dye
Dandelion Yellow
Light Blue Dye
Magenta Dye
Orange Dye
Bone Meal
Bone
Sugar
Cake
Bed
Redstone Repeater
Cookie
Map
Shears
Melon
Pumpkin Seeds
Melon Seeds
Raw Beef
Steak
Raw Chicken
Cooked Chicken
Rotten Flesh
Ender Pearl
Blaze Rod
Ghast Tear
Gold Nugget
Nether Wart Seeds
Potion
Glass Bottle
Spider Eye
Fermented Spider Eye
Blaze Powder
Magma Cream
Gold Music Disc
Green Music Disc
Chicken
Cow
Mooshroom
Ocelot
Pig
Sheep
Squid
Villager
Enderman
Wolf
Zombie Pigman
Wolf
Ocelot
Blaze
Cave Spider
Creeper
Ghast
Magma Cube
Silverfish
Skeleton
Slime
Spider
Spider Jockey
Zombie
Snow Golem
Iron Golem
Ender Dragon
Rana

View File

@ -34,7 +34,7 @@ class ModuleBase:
here"""
self.config={}
"""Configuration dictionary. Autoloaded from `%(datadir)s/%(modulename)s.yml`"""
"""Configuration dictionary. Autoloaded from `%(datadir)s/%(modulename)s.json`"""
self.log = logging.getLogger("Module.%s" % self.moduleName)
"""Logger object for this module"""
@ -57,7 +57,7 @@ class ModuleBase:
pass
def getConfigPath(self):
"""Returns the absolute path of this module's YML config file"""
"""Returns the absolute path of this module's json config file"""
return self.bot.getConfigPath(self.moduleName)
def getFilePath(self, f=None):

474
pyircbot/modules/CardsAgainstHumanity.py Normal file → Executable file
View File

@ -6,7 +6,6 @@
"""
from pyircbot.modulebase import ModuleBase,ModuleHook
import yaml
import os
import time
from threading import Timer
@ -14,243 +13,242 @@ from operator import itemgetter
from random import choice
class CardsAgainstHumanity(ModuleBase):
def __init__(self, bot, moduleName):
# init the base module
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
self.loadConfig()
# Dictionary
self.whitesFile = open(self.getFilePath("answers.txt"),'r')
self.blacksFile = open(self.getFilePath("questions.txt"),'r')
self.whites = [line.rstrip() for line in self.whitesFile]
self.blacks = [line.rstrip() for line in self.blacksFile]
self.currentBlack = ""
self.whitesFile.close()
self.blacksFile.close()
self.log.info("CAH: Loaded."+str(len(self.whites))+" White Cards "+str(len(self.blacks))+" Black Cards")
# Per channel games
self.games = {}
def scramble(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
if not channel in self.games:
self.games[channel]=cardsGame(self, channel,self.whites,self.blacks)
self.games[channel].stuff(args, prefix, trailing)
def ondisable(self):
self.log.info("CAH: Unload requested, ending games...")
# for game in self.games:
# self.games[game].gameover()
def __init__(self, bot, moduleName):
# init the base module
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
# Dictionary
self.whitesFile = open(self.getFilePath("answers.txt"),'r')
self.blacksFile = open(self.getFilePath("questions.txt"),'r')
self.whites = [line.rstrip() for line in self.whitesFile]
self.blacks = [line.rstrip() for line in self.blacksFile]
self.currentBlack = ""
self.whitesFile.close()
self.blacksFile.close()
self.log.info("CAH: Loaded."+str(len(self.whites))+" White Cards "+str(len(self.blacks))+" Black Cards")
# Per channel games
self.games = {}
def scramble(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
if not channel in self.games:
self.games[channel]=cardsGame(self, channel,self.whites,self.blacks)
self.games[channel].stuff(args, prefix, trailing)
def ondisable(self):
self.log.info("CAH: Unload requested, ending games...")
# for game in self.games:
# self.games[game].gameover()
class cardsGame:
def __init__(self, master, channel,whites,blacks):
self.master = master
self.channel = channel
# Running?
self.running = False
# Current word
# self.message = 'xmopxshell has downs'
self.players = {}
self.timers = {}
self.whites = whites
self.blacks = blacks
self.lastCzar = -1
self.czar = ""
self.started = False
self.active = False
self.allowPick = 0
self.choices = {}
self.czarTimer = None
def stuff(self, args, prefix, trailing):
prefix = self.master.bot.decodePrefix(prefix)
sender = prefix.nick
if self.master.bot.messageHasCommand(".joinGame", trailing):
self.join(sender)
elif self.master.bot.messageHasCommand(".ready",trailing):
result = self.markReady(sender)
if result:
self.started = True
self.master.bot.act_PRIVMSG(self.channel,"All players are ready!")
for player in self.players:
self.master.bot.act_PRIVMSG(player,"ITS TIME TO D-D-D-D-D-DUEL!")
self.players[player]=[]
for player in self.players:
self.deal(player)
self.sendCards(player)
self.active = True
self.makeTurn()
elif self.master.bot.messageHasCommand(".pick",trailing):
if self.active:
if sender != self.czar:
print(sender,self.czar)
print(sender != self.czar)
if self.allowPick > 0:
if sender in self.players:
cards = trailing.split(' ')[1:]
if len(cards)==self.allowPick:
if self.checkBounds(cards):
if sender not in self.choices:
cardChoices = [self.players[sender][int(index)] for index in cards]
print(cardChoices)
self.choices[sender] = cardChoices
self.removeAndReplenishCards(sender, cardChoices)
self.sendCards(sender)
del self.choices[sender]
if sender in timers:
self.timers[sender].cancel()
if self.allDrawn():
self.readChoices()
self.master.bot.act_PRIVMSG(self.channel,self.czar+"! Please choose the winner!")
czarTimer = Timer(180,self.kick,(self.czar,"taking too long to pick a choice. The next turn iwll be made."))
self.makeTurn()
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked a card that was out of the range. Please don't do that.")
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked "+str(len(cards))+" cards. You were supposed to pick "+str(self.allowPick))
elif self.master.bot.messageHasCommand(".choose",trailing):
if sender==self.czar:
choice = trailing.split()[1:]
if len(choice)==1:
if self.checkChoiceBounds(int(choice[0])):
self.master.bot.act_PRIVMSG(self.channel,list(self.choices.keys())[int(choice[0])]+", you won the round!")
if self.czarTimer!=None:
self.czarTimer.cancel()
self.makeTurn()
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", your choice was out of the range. Please don't do that.")
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked "+str(len(choice))+" "+" winners. You were only supposed to pick 1.")
elif self.master.bot.messageHasCommand('.leave',trailing):
if sender in self.players:
self.kick(sender,'choosing to leave the game you dolt')
if sender is self.czar:
self.makeTurn()
def join(self,nick):
if not self.started:
if nick not in self.players:
self.players[nick]=False
self.master.bot.act_PRIVMSG(self.channel, nick+" has joined the game! | The players currently are "+str(self.players))
else:
print("the game has already started!")
self.master.bot.act_PRIVMSG(self.channel,"The game has already started!")
def markReady(self,nick):
if not self.started:
if nick in self.players:
self.players[nick]=True
for player in self.players:
print(player)
if not self.players[player]:
print (player+" not ready")
return False
return True
else:
self.master.bot.act_PRIVMSG(self.channel, "You are not in the game! Type .joinGame!")
else:
print("game has already started!")
self.master.bot.act_PRIVMSG(self.channel,"The game has already started!")
def deal(self,nick):
self.players[nick] = [self.pickWhite() for i in range (7)]
def pickWhite(self):
card = choice(self.whites)
self.whites.remove(card)
return card
def pickBlack(self):
card = choice(self.blacks)
self.blacks.remove(card)
return card
def sendCards(self,nick):
cards = ""
for card in self.players[nick]:
cards+=str(self.players[nick].index(card))+". "
cards+=card+" "
self.master.bot.act_PRIVMSG(nick,"Your cards are "+cards)
def readCard(self,card):
count = card.count('_')
if count == 0:
if 'haiku' in card:
count = 3
else:
count = 1
self.master.bot.act_PRIVMSG(self.channel,"The black card is \""+card+"\" Pick "+str(count))
return count
def pickCzar(self):
index = self.lastCzar+1
if index < len(self.players):
self.lastCzar = index
return index
else:
self.lastCzar = 0
return 0
def announceCzar(self):
self.master.bot.act_PRIVMSG(self.channel,"The Czar is "+self.czar+"!")
def checkBounds(self,cards):
for item in cards:
if int(item)>6 or int(item)<0:
return False
return True
def checkChoiceBounds(self,choice):
if choice<0 or choice>len(self.choices)-1:
return False
return True
def makeTurn(self):
self.choices.clear()
card = self.pickBlack()
self.timers.clear()
self.currentBlack = card
self.allowPick = self.readCard(card)
self.lastCzar = self.pickCzar()
self.czar = list(self.players.keys())[self.lastCzar]
print (self.lastCzar,self.czar)
for player in self.players:
if player!=self.czar:
self.timers[player] = Timer(180,self.kick,(player,"taking more than 180 seconds for their turn."))
self.timers[player].start()
self.announceCzar()
def kick(self,nick,reason):
del self.players[nick]
if nick in self.timers:
self.timers[nick].cancel()
del self.timers[nick]
self.master.bot.act_PRIVMSG(self.channel,nick+" has been kicked due to "+reason)
if len(self.players)<=1:
self.master.bot.act_PRIVMSG(self.channel,"The game is being shut down due to having <=1 players")
self.started = False
self.active = False
for timer in self.timers:
timer.cancel()
self.timers.clear()
self.players.clear()
def removeAndReplenishCards(self,nick,cards):
for card in cards:
self.players[nick].remove(card)
self.players[nick].append(self.pickWhite())
def readChoices(self):
if '_' in self.currentBlack:
for player in list(self.choices.keys()):
cardInstance = str(list(self.choices.keys()).index(player))+". "+self.currentBlack
cardInstance = list(cardInstance) #do this as opposed to space to preserve spaces
for choice in self.choices[player]:
for char in cardInstance:
if char=='_':
print(char)
choice = choice.replace('.','')
cardInstance[cardInstance.index(char)] = choice
break
self.master.bot.act_PRIVMSG(self.channel,''.join(cardInstance))
else:
for player in self.choices:
self.master.bot.act_PRIVMSG(self.channel,self.currentBlack+' '+' '.join(self.choices[player]))
def allDrawn(self):
for player in self.players:
if player not in self.choices:
if player != self.czar:
return False
return True
def __init__(self, master, channel,whites,blacks):
self.master = master
self.channel = channel
# Running?
self.running = False
# Current word
# self.message = 'xmopxshell has downs'
self.players = {}
self.timers = {}
self.whites = whites
self.blacks = blacks
self.lastCzar = -1
self.czar = ""
self.started = False
self.active = False
self.allowPick = 0
self.choices = {}
self.czarTimer = None
def stuff(self, args, prefix, trailing):
prefix = self.master.bot.decodePrefix(prefix)
sender = prefix.nick
if self.master.bot.messageHasCommand(".joinGame", trailing):
self.join(sender)
elif self.master.bot.messageHasCommand(".ready",trailing):
result = self.markReady(sender)
if result:
self.started = True
self.master.bot.act_PRIVMSG(self.channel,"All players are ready!")
for player in self.players:
self.master.bot.act_PRIVMSG(player,"ITS TIME TO D-D-D-D-D-DUEL!")
self.players[player]=[]
for player in self.players:
self.deal(player)
self.sendCards(player)
self.active = True
self.makeTurn()
elif self.master.bot.messageHasCommand(".pick",trailing):
if self.active:
if sender != self.czar:
print(sender,self.czar)
print(sender != self.czar)
if self.allowPick > 0:
if sender in self.players:
cards = trailing.split(' ')[1:]
if len(cards)==self.allowPick:
if self.checkBounds(cards):
if sender not in self.choices:
cardChoices = [self.players[sender][int(index)] for index in cards]
print(cardChoices)
self.choices[sender] = cardChoices
self.removeAndReplenishCards(sender, cardChoices)
self.sendCards(sender)
del self.choices[sender]
if sender in timers:
self.timers[sender].cancel()
if self.allDrawn():
self.readChoices()
self.master.bot.act_PRIVMSG(self.channel,self.czar+"! Please choose the winner!")
czarTimer = Timer(180,self.kick,(self.czar,"taking too long to pick a choice. The next turn iwll be made."))
self.makeTurn()
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked a card that was out of the range. Please don't do that.")
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked "+str(len(cards))+" cards. You were supposed to pick "+str(self.allowPick))
elif self.master.bot.messageHasCommand(".choose",trailing):
if sender==self.czar:
choice = trailing.split()[1:]
if len(choice)==1:
if self.checkChoiceBounds(int(choice[0])):
self.master.bot.act_PRIVMSG(self.channel,list(self.choices.keys())[int(choice[0])]+", you won the round!")
if self.czarTimer!=None:
self.czarTimer.cancel()
self.makeTurn()
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", your choice was out of the range. Please don't do that.")
else:
self.master.bot.act_PRIVMSG(self.channel,sender+", you picked "+str(len(choice))+" "+" winners. You were only supposed to pick 1.")
elif self.master.bot.messageHasCommand('.leave',trailing):
if sender in self.players:
self.kick(sender,'choosing to leave the game you dolt')
if sender is self.czar:
self.makeTurn()
def join(self,nick):
if not self.started:
if nick not in self.players:
self.players[nick]=False
self.master.bot.act_PRIVMSG(self.channel, nick+" has joined the game! | The players currently are "+str(self.players))
else:
print("the game has already started!")
self.master.bot.act_PRIVMSG(self.channel,"The game has already started!")
def markReady(self,nick):
if not self.started:
if nick in self.players:
self.players[nick]=True
for player in self.players:
print(player)
if not self.players[player]:
print (player+" not ready")
return False
return True
else:
self.master.bot.act_PRIVMSG(self.channel, "You are not in the game! Type .joinGame!")
else:
print("game has already started!")
self.master.bot.act_PRIVMSG(self.channel,"The game has already started!")
def deal(self,nick):
self.players[nick] = [self.pickWhite() for i in range (7)]
def pickWhite(self):
card = choice(self.whites)
self.whites.remove(card)
return card
def pickBlack(self):
card = choice(self.blacks)
self.blacks.remove(card)
return card
def sendCards(self,nick):
cards = ""
for card in self.players[nick]:
cards+=str(self.players[nick].index(card))+". "
cards+=card+" "
self.master.bot.act_PRIVMSG(nick,"Your cards are "+cards)
def readCard(self,card):
count = card.count('_')
if count == 0:
if 'haiku' in card:
count = 3
else:
count = 1
self.master.bot.act_PRIVMSG(self.channel,"The black card is \""+card+"\" Pick "+str(count))
return count
def pickCzar(self):
index = self.lastCzar+1
if index < len(self.players):
self.lastCzar = index
return index
else:
self.lastCzar = 0
return 0
def announceCzar(self):
self.master.bot.act_PRIVMSG(self.channel,"The Czar is "+self.czar+"!")
def checkBounds(self,cards):
for item in cards:
if int(item)>6 or int(item)<0:
return False
return True
def checkChoiceBounds(self,choice):
if choice<0 or choice>len(self.choices)-1:
return False
return True
def makeTurn(self):
self.choices.clear()
card = self.pickBlack()
self.timers.clear()
self.currentBlack = card
self.allowPick = self.readCard(card)
self.lastCzar = self.pickCzar()
self.czar = list(self.players.keys())[self.lastCzar]
print (self.lastCzar,self.czar)
for player in self.players:
if player!=self.czar:
self.timers[player] = Timer(180,self.kick,(player,"taking more than 180 seconds for their turn."))
self.timers[player].start()
self.announceCzar()
def kick(self,nick,reason):
del self.players[nick]
if nick in self.timers:
self.timers[nick].cancel()
del self.timers[nick]
self.master.bot.act_PRIVMSG(self.channel,nick+" has been kicked due to "+reason)
if len(self.players)<=1:
self.master.bot.act_PRIVMSG(self.channel,"The game is being shut down due to having <=1 players")
self.started = False
self.active = False
for timer in self.timers:
timer.cancel()
self.timers.clear()
self.players.clear()
def removeAndReplenishCards(self,nick,cards):
for card in cards:
self.players[nick].remove(card)
self.players[nick].append(self.pickWhite())
def readChoices(self):
if '_' in self.currentBlack:
for player in list(self.choices.keys()):
cardInstance = str(list(self.choices.keys()).index(player))+". "+self.currentBlack
cardInstance = list(cardInstance) #do this as opposed to space to preserve spaces
for choice in self.choices[player]:
for char in cardInstance:
if char=='_':
print(char)
choice = choice.replace('.','')
cardInstance[cardInstance.index(char)] = choice
break
self.master.bot.act_PRIVMSG(self.channel,''.join(cardInstance))
else:
for player in self.choices:
self.master.bot.act_PRIVMSG(self.channel,self.currentBlack+' '+' '.join(self.choices[player]))
def allDrawn(self):
for player in self.players:
if player not in self.choices:
if player != self.czar:
return False
return True

View File

@ -9,7 +9,6 @@
from pyircbot.modulebase import ModuleBase,ModuleHook
import random
import yaml
import os
import time
import math

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
.. module:: DogeRPC
:synopsis: Provides a service for interacting with dogecoind.
:synopsis: Provides a service for interacting with dogecoind.
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
@ -11,64 +11,67 @@ from pyircbot.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
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 a local 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"]))
"RPC instance control class"
def __init__(self, master):
self.config = master.config
self.log = master.log
self.con = None
self.ping()
def ping(self):
"Test connection and re-establish if necessary"
try:
self.con.getinfo()
except:
self.connect()
def connect(self):
"Connect to RPC endpoint"
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"]))

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
.. module:: DogeScramble
:synopsis: This module provides a word scrambling game that rewards winners with small amounts of Dogecoin
:synopsis: This module provides a word scrambling game that rewards winners with small amounts of Dogecoin
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
@ -9,258 +9,257 @@
from pyircbot.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.getKey(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()
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.getKey(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.getKey(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.getKey(prefix.nick, "dogeaddr")
userwallet = self.master.attr.getKey(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()
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.getKey(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.getKey(prefix.nick, "dogeaddr")
userwallet = self.master.attr.getKey(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()

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
.. module:: DuckHunt
:synopsis: An animal hunting IRC game
:synopsis: An animal hunting IRC game
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
@ -9,160 +9,160 @@
from pyircbot.modulebase import ModuleBase,ModuleHook
import time
import yaml
import json
import random
from threading import Timer
import os
class DuckHunt(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.hunt)]
self.loadConfig()
self.ymlPath = self.getFilePath("scores.yml")
self.timer = None
self.isDuckOut = False
self.outStart = 0
self.misses = {}
self.startHunt()
def hunt(self, args, prefix, trailing):
prefixObj = self.bot.decodePrefix(prefix)
fromWho = prefixObj.nick
cmd = self.bot.messageHasCommand("!huntscore", trailing, False)
if cmd:
scores = self.loadScores()
if not fromWho in scores:
self.bot.act_PRIVMSG(fromWho, "You have no points :(")
else:
scores = scores[fromWho]
kills = 0
runts = 0
prime = 0
weight = 0.0
shots = 0
misses = 0
for kill in scores:
if kill["prime"]:
prime+=1
if kill["runt"]:
runts+=1
kills+=1
weight+=kill["weight"]
shots+=1
shots+=kill["misses"]
misses+=kill["misses"]
self.bot.act_PRIVMSG(fromWho, "You've shot %s %s for a total weight of %s lbs." % (kills, self.config["animalSpeciesPlural"], weight))
self.bot.act_PRIVMSG(fromWho, "%s prime catches, %s runts, %s bullets used and %s misses." % (prime, runts, shots, misses))
#self.bot.act_PRIVMSG(fromWho, "More info & highscores: http://duckhunt.xmopx.net/")
self.log.info("DuckHunt: %s used !huntscore" % fromWho)
return
# Channel only
if not args[0][0]=="#":
return
cmd = self.bot.messageHasCommand("!shoot", trailing, False)
if cmd:
if self.isDuckOut:
if not fromWho in self.misses:
self.misses[fromWho]=0
shotIn = round(time.time() - self.outStart, 2)
if random.randint(0, 100) <= self.config["missChance"]:
self.bot.act_PRIVMSG(self.config["activeChannel"], "%s fires after %s seconds and misses!" % (fromWho, shotIn))
self.misses[fromWho]+=1
return
self.isDuckOut = False
bagged = {
"species":self.config["animalSpecies"],
"gender":"M" if random.randint(0,1)==1 else "F",
"time":shotIn,
"prime":False,
"runt":False,
"weight":0.0,
"date":time.time(),
"misses":self.misses[fromWho]
}
message = "%s %s " % (fromWho, "bags")
if random.randint(0, 100) <= self.config["primeChance"]:
bagged["prime"]=True
bagged["weight"]=self.getRandWeight(self.config["weightMax"], self.config["weightFat"])
message += "a prime catch, a "
elif random.randint(0, 100) <= self.config["runtChance"]:
bagged["runt"]=True
bagged["weight"]=self.getRandWeight(self.config["weightRunt"], self.config["weightMin"])
message += "a runt of a catch, a "
else:
bagged["weight"]=self.getRandWeight(self.config["weightMin"], self.config["weightMax"])
message += "a "
message += "%s lb " % (bagged["weight"])
if bagged["gender"]=="M":
message += self.config["animalNameMale"]+" "
else:
message += self.config["animalNameFemale"]+" "
message += "in %s seconds!" % shotIn
self.bot.act_PRIVMSG(self.config["activeChannel"], message)
self.addKillFor(fromWho, bagged)
self.misses = {}
self.startHunt();
def startHunt(self):
" Creates a timer that waits a certain amount of time then sends out a bird \_o< quack"
delay = self.config["delayMin"] + random.randint(0, self.config["delayMax"]-self.config["delayMin"])
self.timer = Timer(delay, self.duckOut)
self.timer.start()
print("DuckHunt: Sending out animal in %s seconds" % delay)
def duckOut(self):
self.isDuckOut = True
self.bot.act_PRIVMSG(self.config["activeChannel"], self.config["animal"])
self.outStart = time.time()
def getRandWeight(self, minW, maxW):
weight = maxW-minW;
weight = float(weight)*random.random()
return round(weight+minW, 2)
def getScoreFor(self, playername):
return 1
def getScoresFor(self, playername):
return 1
def addKillFor(self, playername, kill):
scores = self.loadScores()
if scores==None:
scores = {}
if not playername in scores:
scores[playername]=[]
scores[playername].append(kill)
self.saveScores(scores)
def loadScores(self):
if not os.path.exists(self.ymlPath):
yaml.dump({}, open(self.ymlPath, 'w'))
return yaml.load(open(self.ymlPath, 'r'))
def saveScores(self, scores):
yaml.dump(scores, open(self.ymlPath, 'w'))
def ondisable(self):
self.timer.cancel()
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.hunt)]
self.loadConfig()
self.jsonPath = self.getFilePath("scores.json")
self.timer = None
self.isDuckOut = False
self.outStart = 0
self.misses = {}
self.startHunt()
def hunt(self, args, prefix, trailing):
prefixObj = self.bot.decodePrefix(prefix)
fromWho = prefixObj.nick
cmd = self.bot.messageHasCommand("!huntscore", trailing, False)
if cmd:
scores = self.loadScores()
if not fromWho in scores:
self.bot.act_PRIVMSG(fromWho, "You have no points :(")
else:
scores = scores[fromWho]
kills = 0
runts = 0
prime = 0
weight = 0.0
shots = 0
misses = 0
for kill in scores:
if kill["prime"]:
prime+=1
if kill["runt"]:
runts+=1
kills+=1
weight+=kill["weight"]
shots+=1
shots+=kill["misses"]
misses+=kill["misses"]
self.bot.act_PRIVMSG(fromWho, "You've shot %s %s for a total weight of %s lbs." % (kills, self.config["animalSpeciesPlural"], weight))
self.bot.act_PRIVMSG(fromWho, "%s prime catches, %s runts, %s bullets used and %s misses." % (prime, runts, shots, misses))
#self.bot.act_PRIVMSG(fromWho, "More info & highscores: http://duckhunt.xmopx.net/")
self.log.info("DuckHunt: %s used !huntscore" % fromWho)
return
# Channel only
if not args[0][0]=="#":
return
cmd = self.bot.messageHasCommand("!shoot", trailing, False)
if cmd:
if self.isDuckOut:
if not fromWho in self.misses:
self.misses[fromWho]=0
shotIn = round(time.time() - self.outStart, 2)
if random.randint(0, 100) <= self.config["missChance"]:
self.bot.act_PRIVMSG(self.config["activeChannel"], "%s fires after %s seconds and misses!" % (fromWho, shotIn))
self.misses[fromWho]+=1
return
self.isDuckOut = False
bagged = {
"species":self.config["animalSpecies"],
"gender":"M" if random.randint(0,1)==1 else "F",
"time":shotIn,
"prime":False,
"runt":False,
"weight":0.0,
"date":time.time(),
"misses":self.misses[fromWho]
}
message = "%s %s " % (fromWho, "bags")
if random.randint(0, 100) <= self.config["primeChance"]:
bagged["prime"]=True
bagged["weight"]=self.getRandWeight(self.config["weightMax"], self.config["weightFat"])
message += "a prime catch, a "
elif random.randint(0, 100) <= self.config["runtChance"]:
bagged["runt"]=True
bagged["weight"]=self.getRandWeight(self.config["weightRunt"], self.config["weightMin"])
message += "a runt of a catch, a "
else:
bagged["weight"]=self.getRandWeight(self.config["weightMin"], self.config["weightMax"])
message += "a "
message += "%s lb " % (bagged["weight"])
if bagged["gender"]=="M":
message += self.config["animalNameMale"]+" "
else:
message += self.config["animalNameFemale"]+" "
message += "in %s seconds!" % shotIn
self.bot.act_PRIVMSG(self.config["activeChannel"], message)
self.addKillFor(fromWho, bagged)
self.misses = {}
self.startHunt();
def startHunt(self):
" Creates a timer that waits a certain amount of time then sends out a bird \\_o< quack"
delay = self.config["delayMin"] + random.randint(0, self.config["delayMax"]-self.config["delayMin"])
self.timer = Timer(delay, self.duckOut)
self.timer.start()
print("DuckHunt: Sending out animal in %s seconds" % delay)
def duckOut(self):
self.isDuckOut = True
self.bot.act_PRIVMSG(self.config["activeChannel"], self.config["animal"])
self.outStart = time.time()
def getRandWeight(self, minW, maxW):
weight = maxW-minW;
weight = float(weight)*random.random()
return round(weight+minW, 2)
def getScoreFor(self, playername):
return 1
def getScoresFor(self, playername):
return 1
def addKillFor(self, playername, kill):
scores = self.loadScores()
if scores==None:
scores = {}
if not playername in scores:
scores[playername]=[]
scores[playername].append(kill)
self.saveScores(scores)
def loadScores(self):
if not os.path.exists(self.jsonPath):
json.dump({}, open(self.jsonPath, 'w'))
return json.load(open(self.jsonPath, 'r'))
def saveScores(self, scores):
json.dump(scores, open(self.jsonPath, 'w'))
def ondisable(self):
self.timer.cancel()

View File

@ -9,7 +9,6 @@
from pyircbot.modulebase import ModuleBase,ModuleHook
import random
import yaml
import os
import time
from threading import Timer

View File

@ -1,6 +1,6 @@
"""
.. module:: Scramble
:synopsis: Module to provide a word scramble game
:synopsis: Module to provide a word scramble game
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
@ -8,232 +8,232 @@
from pyircbot.modulebase import ModuleBase,ModuleHook
import random
import yaml
import json
import os
import time
from threading import Timer
from operator import itemgetter
class Scramble(ModuleBase):
def __init__(self, bot, moduleName):
# init the base module
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
self.loadConfig()
# Dictionary
self.wordsCount=0;
self.wordsFile = self.getFilePath("words.txt")
print(self.wordsFile)
wordsF = open(self.wordsFile, "r")
while True:
word = wordsF.readline()
if word=="":
break
self.wordsCount+=1
wordsF.close
self.log.info("Scramble: Loaded %s words" % str(self.wordsCount))
# Load scores
self.scoresFile = self.getFilePath("scores.yml")
if not os.path.exists(self.scoresFile):
yaml.dump({}, file(self.scoresFile, 'w'))
self.scores = yaml.load(file(self.scoresFile, 'r'))
# Per channel games
self.games = {}
# Hook in
self.hooks=[ModuleBase.ModuleHook("PRIVMSG", self.scramble)]
def scramble(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
if not channel in self.games:
self.games[channel]=scrambleGame(self, channel)
self.games[channel].scramble(args, prefix, trailing)
def saveScores(self):
yaml.dump(self.scores, file(self.scoresFile, 'w'))
def getScore(self, player, add=0):
player = player.lower()
if not player in self.scores:
self.scores[player] = 0
if not add == 0:
self.scores[player]+=add
self.saveScores()
return self.scores[player]
def getScoreNoWrite(self, player):
if not player.lower() in self.scores:
return 0
else:
return self.getScore(player)
def ondisable(self):
self.log.info("Scramble: Unload requested, ending games...")
for game in self.games:
self.games[game].gameover()
self.saveScores()
def __init__(self, bot, moduleName):
# init the base module
ModuleBase.__init__(self, bot, moduleName);
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
self.loadConfig()
# Dictionary
self.wordsCount=0;
self.wordsFile = self.getFilePath("words.txt")
print(self.wordsFile)
wordsF = open(self.wordsFile, "r")
while True:
word = wordsF.readline()
if word=="":
break
self.wordsCount+=1
wordsF.close
self.log.info("Scramble: Loaded %s words" % str(self.wordsCount))
# Load scores
self.scoresFile = self.getFilePath("scores.json")
if not os.path.exists(self.scoresFile):
json.dump({}, open(self.scoresFile, 'w'))
self.scores = json.load(open(self.scoresFile, 'r'))
# Per channel games
self.games = {}
# Hook in
self.hooks=[ModuleHook("PRIVMSG", self.scramble)]
def scramble(self, args, prefix, trailing):
channel = args[0]
if channel[0] == "#":
if not channel in self.games:
self.games[channel]=scrambleGame(self, channel)
self.games[channel].scramble(args, prefix, trailing)
def saveScores(self):
json.dump(self.scores, open(self.scoresFile, 'w'))
def getScore(self, player, add=0):
player = player.lower()
if not player in self.scores:
self.scores[player] = 0
if not add == 0:
self.scores[player]+=add
self.saveScores()
return self.scores[player]
def getScoreNoWrite(self, player):
if not player.lower() in self.scores:
return 0
else:
return self.getScore(player)
def ondisable(self):
self.log.info("Scramble: Unload requested, ending games...")
for game in self.games:
self.games[game].gameover()
self.saveScores()
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;
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
cmd = self.master.bot.messageHasCommand(".scrambleon", trailing)
if cmd and not self.running:
self.running = True
self.startScramble()
return
cmd = self.master.bot.messageHasCommand(".scrambleoff", trailing)
if cmd and self.running:
self.gameover()
self.running = False
return
cmd = self.master.bot.messageHasCommand(".scramble top", trailing)
if cmd:
sortedscores = []
for player in self.master.scores:
sortedscores.append({'name':player, 'score':self.master.scores[player]})
sortedscores = sorted(sortedscores, key=itemgetter('score'))
sortedscores.reverse()
numScores = len(sortedscores)
if numScores>3:
numScores=3
resp = "Top %s: " % str(numScores)
which = 1
while which<=numScores:
resp+="%s: %s, " % (sortedscores[which-1]["name"], sortedscores[which-1]["score"])
which+=1
self.master.bot.act_PRIVMSG(self.channel, resp[:-2])
cmd = self.master.bot.messageHasCommand(".scramble score", trailing)
if cmd:
someone = cmd.args.strip()
if len(someone) > 0:
self.master.bot.act_PRIVMSG(self.channel, "%s: %s has a score of %s" % (sender, someone, self.master.getScoreNoWrite(someone)))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: %s" % (sender, self.master.getScore(sender)))
if self.currentWord and trailing.strip().lower() == self.currentWord:
playerScore = self.master.getScore(sender, 1)
self.master.bot.act_PRIVMSG(self.channel, "%s guessed the word - %s! %s now has %s points. Next word in %s seconds." % (sender, self.currentWord, sender, playerScore, self.delayNext))
self.currentWord = None
self.clearTimers()
self.hintsGiven = 0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
self.guesses=0
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.master.log.info("Scramble: New word for %s: %s" % (self.channel, self.currentWord))
self.scrambled = self.scrambleWord(self.currentWord)
self.master.bot.act_PRIVMSG(self.channel, "New word - %s " % (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 .scrambleon to start again.")
self.gameover()
return
else:
self.gamesWithoutGuesses=0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
def pickWord(self):
f = open(self.master.wordsFile, "r")
skip = random.randint(0, self.master.wordsCount)
while skip>=0:
f.readline()
skip-=1
picked = f.readline().strip().lower()
f.close()
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()
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 gamesWithoutGuesses submitted this round
self.guesses = 0;
# How many games in a row where nobody guessed
self.gamesWithoutGuesses = 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
cmd = self.master.bot.messageHasCommand(".scrambleon", trailing)
if cmd and not self.running:
self.running = True
self.startScramble()
return
cmd = self.master.bot.messageHasCommand(".scrambleoff", trailing)
if cmd and self.running:
self.gameover()
self.running = False
return
cmd = self.master.bot.messageHasCommand(".scramble top", trailing)
if cmd:
sortedscores = []
for player in self.master.scores:
sortedscores.append({'name':player, 'score':self.master.scores[player]})
sortedscores = sorted(sortedscores, key=itemgetter('score'))
sortedscores.reverse()
numScores = len(sortedscores)
if numScores>3:
numScores=3
resp = "Top %s: " % str(numScores)
which = 1
while which<=numScores:
resp+="%s: %s, " % (sortedscores[which-1]["name"], sortedscores[which-1]["score"])
which+=1
self.master.bot.act_PRIVMSG(self.channel, resp[:-2])
cmd = self.master.bot.messageHasCommand(".scramble score", trailing)
if cmd:
someone = cmd.args.strip()
if len(someone) > 0:
self.master.bot.act_PRIVMSG(self.channel, "%s: %s has a score of %s" % (sender, someone, self.master.getScoreNoWrite(someone)))
else:
self.master.bot.act_PRIVMSG(self.channel, "%s: %s" % (sender, self.master.getScore(sender)))
if self.currentWord and trailing.strip().lower() == self.currentWord:
playerScore = self.master.getScore(sender, 1)
self.master.bot.act_PRIVMSG(self.channel, "%s guessed the word - %s! %s now has %s points. Next word in %s seconds." % (sender, self.currentWord, sender, playerScore, self.delayNext))
self.currentWord = None
self.clearTimers()
self.hintsGiven = 0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
self.guesses=0
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.master.log.info("Scramble: New word for %s: %s" % (self.channel, self.currentWord))
self.scrambled = self.scrambleWord(self.currentWord)
self.master.bot.act_PRIVMSG(self.channel, "New word - %s " % (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 .scrambleon to start again.")
self.gameover()
return
else:
self.gamesWithoutGuesses=0
self.nextTimer = Timer(self.delayNext, self.startNewWord)
self.nextTimer.start()
def pickWord(self):
f = open(self.master.wordsFile, "r")
skip = random.randint(0, self.master.wordsCount)
while skip>=0:
f.readline()
skip-=1
picked = f.readline().strip().lower()
f.close()
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()

18
pyircbot/modules/Test.py Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
"""
.. module:: Test
:synopsis: For testing code
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
"""
from pyircbot.modulebase import ModuleBase,ModuleHook
class Test(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName)
self.hooks=[ModuleHook("PRIVMSG", self.dotest)]
def dotest(self, args):
print("DOTEST(%s)"%(args,))

View File

@ -301,9 +301,7 @@ class PyIRCBot:
basepath = "%s/config/%s" % (self.botconfig["bot"]["datadir"], moduleName)
if os.path.exists("%s.yml"%basepath):
return "%s.yml"%basepath
elif os.path.exists("%s.json"%basepath):
if os.path.exists("%s.json"%basepath):
return "%s.json"%basepath
return None
@ -360,15 +358,12 @@ class PyIRCBot:
def load(filepath):
"""Return an object from the passed filepath
:param filepath: path to a file of json or yaml format. filename must end with .json or .yml
:param filepath: path to a json file. filename must end with .json
:type filepath: str
:Returns: | dict
"""
if filepath.endswith(".yml"):
from yaml import load
return load(open(filepath, 'r'))
elif filepath.endswith(".json"):
if filepath.endswith(".json"):
from json import load
return load(open(filepath, 'r'))
else: