Remove yaml, convert all configs to json
This commit is contained in:
parent
bdf0081ba8
commit
f6404047cf
|
@ -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
|
||||
---------------
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
---------------
|
||||
|
|
|
@ -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
|
||||
---------------
|
||||
|
|
|
@ -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
|
||||
---------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cache": 300
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
cache: 300
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"allowDelete": true,
|
||||
"delaySubmit": 0,
|
||||
"delayCalc": 0,
|
||||
"delayCalcSpecific": 0,
|
||||
"delayMatch": 0,
|
||||
"cmd_calc": [
|
||||
".calc",
|
||||
"calc",
|
||||
".quote"
|
||||
],
|
||||
"cmd_match": [
|
||||
".match",
|
||||
"match"
|
||||
]
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
allowDelete: true
|
||||
delaySubmit: 0
|
||||
delayCalc: 0
|
||||
delayCalcSpecific: 0
|
||||
delayMatch: 0
|
||||
cmd_calc:
|
||||
- .calc
|
||||
- calc
|
||||
- .quote
|
||||
cmd_match:
|
||||
- .match
|
||||
- match
|
|
@ -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/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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/
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"minBet": 0.01,
|
||||
"lobbyIdleSeconds": 15,
|
||||
"channelWhitelistOn": true,
|
||||
"channelWhitelist": [
|
||||
"dogegamestest",
|
||||
"test"
|
||||
]
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
minBet: .01
|
||||
lobbyIdleSeconds: 15
|
||||
channelWhitelistOn: True
|
||||
channelWhitelist:
|
||||
- dogegamestest
|
||||
- test
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"host": "127.0.0.1",
|
||||
"username": "wallet_rpc_user",
|
||||
"password": "wallet_rpc_pass",
|
||||
"port": 22555
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
host: 127.0.0.1
|
||||
username: wallet_rpc_user
|
||||
password: wallet_rpc_pass
|
||||
port: 22555
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"hintDelay": 15,
|
||||
"delayNext": 5,
|
||||
"maxHints": 5,
|
||||
"abortAfterNoGuesses": 2,
|
||||
"categoryduration": 10,
|
||||
"winAmount": 5,
|
||||
"decreaseFactor": 0.75
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"channelWhitelistOn": true,
|
||||
"channelWhitelist": [
|
||||
"test"
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
channelWhitelistOn: True
|
||||
channelWhitelist:
|
||||
- test
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"username": "root",
|
||||
"password": "root",
|
||||
"database": "pyircbot"
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
host: 10.0.3.14
|
||||
username: root
|
||||
password: root
|
||||
database: pyircbot_dev
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cache": 90
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
cache: 90
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"limit": 10000
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
limit: 10000
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"mytimezone": "US/Pacific",
|
||||
"precision": 5
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
mytimezone: US/Pacific
|
||||
precision: 5
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"hintDelay": 15,
|
||||
"delayNext": 5,
|
||||
"maxHints": 5,
|
||||
"abortAfterNoGuesses": 5
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
hintDelay: 15
|
||||
delayNext: 5
|
||||
maxHints: 5
|
||||
abortAfterNoGuesses: 5
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"timezone": "EST",
|
||||
"add_hours": 0
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
timezone: EST
|
||||
add_hours: 0
|
|
@ -19,7 +19,7 @@
|
|||
"ghost_cmd":"ghost %(nick)s %(password)s"
|
||||
},
|
||||
"channels":[
|
||||
"#xmopx"
|
||||
"##xmopx"
|
||||
],
|
||||
"privatechannels":{
|
||||
"to":"chanserv",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"max": 10,
|
||||
"maxage": 2678400
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
max: 10
|
||||
maxage: 2678400
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"apikey": "get an API key at: http://www.wunderground.com/weather/api/ (choose 'anvil')",
|
||||
"defaultUnit": "c"
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
apikey: "get an API key at: http://www.wunderground.com/weather/api/ (choose \"anvil\")"
|
||||
defaultUnit: c
|
|
@ -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
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
from pyircbot.modulebase import ModuleBase,ModuleHook
|
||||
import random
|
||||
import yaml
|
||||
import os
|
||||
import time
|
||||
import math
|
||||
|
|
|
@ -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"]))
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
from pyircbot.modulebase import ModuleBase,ModuleHook
|
||||
import random
|
||||
import yaml
|
||||
import os
|
||||
import time
|
||||
from threading import Timer
|
||||
|
|
|
@ -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()
|
|
@ -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,))
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue