def get_monster(uid):
    """Get a new monster for a player"""
    (conn, db) = get_db()

    if db:
        cursor = db.floors
        result = cursor.find().count()
        log.info("get_monster: found %i monsters" % (result))
        if result > 0:
            id = random.randint(1, result - 1)
            floor  = cursor.find_one({"_id" : id})
            # TODO: test if found or not
            cursor = db.players
            player = cursor.find_one({"fb_uid" : uid})
            # TODO: test if found or not
            # we need to make a monster table!
            player["monster_id"] = id
            player["monster_hp"] = random.randint(10,50)
            log.info("get_monster: uid = %s got monster = %i" % (uid,id))
            cursor.save(player)
            return player
        else:
            return None
    else:
        log.error("get_monster: couldn't connect to db")
        return None
    def run(self):

        log.info('Starting Database: ')
        DB = app.db.test_database()
        if DB:
            log.info('Database started')
        else:
            log.critical('Database failed to initalize - aborting')
            sys.exit(1)

        app.db.add_news(0, time.time(), "http://da.mithrilsoft.com/da/assets/images/logo_50x50.gif", "Server version %s was restarted at %s" % (VERSION, datetime.datetime.now()))

        log.info('Starting Webserver: ')
        try:
            WS = app.httpd.WebServer()
            log.info('Webserver started')
        except:
            log.critical('Webserver failed to initalize - aborting')
            sys.exit(1)

        #log.info('Starting Timer: ')
        #TM = app.timer.Timer()
        #if TM:
        #    log.info('Timer started')
        #else:
        #    log.critical('Timer failed to initalize - aborting')
        #    sys.exit(1)

        #with daemon.DaemonContext():
        # do nothing useful for now                  
        while True:
            log.info('waking up')
            time.sleep(600)
 def process_active_list(self):
     """
     Process all currently running tasks.
     """
     log.info('active_queue = ' + str(self.active_queue.qsize())) 
     i = random.randint(0, 5)
     while i > 0:
         self.add_work('TEST_TASK', 
                      app.worker.test_task, 
                      random.randint(0, 30))
         i -= 1
def test_database():
    """
    """
    (conn, db) = get_db() 

    if db:
        log.info("Database version: " + conn.server_info()['version'])
        return True
    else:
        log.error("test_database: couldn't connect to db")
        return False   
 def run(self):
     """
     Start worker.
     """
     log.info("worker started")
     while True:
         task_name, _callable, args, kwds = self.task_queue.get()
         log.debug("worker got " + task_name)
         # pylint: disable-msg=W0142
         results = _callable(*args, **kwds)
         # pylint: enable-msg=W0142
         if results is False:
             log.error("Task failed: " + task_name)
def get_player_info(uid, name, pic_square):
    """
    """
    (conn, db) = get_db() 

    if db:
        cursor = db.players
        result = cursor.find_one({"fb_uid": uid})
        log.info("get_player_info: find_one by fb_uid, uid = " + uid)
        ts = time.time()
        if result == None:
            # new player, create record
            log.info("get_player_info: Creating new player: fb_uid = " + uid + " name = " + name)
            player = {"fb_uid": uid,
                      "name" : name,
                      "pic_square" : pic_square,
                      "xp": 0,
                      "gold": 0,
                      "level": 1,
                      "sp": 5,
                      "max_sp": 5,
                      "attack": 0,
                      "defense": 0,
                      "hp": 20,
                      "max_hp": 20,
                      "actions": 0,
                      "errors": 0,
                      "dungeon_id": 0, # for now zero = in town
                      "result_id": 0,
                      "result_msg": "",
                      "dungeon_coord": None,
                      "monster_id": 1, # dummy
                      "monster_hp": 100, # dummy
                      "north": 0,
                      "south": 0,
                      "east": 0,
                      "west": 0,
                      "trap_id": 0,
                      "chest_id": 0,
                      "stairs": 0,
                      "session_id": 1919, # dummy
                      "timestamp": ts,
                      "created": ts,
                      "version": 1,
                     }
            cursor.save(player)
            result = cursor.find_one({"fb_uid": uid}) # make sure it was created
            add_news(uid, ts, pic_square, "%s created a character at %s" % (player["name"], datetime.datetime.now()))
        else:
            log.info("get_player_info: Found player: fb_uid = " + uid + " name = " + name)
            if result["timestamp"] < ts - 3600:
                add_news(uid, ts, pic_square, "%s logged on at %s" % (result["name"], datetime.datetime.now()))

        for i in result:
           log.info("get_player_info: " + i + " " + str(result[i]))

        return result
    else:
        log.error("get_player_info: couldn't connect to db")
        return None
def get_news(uid):
    """Get news for this player"""
    (conn, db) = get_db()

    if db:
        news_cursor = db.news
        # TODO: probably uses too many resources
        news = news_cursor.find({}, {"Image":1,"Item":1}).sort("ts", pymongo.DESCENDING).limit(15); # 15 results maximum
        result = [] 
        for items in news:
            result.append(items)
            log.info("get_news: %s" % (items["Item"]))
        return result
    else:
        log.error("get_news: couldn't connect to db")
        return None
 def run(self):
     """
     Check the tasks queue and run anything that is due.
     """
     while True:
         while self.current_workers < self.total_workers:
             log.debug("worker added")
             app.worker.Worker(self.active_queue)
             self.current_workers += 1
             
         self.process_pending_list()
         self.process_active_list()
         self.process_done_list()
         
         log.info('active_queue = ' + str(self.active_queue.qsize())) 
         time.sleep(app.config.TIMER_SLEEP_INTERVAL)
         log.debug("waking")            
    def __init__(self):
        #self.setDaemon(True)
        #self.setName('WebServer')
        
        channel_set = WsgiChannelSet()
        rpc_channel = WsgiChannel('amf')
        channel_set.mapChannel(rpc_channel)
        app.utils.setup_channel_set(channel_set)

        try:
            log.info('Listening for connections')
            server = wsgi.WSGIServer(('', 8000), channel_set).serve_forever()
            server.handler_class(channel_set)
         
        except (KeyboardInterrupt, SystemExit):
            raise

        return None
def do_move(uid, direction):
    """Move between rooms in a dungeon"""
    if direction not in ("n","s","e","w","u","d"):
        return None

    (conn, db) = get_db()

    if db:
        player_cursor = db.players 
        player = player_cursor.find_one({"fb_uid" : uid})
        floor_cursor = db.floors
        # TODO: test if found or not
        floor  = floor_cursor.find_one({"_id" : player["dungeon_id"]})
        (row,col) = player["dungeon_coord"].split(",")
        try_row = int(row)
        try_col = int(col)

        if direction == "d":
            if player["dungeon_coord"] in floor["exits"]:
                log.info("do_move: found exit")
                return None
        elif direction == "u":
            return None

        if direction == "n":
            try_row += 1            
        elif direction == "s":
            try_row -= 1            
        elif direction == "e":
            try_col += 1
        else: 
            try_col -= 1

        try_coord = "%i,%i" % (try_row,try_col)
        if floor["rooms"][try_coord]:
            player["dungeon_coord"] =  try_coord
            player_cursor.save(player)
            log.info("do_move: moved from %s,%s to %i,%i" % (row,col,try_row,try_col))

    else:
        log.error("do_move: couldn't connect to db")
        return None
 def get_player_info(self, uid, name, pic_square):
     log.info("controller: called get_player_info uid = " + uid + " " + name)
     return app.db.get_player_info(uid, name, pic_square)
 def get_monster(self, uid):
     log.info("controller: called get_monster uid = " + uid)
     return app.db.get_monster(uid)
 def get_news(self, uid):
     log.info("controller: called get_news uid = " + uid)
     return app.db.get_news(uid)
 def do_attack(self, uid):
     log.info("controller: called do_attack uid = " + uid)
     return app.db.do_attack(uid) 
def get_floor(uid):
    """Get a new dungeon floor for a player and move them to it"""
    (conn, db) = get_db()

    if db:
        cursor = db.floors
        result = cursor.find().count()
        log.info("get_floor: found %i floors" % (result))
        if result > 0:
            f = random.randint(1, result - 1)
            floor  = cursor.find_one({"_id" : f})
            # TODO: test if found or not
            cursor = db.players 
            player = cursor.find_one({"fb_uid" : uid})
            # TODO: test if found or not
            player["dungeon_id"] = f
            player["dungeon_coord"] = floor["start_room"]
            log.info("get_floor: uid = %s got dungeon = %i dungeon_coord = %s" % (uid,f,floor["start_room"]))

            # TODO: this is not very efficent    
            rooms = floor["rooms"]
            (row,col) = player["dungeon_coord"].split(",")
            try_row = int(row)
            try_col = int(col)
            for key in rooms:
                log.info("found: %s" % key)
            try_coord = "%i,%i" % (try_row+1,try_col)
            log.info("get_floor: uid = %s try_coord = %s" % (uid,try_coord))
            if try_coord in rooms:
                player["north"] = try_coord
            else:
                player["north"] = ""
            try_coord = "%i,%i" % (try_row-1,try_col)
	    log.info("get_floor: uid = %s try_coord = %s" % (uid,try_coord))
            if try_coord in rooms:
                player["south"] = try_coord
            else:
                player["south"] = ""
            try_coord = "%i,%i" % (try_row,try_col+1)
            log.info("get_floor: uid = %s try_coord = %s" % (uid,try_coord))
            if try_coord in rooms:
                player["east"] = try_coord
            else:
                player["east"] = ""
            try_coord = "%i,%i" % (try_row,try_col-1)
            log.info("get_floor: uid = %s try_coord = %s" % (uid,try_coord))
            if try_coord in rooms:
                player["west"] = try_coord
            else:
                player["west"] = ""

            cursor.save(player)
            return player
        else:
            return None
    else:
        log.error("get_floor: couldn't connect to db")
        return None
def do_attack(uid):
    """
    """
    (conn, db) = get_db()

    if db:
        cursor = db.players
        player = cursor.find_one({"fb_uid": uid})
        log.info("do_attack: fb_uid = " + uid)
        if player == None:
            log.info("do_attack: player: fb_uid = " + uid + "not found")
            return None
        elif player["monster_id"] < 1:
            log.info("do_attack: player: fb_uid = " + uid + " found nothing to attack ")
            return player
        else:
            log.info("do_attack: player: fb_uid = %s attacks mon_id = %d " % (uid, player["monster_id"]))
            i = random.randint(1,100)
            if i > 30: # dummy hit
                mon_hp = player["monster_hp"]
                mon_hp -= random.randint(2,20) 
                if mon_hp < 1:
                    log.info("do_attack: player: fb_uid = %s kills mon_id = %d " % (uid, player["monster_id"]))
                    player["monster_id"] = 0
                    player["monster_hp"] = 0
                    player["xp"] += 1
                    player["gold"] += random.randint(2,20)
                else:
                    log.info("do_attack: player: fb_uid = %s hits mon_id = %d " % (uid, player["monster_id"]))
                    player["monster_hp"] = mon_hp 
                player["timestamp"] = time.time()
                cursor.save(player)
            else: #miss
                log.info("do_attack: player: fb_uid = %s misses mon_id = %d " % (uid, player["monster_id"]))
                player["timestamp"] = time.time()
                cursor.save(player)
             
        return player #is this needed?
    else:
        log.error("do_attack: couldn't connect to db")
        return None
 def process_pending_list(self):
     """
     Process all pending tasks.
     """
     log.info('pending_queue = ' + str(self.pending_queue.qsize())) 
 def do_move(self, uid, direction):
     log.info("controller: called do_move uid = %s, d = %s" % (uid, direction))
     return app.db.do_move(uid, direction) 
 def process_done_list(self):
     """
     Finish any tasks that have completed.
     """
     log.info('done_queue = ' + str(self.done_queue.qsize())) 
import datetime

from app.log import mylogger as log
from app.daemon import Daemon
import app.config
import app.timer
import app.config
import app.timer
import app.db
import app.httpd
import app.worker

PROGNAME = 'dad'
VERSION = '0.0.13'

log.info(PROGNAME + ' version ' + VERSION + ' starting')

class MyDaemon(Daemon):
    def run(self):

        log.info('Starting Database: ')
        DB = app.db.test_database()
        if DB:
            log.info('Database started')
        else:
            log.critical('Database failed to initalize - aborting')
            sys.exit(1)

        app.db.add_news(0, time.time(), "http://da.mithrilsoft.com/da/assets/images/logo_50x50.gif", "Server version %s was restarted at %s" % (VERSION, datetime.datetime.now()))

        log.info('Starting Webserver: ')