def recordTime(uuid, customTime=-1): if not uuid: return if customTime > 0: clockTime = customTime else: clockTime = time.time() #Check for incomplete time slots incompleteTime = db.fetchOne(queries.check_for_open, (uuid, )) if incompleteTime: #Ignore incomplete entry if over 18 hours old. if time.time() - incompleteTime[0] > 3600 * 18: print("Removed time for ", uuid) db.execute(queries.cancel_open_member_clock, (uuid, )) #Ignore accidental triggers close to login elif time.time() - incompleteTime[0] < DEBOUNCE: print("Ignoring accidental trigger.") return else: print("Closed time for ", uuid) db.execute(queries.close_clock, ( clockTime, uuid, )) return #If no open time is found, create a login lastOutTime = db.fetchOne(queries.get_last_member_clock_out, (uuid, )) if lastOutTime and lastOutTime[0]: if time.time() - lastOutTime[0] < DEBOUNCE: print("Ignoring accidental trigger.") return print("Opened time for ", uuid) db.execute(queries.clock_member, (uuid, currentEvent, clockTime, -1))
def registerMember(name, uuid): #Delete old entries from uuid to be registered db.execute(queries.clear_member_clocks, (uuid, )) #Migrate past user entries to new ID lastUUID = db.fetchOne(queries.get_uuid_by_name, (name, )) if lastUUID: for entry in db.fetchAll(queries.get_clocks, (lastUUID[0], )): db.execute(queries.clock_member, ( uuid, entry[0], entry[1], entry[2], )) db.execute(queries.clear_member_clocks, (lastUUID[0], )) #If uuid has been registered, update name and register time, otherwise insert new entry if db.fetchOne(queries.check_member_exists, (uuid, )): db.execute(queries.update_name, ( name, time.time(), uuid, )) else: db.execute(queries.register_member, (uuid, name, time.time()))
def formDelete(self): if (self.ID): db.fetchOne("delete from ogrencibilgi where id={}".format(self.ID)) self.formList() else: QtWidgets.QMessageBox.critical(self, "HATA", "ID bulunamadı!") self.ID = 0
def register(self, nickname="", email_reg="", **args): if (nickname == "" or nickname == "Nickname"): return self.register_complete("Username is empty") if (email_reg == "") or (email_reg == "E-Mail Address") or (email_reg.lower()[-7:] != "@si.lan"): return self.register_complete("Email address is invalid, must be @si.lan") SanitizeValues = dict() SanitizeValues["nickname"] = nickname SanitizeValues["email_reg"] = email_reg SanitizeValues = db.sanitize(**SanitizeValues) nickname = SanitizeValues["nickname"] email_reg = SanitizeValues["email_reg"] (ret, row) = db.fetchOne(cherrypy.thread_data.conn,'SELECT id FROM assassins WHERE lower(nickname)=?', (nickname.lower(),)) if row != None and len(row) != 0: return self.register_complete("Nickname already in use") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,'SELECT id FROM assassins WHERE email_address=?', (email_reg.lower(),)) if row != None and len(row) != 0: return self.register_complete("Email address already in use") password = ''.join([random.choice(string.letters + string.digits) for i in range(8)]) passwordhash = bcrypt.hashpw(password, bcrypt.gensalt()) try: db.execute(cherrypy.thread_data.conn,"insert into Assassins(nickname, email_address, password) values(?, ?, ?)", (nickname, email_reg.lower(), passwordhash)) self.SendEmail(email_reg.lower(), "Welcome to Nerf Assassin.\r\nYour nickname is: %s\r\nYour password is: %s\r\n\r\nPasswords are case sensitive\r\n" % (nickname, password)) return self.register_complete("New assassin created, email sent to %s" % (email_reg), "") except Exception, ex: return self.register_complete("Error creating a new assassin")
def stats(self): (ret, rows) = db.fetchAll(cherrypy.thread_data.conn,"select id, firstname, lastname, nickname, ranking from assassins where ranking is not null order by ranking, firstname, lastname, nickname") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from games where end_datetime is null") if(row == None or len(row) == 0): game_id = 0 else: (game_id,) = row StatData = [] for Entry in rows: (id, firstname, lastname, nickname, ranking) = Entry dictEntry = dict() dictEntry["profile_id"] = id dictEntry["firstname"] = firstname dictEntry["lastname"] = lastname dictEntry["nickname"] = nickname dictEntry["rank"] = html.ordinal(ranking) dictEntry["total_assassinations"] = 0 (ret, rowcount) = db.fetchOne(cherrypy.thread_data.conn,"Select count(killer_id) from gameinfo where killer_id=? and game_id != ?", (id, game_id)) if(ret == True and rowcount != None): (dictEntry["total_assassinations"],) = rowcount (ret, rowcount) = db.fetchOne(cherrypy.thread_data.conn,"Select count(target_id) from gameinfo where target_id=? and killer_id is not null and killer_id != 0 and game_id != ?", (id, game_id)) if(ret == True and rowcount != None): (dictEntry["total_deaths"],) = rowcount StatData.append(dictEntry) (ret, rows) = db.fetchAll(cherrypy.thread_data.conn,"select id, firstname, lastname, nickname, ranking from assassins where ranking is null order by ranking, firstname, lastname, nickname") for Entry in rows: (id, firstname, lastname, nickname, ranking) = Entry dictEntry = dict() dictEntry["profile_id"] = id dictEntry["firstname"] = firstname dictEntry["lastname"] = lastname dictEntry["nickname"] = nickname dictEntry["rank"] = html.ordinal(ranking) dictEntry["total_assassinations"] = 0 (ret, rowcount) = db.fetchOne(cherrypy.thread_data.conn,"Select count(killer_id) from gameinfo where killer_id=? and game_id != ?", (id, game_id)) if(ret == True and rowcount != None): (dictEntry["total_assassinations"],) = rowcount (ret, rowcount) = db.fetchOne(cherrypy.thread_data.conn,"Select count(target_id) from gameinfo where target_id=? and killer_id is not null and killer_id != 0 and game_id != ?", (id, game_id)) if(ret == True and rowcount != None): (dictEntry["total_deaths"],) = rowcount StatData.append(dictEntry) StatHTML = open("static/stats.html","r").read() StatHTML = html.HTMLCheckLoggedIn(self.ValidateLogin(), StatHTML) return html.HTMLReplaceSection(self.ValidateLogin(), "stat", StatHTML, StatData)
def formSave(self): isim = self.isimLe.text() sinif = self.sinifLe.text() alan = self.alanLe.text() email = self.emailLe.text() if isim and sinif and alan and email: db.fetchOne( "insert into ogrencibilgi (isim,sinif,alan,email) values ('{}','{}','{}','{}')" .format(isim, sinif, alan, email)) self.formList() else: QtWidgets.QMessageBox.critical( self, "HATA", "Tüm alanlar zorunludur ve doldurmanız gerekmektedir!")
def formUpdate(self): isim = self.isimLe.text() sinif = self.sinifLe.text() alan = self.alanLe.text() email = self.emailLe.text() if isim and sinif and alan and email and self.ID: db.fetchOne( "update ogrencibilgi set isim='{}', sinif='{}', alan='{}', email='{}' where id={}" .format(isim, sinif, alan, email, self.ID)) self.formList() else: QtWidgets.QMessageBox.critical( self, "HATA", "Tüm alanlar zorunludur ve doldurmanız gerekmektedir!") self.ID = 0
def UpdateLCD(): global lcd (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select sum(amount) from money") (Amount,) = row lcd.clear() lcd.home() lcd.writeString("Samantha's Money") lcd.setPosition(2, 0) lcd.writeString("%0.2f" % (Amount))
def sessions(id): room = session.get('session_id') sessionObject = db.fetchOne({'_id': ObjectId(room)}) messages = sessionObject['messages'] session['unplaced_pieces'] = sessionObject['unplaced_pieces'][ session['user_id']] session['board_state'] = g.board_state = sessionObject['board_state'] session['phase'] = sessionObject['phase'] g.messages = [message for message in messages if len(message) == 2] return render_template('session.html')
def handle_my_custom_event(json, methods=['GET', 'POST']): print('received my event: ' + str(json)) room = session.get('session_id') socketio.emit('my response', json, callback=messageReceived, room=room) gameSession = db.fetchOne({'_id': ObjectId(room)}) gameSession['messages'].append(json) db.updateOne({'_id': ObjectId(room)}, {'$set': { 'messages': gameSession['messages'] }})
def confirm_kill(self, **args): if(self.ValidateLogin()): if "confirm" in args: confirm = args["confirm"] else: confirm = cherrypy.session.pop("confirm_hash", None) if(confirm == None): return self.profile() if "confirmed" not in args: return html.HTMLReplaceSection(self.ValidateLogin(), "confirm", open("static/confirm.html","r").read(), [{"confirm":confirm, "url":"confirm_kill"}]) else: if(args["confirmed"] == 0): #email the assassin and notify them (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select a.nickname, a.email_address, gi.target_id, gi.id from assassins a, gameinfo gi, games g where gi.game_id = g.id and g.end_datetime is null and gi.confirm_hash=? and a.id=gi.reporting_killer", (confirm,)) if(row != None and len(row) != 0): (nickname, assassin_email, target_id, gameinfo_id) = row if(target_id == None): db.execute(cherrypy.thread_data.conn,"delete from gameinfo where id=?", (gameinfo_id,)) self.SendEmail(assassin_email, "%s\nThe target did not confirm your kill" % (nickname)) return html.display_message(self.ValidateLogin(), "Kill not confirmed") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select gi.id, gi.target_id, gi.reporting_killer from gameinfo gi, games g where gi.game_id = g.id and g.end_datetime is null and gi.confirm_hash=? and killer_id is null", (confirm,)) if(confirm == None or row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Invalid confirmation code") (gameinfo_id, target_id, reporting_killer) = row #if no target then this was a kill without it being a known target if(target_id == None): db.execute(cherrypy.thread_data.conn,"delete from gameinfo where id=?", (gameinfo_id,)) return self.kill_player(reporting_killer) elif("confirm" in args): cherrypy.session["confirm_hash"] = args["confirm"] raise cherrypy.HTTPRedirect("/login.html") return html.display_message(self.ValidateLogin(), "Invalid confirmation code")
def invalidpic(self, id): if(self.ValidateLogin() and cherrypy.session.get("ProfileID") == 1): (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select nickname, email_address, picture_filename from assassins where picture_filename is not null and id=?", (id,)) (nickname, email, picture) = row if(picture == None): return html.display_message(self.ValidateLogin(), "No picture found") db.execute(cherrypy.thread_data.conn,"Update assassins set picture_filename=Null where id=?", (id,)) (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from games where end_datetime is null") if(row != None and len(row) != 0): (gameid,) = row db.execute(cherrypy.thread_data.conn,"delete from gameinfo where assassin_id=? and target_id=Null and game_id=?", (id, gameid)) os.remove("profile-images/" + picture) self.SendEmail(email, "Your picture was invalid and removed. If you were part of a game then you have been removed from the game for an invalid profile picture") return html.display_message(self.ValidateLogin(), "Picture removed and email sent") else: return html.display_message(self.ValidateLogin(), "No access")
def kill_player(self, killer_id): #called when we are to kill the local player profile_id = cherrypy.session.get("ProfileID") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select gi.id, g.id, gi.assassin_id from games g, gameinfo gi where gi.game_id = g.id and gi.target_id=? and g.end_datetime is null and gi.killer_id is null", (profile_id,)) if(row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Error updating kills") (gameinfo_id, game_id, assassin_id) = row #figure out the ranking (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select min(ranking) from gameinfo where game_id=?", (game_id,)) (ranking,) = row if(row == None or len(row) == 0 or ranking == None): (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select count(distinct(target_id))+1 from gameinfo where game_id=?", (game_id,)) (ranking,) = row ranking = int(ranking) ranking = ranking - 1 db.execute(cherrypy.thread_data.conn,"update gameinfo set killer_id=?, kill_datetime=datetime('now'), ranking=? where id=?", (killer_id, ranking, gameinfo_id)) #lookup who this player's target was (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select target_id from gameinfo where assassin_id=? and game_id=? and killer_id is null", (profile_id,game_id)) (target_id,) = row #mark the record for this player to be no kill db.execute(cherrypy.thread_data.conn,"update gameinfo set killer_id=0 where game_id=? and target_id=? and assassin_id=? and killer_id is null", (game_id, target_id, profile_id)) #don't insert if the assassin and target match as it is end of the game if(target_id != assassin_id): db.execute(cherrypy.thread_data.conn,"insert into gameinfo (game_id, assassin_id, target_id) values(?,?,?)", (game_id, assassin_id, target_id)) #report the new target to the assassin (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select a.nickname, a.firstname, a.lastname, a.email_address, b.firstname, b.lastname, b.nickname, b.picture_filename from assassins a, assassins b, gameinfo gi where gi.game_id=? and a.id=gi.assassin_id and gi.assassin_id=? and b.id=gi.target_id and gi.killer_id is null", (game_id, assassin_id)) (assassin_nick, assassin_first, assassin_last, assassin_email, target_first, target_last, target_nick, target_picture) = row self.SendEmail(assassin_email, "%s, your target is now %s, also known as %s %s. Attached is your target's picture" % (assassin_nick, target_nick, target_first, target_last), target_picture) else: #update the last player to be first db.execute(cherrypy.thread_data.conn,"Update gameinfo set ranking=1 where killer_id=0 and target_id=? and game_id=? and assassin_id=?", (assassin_id, game_id, profile_id)) return html.display_message(self.ValidateLogin(), "Thank you for confirming your death")
def report_killed(self): if(self.ValidateLogin()): gamehash = ''.join([random.choice(string.letters + string.digits) for i in range(32)]) (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from games where end_datetime is null") if(row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "No active game") (game_id, ) = row db.execute(cherrypy.thread_data.conn,"insert into gameinfo(game_id, assassin_id, confirm_hash, reporting_killer) values(?,?,?,?)", (game_id, cherrypy.session.get("ProfileID"), gamehash, cherrypy.session.get("ProfileID"))) return html.display_message(self.ValidateLogin(), "Please provide the following URL to the person you killed<br>%s" % ("http://tank:8080/confirm_kill?confirm=" + gamehash)) else: raise cherrypy.HTTPRedirect("/")
def gamecheck(self): #check on any games that are active or becoming active for assignment (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id, start_datetime [timestamp], gametype from games where end_datetime is null") if(row == None or len(row) == 0): return #we have a game that will start or is running, determine and assign accordingly (gameid, starttime, gametype) = row #if the time is in the future, exit if(starttime > datetime.datetime.utcnow()): return #see if we need to do assignments (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select id, assassin_id, target_id from gameinfo where game_id=? order by target_id desc", (gameid,)) if(len(players) <= 1): #no players or only 1 player, time is past, remove the game db.execute(cherrypy.thread_data.conn,"delete from games where id=?", (gameid,)) return Game = NerfGames.GetGameByID(gametype) Game.NerfAssassin = NerfAssassin Game.db = db Game.GameID = gameid Game.GameTypeID = gametype (id, assassin_id, target_id) = players[0] if(target_id == None): Game.AssignPlayers(players) else: #game has assignments, see if the game is over yet Game = NerfAssassin.GetGameByID(gametype) Game.NerfAssassin = NerfAssassin Game.db = db Game.GameID = gameid Game.GameTypeID = gametype if(Game.IsGameOver()): #if no one left to kill, game over db.execute(cherrypy.thread_data.conn,"update games set end_datetime=datetime(\"now\") where id=?", (gameid,)) #remove any outstanding reports db.execute(cherrypy.thread_data.conn,"delete from gameinfo where reporting_killer is not null and target_id is null and game_id=?",(gameid,)) #do a stats update for the game type Game.CalculateStats() else: Game.CheckConfirmationTimeout() del Game return
def lastClock(uuid, events=[currentEvent]): if not uuid: return 0 if not events or len(events) == 0: return 0 eventString = "(" for i in range(0, len(events) - 1): eventString += "\"" + events[i] + "\", " eventString += "\"" + events[len(events) - 1] + "\")" clock = queries.get_last_member_clock_out_by_event + eventString last = db.fetchOne(clock, (uuid, )) if last and len(last) > 0: return last[0]
def target_killed(self, id): if(self.ValidateLogin()): #make sure that the request is valid (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select gi.id, a.email_address from gameinfo gi, games g, assassins a where gi.assassin_id=? and gi.target_id=? and gi.game_id=g.id and g.end_datetime is null and a.id=gi.target_id", (cherrypy.session.get("ProfileID"), id)) if row != None and len(row) != 0: (gameinfo_id, email_address) = row gamehash = ''.join([random.choice(string.letters + string.digits) for i in range(32)]) db.execute(cherrypy.thread_data.conn,"update gameinfo set confirm_hash=?, reporting_killer=? where id=?", (gamehash, cherrypy.session.get("ProfileID"), gameinfo_id)) self.SendEmail(email_address, "It was reported that you have been assassinated. Please goto the following link to confirm your assassination.\n%s" % ("http://tank:8080/confirm_kill?confirm=" + gamehash)) return html.display_message(self.ValidateLogin(), "Email sent") else: return html.display_message(self.ValidateLogin(), "Invalid ID") else: raise cherrypy.HTTPRedirect("/")
def ValidateLogin(self, nickname="", password=""): cherrypy.session.load() if((nickname == "") and (password == "")): try: nickname = cherrypy.session.get("Nickname") password = cherrypy.session.get("Password") if(nickname == None or password == None): return False except: return False (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id, password from assassins where lower(nickname)=?", (nickname.lower(),)) if(row != None and len(row) != 0): (profileid, dbpass) = row if(bcrypt.hashpw(password,str(dbpass)) == str(dbpass)): cherrypy.session["Nickname"] = nickname cherrypy.session["Password"] = password cherrypy.session["ProfileID"] = profileid cherrypy.session.save() return True else: return False return False
import db, queries, time #Time in seconds to wait before allowing another time event for a user. DEBOUNCE = 5 events = [] for event in db.fetchAll(queries.get_events): if len(event) > 0: events.append(event[0]) curr = db.fetchOne(queries.get_current_event) if curr and len(curr) > 0: currentEvent = curr[0] else: currentEvent = events[0] def createEvent(eventName): db.execute(queries.create_event, (eventName, )) events.append(eventName) def registerMember(name, uuid): #Delete old entries from uuid to be registered db.execute(queries.clear_member_clocks, (uuid, )) #Migrate past user entries to new ID lastUUID = db.fetchOne(queries.get_uuid_by_name, (name, )) if lastUUID: for entry in db.fetchAll(queries.get_clocks, (lastUUID[0], )):
def enterGame(username=None, password=None): if request.method == 'POST': if username is None: username = request.form['username'] if password is None: password = request.form['password'] error = None session_code = None try: session_code = request.form['session_code'] print('session found: ' + session_code) except: print('no code found') if session_code is None: session_code = get_random_alphaNumeric_string(5) db.createSession({ 'code': session_code, 'users': {}, 'board_state': board.grid, 'phase': 'preparation', 'unplaced_pieces': {}, 'messages': [] }) print('session created: ' + session_code) if username is None: error = 'Please provide a username. You can make one up.' else: gameSession = db.fetchOne({'code': session_code}) session.clear() # check if user exists in current session if username in gameSession['users']: print('existing username found...') session_id, color, phase = gameSession['_id'], gameSession[ 'users'][username]['color'], gameSession['phase'] if not check_password_hash( gameSession['users'][username]['password'], password): error = 'Incorrect password.' else: print('users\n', gameSession['users']) if len(gameSession['users']) == 1: color = 'red' else: color = 'blue' gameSession['users'].update({ username: { 'password': generate_password_hash(password), 'color': color } }) gameSession['unplaced_pieces'].update({ username: [(key, pieces_reference[key].maxQuantity) for key in pieces_reference] }) db.updateOne({'code': session_code}, { '$set': { 'users': gameSession['users'], 'unplaced_pieces': gameSession['unplaced_pieces'] } }) phase = gameSession['phase'] session_id = str(gameSession['_id']) if error is None: session['user_id'], session['session_code'], session[ 'session_id'], session['color'], session[ 'phase'] = username, session_code, session_id, color, phase return redirect(url_for('sessions', id=session_id)) flash(error) return render_template('auth/login.html')
def creategame(self, **args): if(self.ValidateLogin()): args = db.sanitize(**args) #make sure the user is allowed to create a game (ret, createcheck) = db.fetchOne(cherrypy.thread_data.conn,"select picture_filename, firstname, lastname from assassins where id=? and (firstname is Null or lastname is Null or picture_filename is Null)", (cherrypy.session.get("ProfileID"),)) if(createcheck != None and len(createcheck) != 0): return html.display_message(self.ValidateLogin(), "You can not create a game until your full first and last name is filled in and a face picture is provided") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"Select id from games where end_datetime is null") if(row == None or len(row) == 0): if(args["gamerules"] == "0"): if(args["newrules_name"] == "" or args["newrules"] == ""): return html.display_message(self.ValidateLogin(), "No name specified or new rules are empty") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from rules where lower(rulename) = ?", (args["newrules_name"].lower(),)) if(row != None and len(row) != 0): return html.display_message(self.ValidateLogin(), "Rule already exists") args["newrules"] = args["newrules"].replace("\r","") db.execute(cherrypy.thread_data.conn,"insert into rules(rulename, rules) values(?,?)", (args["newrules_name"], args["newrules"])) (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from rules where lower(rulename) = ?", (args["newrules_name"].lower(),)) (args["gamerules"], ) = row try: Date = args["gamestart_date"].split("/") NewDate = "%02d/%02d/%04d" % (int(Date[0]), int(Date[1]), int(Date[2])) Time = args["gamestart_time"].split(":") if(Time[1].find(" ") != -1): Time2 = Time[1].split(" ") else: Time2 = [] Time2.append(Time[1][0:2]) Time2.append(Time[1][2:4]) NewTime = "%02d:%02d %s" % (int(Time[0]), int(Time2[0]), Time2[1]) StartDate = datetime.datetime.strptime(NewDate + " " + NewTime, "%m/%d/%Y %I:%M %p") except Exception, ex: print ex return html.display_message(self.ValidateLogin(), "Error converting specified date and time") if(StartDate < datetime.datetime.now()): return html.display_message(self.ValidateLogin(), "Start date and time can not be in the past") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from rules where id = ?", (args["gamerules"],)) if(row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Invalid rule") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from gametypes where id = ?", (args["gametypeid"],)) if(row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Invalid game type") #adjust for utc LocalStartDate = StartDate StartDate = StartDate + (datetime.datetime.utcnow() - datetime.datetime.now()) db.execute(cherrypy.thread_data.conn,"insert into games(start_datetime, rule_id) values(datetime(?),?,?)", (StartDate.strftime("%Y-%m-%d %H:%M"), args["gamerules"], args["gametypeid"])) (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select id from games where end_datetime is null") (game_id,) = row db.execute(cherrypy.thread_data.conn,"insert into gameinfo(game_id, assassin_id) values(?,?)", (game_id, cherrypy.session.get("ProfileID"))) #now email everyone (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select nickname, email_address from assassins where email_newgames=1") for Entry in players: (nickname, email) = Entry self.SendEmail(email, "%s:\nA new game is starting at %s. Login and join if you wish to play." % (nickname, LocalStartDate.strftime("%b %d, %Y %I:%M %p")))
def games(self, **args): (ret, rows) = db.fetchAll(cherrypy.thread_data.conn,"select g.id, g.start_datetime [timestamp], g.end_datetime [timestamp], r.rules, g.gametype, gt.name from games g left join rules r on g.rule_id=r.id left join gametypes gt on g.gametype=gt.id order by g.start_datetime desc") GameHTML = open("static/games.html", "r").read() GameHTML = html.HTMLCheckLoggedIn(self.ValidateLogin(), GameHTML) ProfileID = cherrypy.session.get("ProfileID") if(ProfileID == None): ProfileID = 0 GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "joingame", GameHTML) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "newgame", GameHTML) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "creategame", GameHTML) #the very first row is the latest game if(len(rows) == 0): #no games, fake some data so we will still create the labels as needed start_datetime = datetime.datetime(2000,1,1) end_datetime = start_datetime else: (gameid, start_datetime, end_datetime, rules) = rows[0] if(start_datetime > datetime.datetime.utcnow()): #convert back to our timezone curtime = datetime.datetime.utcnow() - datetime.datetime.now() start_datetime = start_datetime - curtime CounterData = [{"year":start_datetime.year, "month":start_datetime.month-1, "day":start_datetime.day, "hour":start_datetime.hour, "minute":start_datetime.minute, "serveryear":curtime.year, "servermonth":curtime.month-1,"serverday":curtime.day, "serverhour":curtime.hour, "serverminute":curtime.minute}] GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "counter", GameHTML, CounterData) if(ProfileID != 0): #if we have a status update, do it here as it is allowed if("status" in args): if args["status"] == "join": #asking to join, make sure that a profile picture and full name exists (ret, joincheck) = db.fetchOne(cherrypy.thread_data.conn,"select picture_filename, firstname, lastname from assassins where id=? and (firstname is Null or lastname is Null or picture_filename is Null or firstname='' or lastname='')", (ProfileID,)) if(joincheck != None and len(joincheck) != 0): return html.display_message(self.ValidateLogin(), "You can not join a game until your full first and last name is filled in and a face picture is provided") db.execute(cherrypy.thread_data.conn,"insert into gameinfo(game_id, assassin_id) values(?,?)", (gameid, ProfileID)) elif args["status"] == "leave": db.execute(cherrypy.thread_data.conn,"delete from gameinfo where game_id=? and assassin_id=?", (gameid, ProfileID)) (ret, ingame) = db.fetchOne(cherrypy.thread_data.conn,"select id from gameinfo where game_id=? and assassin_id=?", (gameid, ProfileID)) if(ingame != None and len(ingame) != 0): GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "joingame", GameHTML, [{"url":"games?status=leave","text":"Leave Game","id":""}]) else: GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "joingame", GameHTML, [{"url":"games?status=join","text":"Join Game","id":""}]) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "newgame", GameHTML) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "creategame", GameHTML) else: GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "counter", GameHTML) if(ProfileID != 0): if(end_datetime == None): GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "joingame", GameHTML) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "newgame", GameHTML) GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "creategame", GameHTML) else: GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "joingame", GameHTML, [{"url":"#newgame", "text":"Start Game","id":"newgame-link"}]) GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "newgame", GameHTML, [{"d":"d"}]) #fill in data to allow a new game GameData = [] dictEntry = dict() NewDate = datetime.datetime.now() + datetime.timedelta(3,60*60) dictEntry["startdate"] = NewDate.strftime("%m/%d/%Y") dictEntry["starttime"] = NewDate.strftime("%I:00 %p") dictEntry["SubSection"] = [] #setup the rules RuleNames = [] RuleData = [] (ret, rulerows) = db.fetchAll(cherrypy.thread_data.conn,"select id, rulename, rules from rules order by rulename") for Entry in rulerows: NewEntry = dict() NewDataEntry = dict() (NewEntry["id"], NewEntry["name"], NewDataEntry["rules"]) = Entry NewDataEntry["rules"] = NewDataEntry["rules"].replace("\r","") NewDataEntry["rules"] = NewDataEntry["rules"].replace("\n","\\n") RuleNames.append(NewEntry) RuleData.append(NewDataEntry) dictEntry["SubSection"].append(("rulelist", RuleNames)) dictEntry["SubSection"].append(("ruledata", RuleData)) if(len(RuleData) != 0): dictEntry["firstindex"] = 1; else: dictEntry["firstindex"] = 0; GameData.append(dictEntry) GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "creategame", GameHTML, GameData) #if the game hasn't ended then display info about it if(end_datetime == None): rows.pop(0) #fill in the current game StatData = [] dictEntry = dict() dictEntry["game_start"] = start_datetime.strftime("%b %d, %Y") if(rules != None): dictEntry["rules"] = rules.replace("\n","<br>") else: dictEntry["rules"] = "" #see if anyone is assigned yet as target should have a value and are either still alive or last one standing has no killer and is ranked already (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select distinct a.id from assassins a, gameinfo gi where gi.game_id=? and gi.target_id=a.id and ((gi.killer_id is null) or (gi.killer_id = 0 and gi.ranking = 1))", (gameid,)) if(len(players) == 0): #possible that no one is assigned yet, get those that are about to play (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select distinct a.id from assassins a, gameinfo gi where gi.game_id=? and gi.assassin_id=a.id", (gameid,)) dictEntry["SubSection"] = [] SubSection = [] AlivePlayers = [] #set a flag as we remove the current profile from AlivePlayers so the player can see their kills if(players == None or len(players) == 0): HavePlayers = 0 else: HavePlayers = 1 for Entry in players: (player_id,) = Entry SubSection.append({"name":"Assassin"}) if(player_id != ProfileID): AlivePlayers.append(player_id) dictEntry["SubSection"].append(("winner", SubSection)) (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select gi.kill_datetime [timestamp], a.id, a.firstname, a.lastname, a.nickname, b.id, b.firstname, b.lastname, b.nickname, gi.ranking from assassins a, assassins b, gameinfo gi where gi.target_id=a.id and gi.killer_id=b.id and gi.game_id=? and gi.killer_id != 0 and gi.kill_datetime is not null order by gi.ranking asc", (gameid,)) SubSection = [] if(len(players) == 0 and HavePlayers == 0): SubSection.append({"kill_date":"","profile_id":"","name":"","killer_name":"","killer_profile_id":"","rank":""}) else: for Entry in players: NewEntry = dict() (NewEntry["kill_date"], NewEntry["profile_id"], firstname, lastname, nickname, NewEntry["killer_profile_id"], killer_fname, killer_lname, killer_nname, ranking) = Entry NewEntry["name"] = str(firstname) + " " + str(lastname) + " (" + str(nickname) + ")" if(NewEntry["killer_profile_id"] in AlivePlayers): NewEntry["killer_profile_id"] = 0 NewEntry["killer_name"] = "Assassin" else: NewEntry["killer_name"] = str(killer_fname) + " " + str(killer_lname) + " (" + str(killer_nname) + ")" NewEntry["rank"] = html.ordinal(ranking) NewEntry["kill_date"] = NewEntry["kill_date"].strftime("%b %d, %Y %H:%M") SubSection.append(NewEntry) dictEntry["SubSection"].append(("players", SubSection)) StatData.append(dictEntry) GameHTML = html.HTMLReplaceSection(self.ValidateLogin(), "latest_game", GameHTML, StatData) else: GameHTML = html.HTMLRemoveSection(self.ValidateLogin(), "latest_game", GameHTML) #if no games, remove the game block if(len(rows) == 0): return html.HTMLRemoveSection(self.ValidateLogin(), "games", GameHTML) StatData = [] for Entry in rows: (gameid, start_datetime, end_datetime, rules) = Entry dictEntry = dict() if(rules != None): dictEntry["rules"] = rules.replace("\n", "<br>") else: dictEntry["rules"] = "" dictEntry["game_start"] = start_datetime.strftime("%b %d, %Y") if(end_datetime != None): dictEntry["game_end"] = end_datetime.strftime("%b %d, %Y") else: dictEntry["game_end"] = "" (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select a.id, a.firstname, a.lastname, a.nickname, a.smack, a.picture_filename, gi.ranking from assassins a, gameinfo gi where gi.target_id = a.id and gi.game_id=? and gi.ranking = 1 order by gi.ranking asc", (gameid,)) dictEntry["SubSection"] = [] SubSection = [] if(len(players) == 0): SubSection.append({"kill_date":"","name":"","profile_id":"","profile_image":"","nickname":"","smack":"","rank":""}) else: for Entry in players: NewEntry = dict() (NewEntry["profile_id"],firstname, lastname, nickname, NewEntry["smack"], NewEntry["profile_image"], ranking) = Entry NewEntry["kill_date"] = "Winner" NewEntry["name"] = str(firstname) + " " + str(lastname) + " (" + str(nickname) + ")" if(NewEntry["profile_image"] == None): NewEntry["profile_image"] = "images/bio-pic.jpg" else: NewEntry["profile_image"] = "profile-images/" + NewEntry["profile_image"] NewEntry["nickname"] = nickname NewEntry["rank"] = html.ordinal(ranking) SubSection.append(NewEntry) dictEntry["SubSection"].append(("winner", SubSection)) (ret, players) = db.fetchAll(cherrypy.thread_data.conn,"select gi.kill_datetime [timestamp], a.id, a.firstname, a.lastname, a.nickname, b.id, b.firstname, b.lastname, b.nickname, gi.ranking from assassins a, assassins b, gameinfo gi where gi.target_id=a.id and gi.killer_id=b.id and gi.game_id=? and gi.killer_id != 0 order by gi.ranking asc", (gameid,)) SubSection = [] if(len(players) == 0): SubSection.append({"kill_date":"","profile_id":"","name":"","killer_name":"","killer_profile_id":"","rank":""}) else: for Entry in players: NewEntry = dict() (NewEntry["kill_date"], NewEntry["profile_id"], firstname, lastname, nickname, NewEntry["killer_profile_id"], killer_fname, killer_lname, killer_nname, ranking) = Entry NewEntry["name"] = str(firstname) + " " + str(lastname) + " (" + str(nickname) + ")" NewEntry["killer_name"] = str(killer_fname) + " " + str(killer_lname) + " (" + str(killer_nname) + ")" NewEntry["rank"] = html.ordinal(ranking) NewEntry["kill_date"] = NewEntry["kill_date"].strftime("%b %d, %Y %H:%M") SubSection.append(NewEntry) dictEntry["SubSection"].append(("players", SubSection)) StatData.append(dictEntry) return html.HTMLReplaceSection(self.ValidateLogin(), "games", GameHTML, StatData)
def profile(self, id=None): ProfileHTML = open("static/profile.html","r").read() ProfileHTML = html.HTMLCheckLoggedIn(self.ValidateLogin(), ProfileHTML) if(id == None): id = cherrypy.session.get("ProfileID") (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select nickname, firstname, lastname, email_address, ranking, smack, picture_filename, email_newgames from assassins where id=?", (id,)) if(ret == False or row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Error accessing profile") (nickname, firstname, lastname, email, ranking, smack, picture_filename, email_newgames) = row if(picture_filename == None): picture_filename = "images/bio-pic.jpg" else: picture_filename = "profile-images/" + picture_filename ranking = html.ordinal(ranking) if(email_newgames): email_newgames="checked" else: email_newgames="" if((cherrypy.session.get("ProfileID") == None) or (int(id) != int(cherrypy.session.get("ProfileID")))): ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "edit", ProfileHTML) ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "target_header", ProfileHTML) ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "target", ProfileHTML) else: (ret, reportrow) = db.fetchOne(cherrypy.thread_data.conn,"select gi.id from gameinfo gi, games g where gi.game_id=g.id and g.end_datetime is null and gi.target_id=? and gi.killer_id is null", (id,)) EditDict = dict() EditDict["nickname"] = nickname EditDict["firstname"] = firstname EditDict["lastname"] = lastname EditDict["email"] = email EditDict["smacktalk"] = smack EditDict["email_newgames"] = email_newgames EditDict["SubSection"] = [] if(reportrow == None or len(reportrow) == 0): EditDict["SubSection"].append(("report_kill", [])) else: EditDict["SubSection"].append(("report_kill", [{"id":""}])) ProfileHTML = html.HTMLReplaceSection(self.ValidateLogin(), "edit", ProfileHTML, [EditDict]) #see if we have a target (ret, rows) = db.fetchAll(cherrypy.thread_data.conn,"select a.firstname, a.lastname, a.nickname, a.picture_filename, gi.killer_id, gi.target_id, ifnull(gi.kill_datetime, datetime('now')) as killdatetime from assassins a, gameinfo gi, games g where g.end_datetime is null and gi.game_id = g.id and gi.assassin_id=? and a.id=gi.target_id order by killdatetime desc", (id,)) if(len(rows) == 0): ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "target", ProfileHTML) ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "target_header", ProfileHTML) else: ProfileHTML = html.HTMLReplaceSection(self.ValidateLogin(), "target_header", ProfileHTML, [{"id":""}]) targets = [] for Entry in rows: NewTarget = dict() (NewTarget["firstname"], NewTarget["lastname"], NewTarget["nickname"], NewTarget["target_pic"], killer_id, target_id, kill_datetime) = Entry if(NewTarget["target_pic"] == None): NewTarget["target_pic"] = "images/bio-pic.jpg" else: NewTarget["target_pic"] = "profile-images/" + NewTarget["target_pic"] NewTarget["SubSection"] = [] if(killer_id == None): NewTarget["SubSection"].append(("kill_target", [{"id":target_id}])) NewTarget["SubSection"].append(("target_killed", [])) elif(killer_id == id): #report if we killed them NewTarget["SubSection"].append(("kill_target", [])) NewTarget["SubSection"].append(("target_killed", [{"notice":"Target Assassinated"}])) elif(killer_id == 0): #report if they survived our encounter NewTarget["SubSection"].append(("kill_target", [])) NewTarget["SubSection"].append(("target_killed", [{"notice":"Target Survived"}])) else: #someone else killed them NewTarget["SubSection"].append(("kill_target", [])) NewTarget["SubSection"].append(("target_killed", [{"notice":"Target Assassinated by Another Assassin"}])) if(killer_id == None): targets.insert(0, NewTarget) else: targets.append(NewTarget) ProfileHTML = html.HTMLReplaceSection(self.ValidateLogin(), "target", ProfileHTML, targets) (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select count(killer_id) from gameinfo where killer_id=?", (id,)) if(ret == False or row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Error getting kill list") (total_assassinations,) = row (ret, row) = db.fetchOne(cherrypy.thread_data.conn,"select count(target_id) from gameinfo where target_id=? and killer_id != 0", (id,)) if(ret == False or row == None or len(row) == 0): return html.display_message(self.ValidateLogin(), "Error getting death list") (total_deaths,) = row ProfileHTML = html.HTMLReplaceSection(self.ValidateLogin(), "profile", ProfileHTML, [{"nickname":nickname, "firstname":firstname, "lastname":lastname, "email":email, "rank":ranking, "smacktalk":smack, "total_assassinations":total_assassinations, "total_deaths":total_deaths, "profile_pic": picture_filename}]) StatData = [] sql = "select g.id, g.start_datetime [timestamp], g.end_datetime [timestamp], a.nickname, a.firstname, a.lastname, gi.killer_id, gi.ranking from games g, gameinfo gi left join assassins a on gi.killer_id=a.id where gi.game_id=g.id and gi.target_id=? and gi.ranking is not null" if(id != cherrypy.session.get("ProfileID")): sql = sql + " and g.end_datetime is not null" sql = sql + " order by g.id desc" (ret, rows) = db.fetchAll(cherrypy.thread_data.conn,sql, (id,)) if(len(rows) == 0): ProfileHTML = html.HTMLRemoveSection(self.ValidateLogin(), "game", ProfileHTML) else: for Entry in rows: dictEntry = dict() (game_id, dictEntry["game_start"], dictEntry["game_end"], killer_nickname, killer_firstname, killer_lastname, killer_id, ranking) = Entry dictEntry["game_start"] = dictEntry["game_start"].strftime("%b %d, %Y") if(dictEntry["game_end"] != None): dictEntry["game_end"] = dictEntry["game_end"].strftime("%b %d, %Y") dictEntry["rank"] = html.ordinal(ranking) if(killer_id == None or killer_id == 0): dictEntry["assassinated_by"] = "" else: dictEntry["assassinated_by"] = str(killer_firstname) + " " + str(killer_lastname) + " (" + str(killer_nickname) + ")" (ret, subrows) = db.fetchAll(cherrypy.thread_data.conn,"select a.nickname, a.firstname, a.lastname, gi.kill_datetime [timestamp], a.id from assassins a, gameinfo gi where gi.killer_id=? and gi.game_id=? and a.id=gi.target_id order by gi.kill_datetime asc", (id, game_id)) dictEntry["total_assassinations"] = len(subrows) dictEntry["SubSection"] = [] SubSection = [] if(len(subrows) == 0): SubSection.append({"kill_date":"", "rank":"", "name":"", "profile_id":""}) else: for SubEntry in subrows: NewEntry = dict() (killed_nickname, killed_firstname, killed_lastname, NewEntry["kill_date"], NewEntry["profile_id"]) = SubEntry NewEntry["rank"] = html.ordinal(0) NewEntry["name"] = str(killed_firstname) + " " + str(killed_lastname) + " (" + str(killed_nickname) + ")" NewEntry["kill_date"] = NewEntry["kill_date"].strftime("%b %d, %Y %H:%M") SubSection.append(NewEntry) dictEntry["SubSection"].append(("game_player", SubSection)) StatData.append(dictEntry) ProfileHTML = html.HTMLReplaceSection(self.ValidateLogin(), "game", ProfileHTML, StatData) return ProfileHTML
def sync_opposing_move(methods=['GET', 'POST']): room = session.get('session_id') gameSession = db.fetchOne({'_id': ObjectId(room)}) session['board_state'], session['phase'] = [ gameSession[attribute] for attribute in ['board_state', 'phase'] ]
def handle_board_state_change(json, methods=['GET', 'POST']): print('received board state: ' + str(json)) username = session['user_id'] room = session.get('session_id') board_state = session.get('board_state') board_state = { row: { key: { 'color': value['color'], 'piece': value['piece'] } for key, value in sorted(board_state[row].items(), key=lambda item: int(item[0])) } for row in board_state } origin_row = json['origin_cell'][0] origin_col = json['origin_cell'][1] destination_row = json['destination_cell'][0] destination_col = json['destination_cell'][1] unplaced_pieces = session.get('unplaced_pieces') if json['origin_cell'] != ['', '']: board_state[origin_row][origin_col]['piece'] = "" board_state[origin_row][origin_col]['color'] = "none" else: for piece in unplaced_pieces: if piece[0] == json['moved_piece']['piece']: piece[1] -= 1 #if two pieces from different teams collide, do battle def combat(piece1, piece2): # if piece being attacked is a flag, end the game if piece2['piece'] == '#': game_over = True else: game_over = False # determine winning piece if auth.pieces_reference[piece1['piece']].weakness == piece2['piece']: result = piece2 elif auth.pieces_reference[ piece2['piece']].weakness == piece1['piece']: result = piece1 elif auth.pieces_reference[piece1[ 'piece']].rank < auth.pieces_reference[piece2['piece']].rank: result = piece1 elif auth.pieces_reference[piece1[ 'piece']].rank == auth.pieces_reference[piece2['piece']].rank: result = {'piece': "", 'color': 'none'} elif auth.pieces_reference[piece1[ 'piece']].rank > auth.pieces_reference[piece2['piece']].rank: result = piece2 return result, game_over if board_state[destination_row][destination_col]['color'] not in [ 'none', json['moved_piece']['color'] ]: json['moved_piece'], json['game_over'] = combat( json['moved_piece'], board_state[destination_row][destination_col]) print(json) socketio.emit('own combat result', json, room=room) board_state[destination_row][destination_col] = json['moved_piece'] # fetch room info from db gameSession = db.fetchOne({'_id': ObjectId(room)}) # update unplaced pieces record gameSession['unplaced_pieces'][username] = unplaced_pieces current_phase = gameSession['phase'] # sum up total pieces unplaced, change phases if necessary total_pieces = 0 if current_phase == "preparation": for user in gameSession['unplaced_pieces']: for piece in gameSession['unplaced_pieces'][user]: total_pieces += piece[1] # check if both players have entered the game and placed all their pieces if (total_pieces == 0) and (len(gameSession['unplaced_pieces']) == 2): current_phase = "blue" elif current_phase == "blue": current_phase = "red" elif current_phase == "red": current_phase = "blue" try: if json['game_over'] == True: current_phase = json['responsible_team'] + '_wins' except KeyError: pass json['phase'] = current_phase # emit response to clients socketio.emit('my response', json, callback=messageReceived, room=room) # update unplaced pieces record for this player, to be re-inserted in db below gameSession['unplaced_pieces'][username] = unplaced_pieces # update board state, phase, and unplaced pieces records in database db.updateOne({'_id': ObjectId(room)}, { '$set': { 'board_state': board_state, 'unplaced_pieces': gameSession['unplaced_pieces'], 'phase': current_phase } }) # update same attributes from above in user's session cookie session['board_state'], session['unplaced_pieces'], session[ 'phase'] = board_state, unplaced_pieces, current_phase print(board_state)