def do_add_to_game(game): """attempts to add user to game""" if not game: raise ValueError("Tried to do_add_to_game without game") # looking to add themselves to this game # check whether this is allowed. c = common_db.Common_DB() this_session = c.common_Sessionmaker() action_result, message = game.add_players_to_game( game.state.this_player_id) if action_result: # added to the game. Check if the game is ready if game.ready_to_start: # do the deal game.deal() action_result, message = game.save(this_session) else: action_result, message = game.save(this_session) if action_result: message = "Added you to the game. Now sit tight and wait for enough other players to join." if action_result: this_session.commit() else: this_session.rollback() this_session.close() return action_result, message
def do_load_game(game_id, this_player_id): """loads a game object""" c = common_db.Common_DB() logger.info(f"Starting to load game for ID '{game_id}'") game = Game() game.state.game_id = game_id game.state.this_player_id = this_player_id logger.debug("Created game") players = get_users_for_game(game_id, c.common_engine) logger.debug(f"players for game {game_id} identified: {players}") game.players = [] for player in players: p = Player(player) if p.ID == this_player_id: logger.debug("Found this player with ID %s", this_player_id) game.this_player = p game.players.append(p) if not game.load(c.common_engine): logger.error(f"Failed to load game {game_id}") logger.info(f"do_load_game complete for game {game_id}") return game
def get_player_for_username(username): c = common_db.Common_DB() result = c.execute( c.common_engine, "SELECT player_id, hash, is_admin FROM users WHERE username = :username", username=username) return result
def do_save_game(game): c = common_db.Common_DB() s = c.common_Sessionmaker() if game.save(s): s.commit() s.close() return True else: s.rollback() s.close() return False
def load_player_cards(self, session, game_id, deck_type): """queries the database for a set of cards for a given player and game and type ande returns as a set""" print("about to load cards for player ID " + str(self.ID) + " for game " + str(game_id) + " with type " + str(deck_type) + ".") c = common_db.Common_DB() cards = c.execute( session, "SELECT card_suit, card_rank FROM game_cards WHERE player_id = :player_id AND card_location = :card_type AND game_id = :game_id ORDER BY card_rank, card_suit ASC", player_id=self.ID, card_type=deck_type, game_id=game_id) cards_to_return = [] if len(cards) > 0: cards_to_return.extend( [Card(card["card_suit"], card["card_rank"]) for card in cards]) print("returning " + str(len(cards_to_return))) return cards_to_return
def save(self, session, game_id): """saves the current player's gamew state, including registering this player as playing this game""" c = common_db.Common_DB() result = c.execute( session, 'INSERT INTO player_game (player_id, game_id) VALUES (:user_id, :game_id) ON CONFLICT (player_id, game_id) DO UPDATE SET player_id = :user_id, game_id = :game_id;', user_id=self.ID, game_id=game_id) if not result: print( f"unable to add or update player in to player_game for player {self.ID} and game {game_id}" ) return False, f"unable to add or update player in to player_game for player {self.ID} and game {game_id}" result = c.execute( session, f"DELETE FROM game_cards WHERE game_id = {game_id} AND player_id = {self.ID};" ) if result == None: # some kind of exception print("unable to delete existing game cards") return False, f"unable to add or update player in to player_game for player {self.ID} and game {game_id}" cards_to_store = [] for pile_id in self.Card_Pile_ID: for card in getattr(self, self.Pile_Objects[pile_id]): cards_to_store.append( f"({game_id}, {self.ID}, {pile_id.value}, {card.suit}, {card.rank})" ) if cards_to_store: cards_to_store = ", ".join(cards_to_store) result = c.execute( session, f"INSERT INTO game_cards (game_id, player_id, card_location, card_suit, card_rank) VALUES {cards_to_store};" ) if not result: print("failed to save game cards, rolling back") return False, f"unable to save player cards for player {self.ID} and game {game_id}" return True, f"player {self.ID} saved successfully"
def register(): """Register user""" # User reached route via POST (as by submitting a form via POST) if request.method == "POST": # Ensure username was submitted if not request.form.get("username"): return apology("must provide username", 400) # Ensure password was submitted elif not request.form.get("password"): return apology("must provide password", 400) # Ensure passwords match elif not request.form.get("password") == request.form.get("confirmation"): return apology("passwords must match", 400) # Query database for username c = common_db.Common_DB() rows = c.execute(c.common_engine, "SELECT player_id, hash FROM users WHERE username = :username", username=request.form.get("username")) if len(rows) != 0: return apology("username already taken, sorry") this_session = c.common_Sessionmaker() result = c.execute(this_session, "INSERT INTO users (username, hash) VALUES (:username, :password_hash)", username=request.form.get("username").lower(), password_hash=generate_password_hash(request.form.get("password"))) if not result: this_session.rollback() this_session.close() return apology("could not register") this_session.commit() this_session.close() # Redirect user to home page return redirect(url_for('login')) # User reached route via GET (as by clicking a link or via redirect) else: return render_template("register.html")
def do_start_new_game(request_json, this_player_user_id): """starts a new game""" game = Game(this_player_user_id) logger.debug(f"do_start_new_game with {request_json}") parsed_values, message = game.parse_requested_config(request_json) if parsed_values: # initalise a session logger.debug( f"do_start_new_game parsed values, creating session to commit save." ) c = common_db.Common_DB() this_session = c.common_Sessionmaker() result, message = game.save(this_session) if not result: logger.error("do_start_new_game save failed, rolling back") this_session.rollback() response = {"startnewgame": False, "message": message} else: logger.info("do_start_new_game save ok, committing") this_session.commit() msg = quote_plus( f"Game created successfully with ID {game.state.game_id}" ". Now let's wait for some other players to join.") response = { "startnewgame": True, "new_game_id": game.state.game_id, "message": message, "redirect_querystring": f"?msg={msg}" } this_session.close() logger.debug( "do_start_new_game completed successfully - returning: %s", jsonpickle.encode(response, unpicklable=False)) return response, game else: logger.error("do_start_new_game unable to parse values: %s", message) response = {"startnewgame": False, "message": message} return response, None
from helpers import apology, login_required from player import Player app_logger = logging.getLogger(__name__) app_logger.info("startup") # Configure application app = Flask(__name__) sslify = SSLify(app, permanent=True) # idea from https://cloud.google.com/appengine/docs/flexible/python/using-cloud-sql # Environment variables are defined in app.yaml. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False c = common_db.Common_DB() app_logger.info("got db engine %s", c.common_engine) c.initialise_models() app_logger.debug("models initialised") sqalchemy_database_uri = c.sqalchemy_database_uri secret_key = c.secret_key if sqalchemy_database_uri and secret_key: app.config['SQLALCHEMY_DATABASE_URI'] = sqalchemy_database_uri app.config['SECRET_KEY'] = secret_key else: raise ValueError( "Cannot load database connection details - sqalchemy_database_uri, secret_key missing") app.config["SESSION_PERMANENT"] = True
def do_reload_game(game): c = common_db.Common_DB() s = c.common_Sessionmaker() game.load(s) s.close()
def do_playcards(request_json, game): """validates that a user is allowed to play a specific action and if so, executes that action and returns the result""" # first, let's get the action and respond with a failure if we can't. if not request_json: logger.error("do_playcards called without reqeust_json") raise ValueError("do_playcards called without request_json") action = request_json.get("action") if not action: logger.error("do_playcards no action in json") response = { 'action': 'unknown', 'action_result': False, 'action_message': "no action specified" } return response cards = request_json.get("action_cards") list_of_actions_which_require_cards = ["swap", "play"] if action in list_of_actions_which_require_cards and not cards: logger.error( f"do_playcards swap called wtih action '{action}' no cards specified to play" ) response = { 'action': action, 'action_result': False, 'action_message': "no cards specified" } return response # at least we've got a candidate action - let's reload the game state from teh database c = common_db.Common_DB() s = c.common_Sessionmaker() game.load(s) if action == "swap": # we have a action_cards object - submit to game response = game.swap_cards(cards, game.this_player) elif action == "no_swap": # player has opted to play without swapping logger.debug("do_playcards starting game without swap") response = game.play_no_swap() elif action == "play": # play these cards logger.debug("do_playcards starting play") response = game.play_move(cards) elif action == "pick": # player has to pick up the cards response = game.play_pick_up() else: # now set this as default action in case it fails to match any action below response = { 'action': action, 'action_result': False, 'action_message': "unknown action :" + action } logger.debug("do_playcards %s: %s", action, response) if not response["action_result"]: logger.error(response["action_message"]) s.rollback() s.close return response if game.save(s): s.commit() logger.debug("do_playcards saved game") else: s.rollback() logger.error("do_playcards unable to save, transaction rolled back") response = { 'action': action, 'action_result': False, 'action_message': "Unable to save game" } s.close() return response