def login(): form = LoginForm() # data has been through valid data checkers at this point (see forms.py) user = form.user.data team = form.team.data room = 'room'+str(form.room.data) # on form submission - create accounts, add them to database, and redirect to song page if form.validate_on_submit() and not current_user.is_authenticated: admin_flag = 1 if team in adminTokens else 0 # check if admin if admin_flag == 1: team = 'admins_' + room # delete user if already in database (to reset user values) player = User.query.filter_by(username=user, room=room).first() if player != None: User.query.filter_by(id=player.id).delete() db.session.commit() # create user, save user in DB, log in user, redirect player = User(username=user, teamname=team, room=room, admin=admin_flag, session='n/a', song='') db.session.add(player) db.session.commit() login_user(player) socketio.emit('send-msg', ['Server [All]', f'{user} has entered the room.', 0], broadcast=True, room=room) return redirect('song') elif current_user.is_authenticated: return redirect('song') # if form hasn't been submitted and no user is logged in -> load login screen return render_template('login.html', title='Login', form=form)
def inputFrame(frame): room_key = f'{current_user.teamname}_{current_user.song}_{current_user.room}_{current_user.admin}' if current_user.admin == 1: room_key = room_key + '_' + current_user.username if room_key in rooms and rooms[room_key].gameOver() == False and rooms[room_key].secondsLeft() > 0: room = rooms[room_key] # returns true if correct else returns hint correct = room.checkFrame(frame) won = room.won() if correct: # if won then game's over if won: msg = 'Congratulations! Your team loaded the song! GAME OVER' socketio.emit('send-msg', ['Server [Team]', msg, 0], room=room_key) # onto the next frame if frame is correct else: msg = f'Good job! You have 10 seconds to send frame {room.current_frame}.' socketio.emit('send-msg', ['Server [Team]', msg, 0], room=room_key + '_ready') else: # game over if frame incorrect msg = f'{current_user.username} submitted the wrong frame GAME OVER [input({frame}) - {correct}]' socketio.emit('send-msg', ['Server [Team]', msg, 0], room=room_key + '_ready') del rooms[room_key] # ends game loop if won or lost if won: socketio.emit('close-loop', win=True, room=room_key + '_ready') elif not correct: socketio.emit('close-loop', win=False, room=room_key + '_ready')
def sendTeamMsg(msg): sender = f'{current_user.username} [team] [admin]' if current_user.admin == 1 else f'{current_user.username} [team] [{current_user.teamname}]' room_key = 'admins_' + current_user.room if current_user.admin == 1 else f'{current_user.teamname}_{current_user.room}_{current_user.admin}' color_flag = 3 if current_user.admin != 1 else 1 # all team messages are sent to admins so they can moderate chat socketio.emit('send-msg', [sender, msg, color_flag], room=f'admins_{current_user.room}') # only send message here if user is not admin because it was already sent to admin (in the line of code above this comment) if current_user.admin != 1: socketio.emit('send-msg', [sender, msg, color_flag], room=room_key)
def teamMsg(to, msg): if to == '/admin': sendAdminMsg(msg) elif to == '/team': sendTeamMsg(msg) elif to == '/all': sendAllMsg(msg) elif to == '/private': sendPrivateMessage(msg) else: socketio.emit('send-msg', ['Server', 'Something went wrong. Your message was not sent. Try again.'], room=request.sid)
def logoutUser(id): user = User.query.filter_by(id=id).first() # check if the user exists if user != None: # broadcast to others that the user is leaving socketio.emit('send-msg', ['Server [All] ', f'{user.username} has left the room.', 0], broadcast=True, room=user.room) # leave a game the user was in it exitGame(id) # delete user from database User.query.filter_by(id=id).delete() db.session.commit()
def logout(): try: # broadcast to others that the user is leaving socketio.emit('send-msg', ['Server [All] ', f'{current_user.username} has left the room.', 0], broadcast=True, room=current_user.room) # leave a game the user was in it exitGame(current_user.id) # delete user from database User.query.filter_by(id=current_user.id).delete() db.session.commit() except: print('already removed') # redirect user to login page return redirect(url_for('login'))
def ready(): if current_user.song != '': room_key = f'{current_user.teamname}_{current_user.song}_{current_user.room}_{current_user.admin}' if current_user.admin == 1: room_key = room_key + '_' + current_user.username # create game room if it doesn't exist yet if room_key not in rooms: rooms[room_key] = Room(packets.getFrames(current_user.song)) # if user hasn't joined if current_user.id not in rooms[room_key].getUsers(): # try to add user to room added = rooms[room_key].addUser(current_user.id) # this is the case when the game has already started (can't join ongoing game) if not added: return socketio.emit('send-msg', ['Server', 'This game has already started. Try again later or pick another song.'], room=request.sid) if added: # add user to game join_room(room_key + '_ready') socketio.emit('send-msg', ['Server [Team]', f'{current_user.username} is ready', 0], broadcast=True, room=room_key) # if all users ready start the game if usersReady(current_user.id): return startGame(current_user.id) else: return socketio.emit('send-msg', ['Server', 'Waiting for players...', 0], room=request.sid) else: # print message if already waiting allready = usersReady(current_user.id) if not allready: return socketio.emit('send-msg', ['Server', 'Waiting for players...', 0], room=request.sid) # start the game if everyone is ready and the game hasn't started if allready and rooms[room_key].gameOver() == True: return startGame(current_user.id) else: return socketio.emit('send-msg', ['Server', 'You haven\'t selected a song', 0], room=request.sid)
def startGame(id): user = User.query.filter_by(id=id).first() room_key = f'{user.teamname}_{user.song}_{user.room}_{user.admin}' if user.admin == 1: # admin keys are slightly different than student keys room_key = room_key + '_' + user.username rooms[room_key].start() time = rooms[room_key].secondsLeft() # start message is slightly different for admins if user.admin == 0: socketio.emit('send-msg', ['Server [Team]', 'Your team is ready! The game will start in 5 seconds. You will have 10 seconds to submit frame 1.', 0], broadcast=True, room=room_key + '_ready') else: socketio.emit('send-msg', ['Server [Team]', 'Your game will start in 5 seconds. You will have 10 seconds to submit frame 1.', 0], broadcast=True, room=room_key + '_ready') # starts game loop (client-side) socketio.emit('game-loop', time, room=room_key + '_ready') # initializes game variables rooms[room_key].start()
def kick_user(username): # only admins can kick users so first we check if the user is admin if current_user.admin == 1: user = User.query.filter_by(username=username, room=current_user.room).first() # check if user exists if user != None: # logout the user socketio.emit('redirect', url_for('logout'), room=user.session) # if user was not redirected to logout successfully remove the user from database user = User.query.filter_by(username=username, room=current_user.room).first() if user != None: logoutUser(user.id) else: socketio.emit('send-msg', ['Server', 'User not found.'], room=request.sid) else: socketio.emit('send-msg', ['Server', 'Your account is not authorized to use /kick.'], room=request.sid)
def sendPrivateMessage(msg): # only admins can send private messages if current_user.admin != 1: return socketio.emit('send-msg', ['Server', 'Your account is not authorized to send /private messages.'], room=request.sid) # checks if msg is parsable if len(msg.split(' ')) > 1: reciever = msg[:msg.index(' ')].strip() sender = f'{current_user.username} [private] [{reciever}]' msg = msg[msg.index(' '):].strip() # get the reciever's data and see if the user exists to get their session id user = User.query.filter_by(username=reciever, room=current_user.room).first() if user != None and user.session != 'n/a': socketio.emit('send-msg', [sender, msg, 1], room=f'admins_{current_user.room}') return socketio.emit('send-msg', [sender, msg, 1], room=user.session) else: return socketio.emit('send-msg', ['Server', f'"{reciever}" was not found.'], room=request.sid) return socketio.emit('send-msg', ['Server', 'Your message is missing.'], room=request.sid)
def gameStats(): room_key = f'{current_user.teamname}_{current_user.song}_{current_user.room}_{current_user.admin}' if current_user.admin == 1: room_key = room_key + '_' + current_user.username if room_key in rooms: room = rooms[room_key] time = int(room.secondsLeft()) # game end cases if room.gameOver(): win = False # time updates for gamers if time == 0: socketio.emit('send-msg', ['Time', 0, 2], room=request.sid) socketio.emit('send-msg', ['Server [Team]', 'Your team ran out of time GAME OVER.', 0], room=request.sid) elif room.won(): win=True socketio.emit('close-loop', win=win, room=request.sid) room.removeUser(current_user.id) # delete room when empty if room.empty(): # broadcast win message to EVERYONE if room.won(): socketio.emit('send-msg', ['Server [All]', f'Team {current_user.teamname} successfully loaded "{current_user.song}"!'], broadcast=True, room=current_user.room) # delete room once it's empty del rooms[room_key] # continues game else: socketio.emit('game-loop', time, request.sid) else: socketio.emit('close-loop', request.sid)
def sendAllMsg(msg): room_key = current_user.room if current_user.admin == 1 else request.sid sender = f'{current_user.username} [all]' if current_user.admin == 1 else 'Server' msg = msg if current_user.admin == 1 else 'Your account is not authorized to send /all messages.' color_flag = 1 if current_user.admin == 1 else 0 socketio.emit('send-msg', [sender, msg, color_flag], room=room_key)
def sendAdminMsg(msg): if current_user.admin != 1: sender = f'{current_user.username} [to:admins] [{current_user.teamname}]' room_key = 'admins_' + current_user.room socketio.emit('send-msg', [sender, msg, 4], room=request.sid) socketio.emit('send-msg', [sender, msg, 4], room=room_key)
def requestSong(): msg = f'Your selected song is {current_user.song}.' if current_user.song != '' else 'Select a song' return socketio.emit('send-msg', ['Server', msg, 0], room=request.sid)
def getUsers(team): # gathers our users data into a list users = [] # gets users by teamname (admin only) if len(team) > 0 and current_user.admin == 1: matches = User.query.filter(User.teamname==team, User.room==current_user.room, User.admin==0, User.session != 'n/a').all() # gets ALL users in room (admin only) elif current_user.admin == 1: matches = User.query.filter(User.room==current_user.room, User.admin==0, User.session != 'n/a').all() # gets current user's team (student only) else: matches = User.query.filter(User.room==current_user.room, User.teamname==current_user.teamname, User.admin==0, User.session != 'n/a').all() # return formatted results to requester socketio.emit('send-msg', ['Server', ''], room=request.sid) socketio.emit('send-msg', ['', '-------------------------'], room=request.sid) socketio.emit('send-msg', ['','<username> : <teamname> : <song> : <status>'], room=request.sid) if matches != None and len(matches) > 0: for u in matches: room_key = f'{u.teamname}_{u.song}_{u.room}_{u.admin}' ready = 'ready' if (room_key in rooms and u.id in rooms[room_key].getUsers()) else 'idle' song = u.song if len(u.song) > 0 else 'none' socketio.emit('send-msg', ['', '------------------------------------'], room=request.sid) socketio.emit('send-msg', ['', f'{u.username} : {u.teamname} : {song} : {ready}'], room=request.sid) socketio.emit('send-msg', ['', '------------------------------------'], room=request.sid) else: socketio.emit('send-msg', ['','no users'], room=request.sid)