def bombed(request): data = json.loads(request.body) # print request.user.first_name # print data # print game_id = data['id'] index = data['index'] cell = data['cell'] # yours = data['yours'] # yours =False # game_obj = Game.objects.filter( # Q(player1=request.user) | Q(player2=request.user) # ).get( # id=game_id # ) game_obj = Game.objects.get(id=game_id) if request.user == game_obj.player1: opponent = game_obj.player2 else: assert request.user == game_obj.player2 opponent = game_obj.player1 Bomb.objects.create( game=game_obj, user=request.user, index=index, new_cell_state=cell, ) channel = 'game-{}-{}'.format(game_obj.id, opponent.username) fanout.publish(channel, { 'index': index, 'yours': True, 'cell': cell, }) return http.JsonResponse({'ok': True})
def test_publish_with_custom_realm1(self): pc = PubControlTestClass() fanout._pubcontrols[('realm2', 'key==2', False)] = pc fanout.publish('channel', 'item', realm='realm2', key='key==2', ssl=False) self.assertEqual(pc.publish_channel, 'channel') self.assertEqual(pc.publish_item.export(), Item(fanout.JsonObjectFormat('item')).export()) self.assertEqual(pc.publish_blocking, False)
def test_publish(self): fanout.realm = 'realm' fanout.key = 'key==' fanout.ssl = True pc = PubControlTestClass() fanout._pubcontrols[('realm', 'key==', True)] = pc fanout.publish('channel', 'item') self.assertEqual(pc.publish_channel, 'channel') self.assertEqual(pc.publish_item.export(), Item(fanout.JsonObjectFormat('item')).export()) self.assertEqual(pc.publish_blocking, False)
def send_fanout(channel, data): if settings.FANOUT_REALM_ID and settings.FANOUT_REALM_KEY: fanout.realm = settings.FANOUT_REALM_ID fanout.key = settings.FANOUT_REALM_KEY assert not channel.startswith('/') # only in JavaScript # If you ever get TypeError around this, it's probably because # you're running a unittest where the fanout lib hasn't # been mocked. If so it'll most likely struggle to accept # the test-bogus value for settings.FANOUT_REALM_KEY fanout.publish(channel, data) else: import warnings warnings.warn('FANOUT_REALM_ID and FANOUT_REALM_KEY not set so Fanout ' 'subscription message not published.')
def test_publish_with_callback(self): self.has_callback_been_called = False fanout.realm = 'realm' fanout.key = 'key==' fanout.ssl = True pc = PubControlTestClass() fanout._pubcontrols[('realm', 'key==', True)] = pc fanout.publish('channel', 'item', 'id', 'prev-id', False, self.callback_for_testing) self.assertEqual(pc.publish_channel, 'channel') self.assertEqual(pc.publish_item.export(), Item(fanout.JsonObjectFormat('item'), 'id', 'prev-id').export()) self.assertEqual(pc.publish_blocking, False) pc.publish_callback(False, 'error') self.assertTrue(self.has_callback_been_called)
def send_fanout(channel, data): if settings.FANOUT_REALM_ID and settings.FANOUT_REALM_KEY: fanout.realm = settings.FANOUT_REALM_ID fanout.key = settings.FANOUT_REALM_KEY assert not channel.startswith('/') # only in JavaScript # If you ever get TypeError around this, it's probably because # you're running a unittest where the fanout lib hasn't # been mocked. If so it'll most likely struggle to accept # the test-bogus value for settings.FANOUT_REALM_KEY fanout.publish(channel, data) else: import warnings warnings.warn( 'FANOUT_REALM_ID and FANOUT_REALM_KEY not set so Fanout ' 'subscription message not published.' )
def fanout_publish(channel, id, prev_id, http_response): fanout.publish(settings.FANOUT_REALM, b64decode(settings.FANOUT_REALM_KEY), channel, id, prev_id, http_response)
def publish(channel, data, id=None, prev_id=None, blocking=False, callback=None, realm=None, key=None, ssl=True): fanout.publish(channel, data, id, prev_id, blocking, callback, realm, key, ssl)
def messages(request): you = request.user if request.method == 'POST': data = json.loads(request.body) if not data.get('id'): return VerboseHttpResponseBadRequest('No game id') game_id = data['id'] game_obj = get_object_or_404(Game, id=game_id) if not (game_obj.player1 == you or game_obj.player2 == you): return VerboseHttpResponseBadRequest('Not your game') message = data.get('message', '').strip() if not message: return VerboseHttpResponseBadRequest('Empty message') # To avoid allowing repeats, do nothing if the last message # in this game was from this user was the same message previous = Message.objects.filter(game=game_obj).order_by('-created') repeat = False for message_obj in previous[:1]: if ( message_obj.user == request.user and message_obj.message == message ): repeat = True if not repeat: message_obj = Message.objects.create( game=game_obj, user=request.user, message=message ) # we're going to want to inform the opponent if you == game_obj.player1: opponent = game_obj.player2 else: opponent = game_obj.player1 channel = 'game-{}-{}'.format(game_obj.id, opponent.username) msg = { 'id': message_obj.id, 'message': message_obj.message, 'name': you.first_name, 'game_id': game_obj.id, } fanout.publish(channel, { 'message': msg, }) # if that opponent is not watching the game right now, # update that too fanout.publish(opponent.username, { 'message': msg, }) else: if not request.GET.get('id'): return VerboseHttpResponseBadRequest('No game id') game_obj = get_object_or_404(Game, id=request.GET['id']) if not (game_obj.player1 == you or game_obj.player2 == you): return VerboseHttpResponseBadRequest('Not your game') items = [] messages_ = Message.objects.filter(game=game_obj).order_by('created') for msg in messages_: item = { 'id': msg.id, 'message': msg.message, } if msg.user == you: item['you'] = True else: if not msg.read: msg.read = True msg.save() item['name'] = msg.user.first_name items.append(item) return http.JsonResponse({ 'messages': items, })
def start(request): """When you start a game you have to pick the rules and design your ships (i.e. place them). If there is a game with the same rules, waiting for an opponent, then return that game and then notify the one who created it. If no match, do nothing here. The user will be asked to go ahead and design their ships so that it's ready to be joined by someone else. """ data = json.loads(request.body) if not data.get('game'): return VerboseHttpResponseBadRequest('no game') if not request.user.first_name: return VerboseHttpResponseBadRequest("you haven't set your name yet") invite = data.get('invite') game = data['game'] if game['you']['designmode']: return VerboseHttpResponseBadRequest("you haven't designed it yet") # If the game already has an opponent, and an id, use that, we should # be good to go. if game.get('id') and game['opponent']['name']: game_obj = Game.objects.get(id=game['id']) # print game_obj.player1.first_name # print game_obj.player2.first_name # from pprint import pprint assert not game['you']['designmode'] assert not game['opponent']['designmode'] # print game['you']['name'] # print game['opponent']['name'] # game = invert_state(game) game_obj.state = invert_state(game) game_obj.save() # pprint(game) return http.JsonResponse({'game': invert_state(game_obj.state)}) # find any started games that don't have a player2 games = Game.objects.filter( ai=False, gameover=False, abandoned=False, player2__isnull=True, ).exclude( player1=request.user, ) my_ongoing_games = Game.objects.filter( Q(player1=request.user) | Q(player2=request.user) ).filter( ai=False, gameover=False, abandoned=False, ) my_ongoing_opponents = [] for ongoing_game in my_ongoing_games: my_ongoing_opponents.append(ongoing_game.player1_id) if ongoing_game.player2_id: my_ongoing_opponents.append(ongoing_game.player2_id) if my_ongoing_opponents: games = games.exclude(player1_id__in=my_ongoing_opponents) if invite: games = games.filter(player1__id=invite['id']) for other in games: # all saved games should be designed assert not other.state['you']['designmode'], 'not designed' if other.state['rules'] == game['rules']: # we have a match! other.player2 = request.user other.state['opponent']['name'] = request.user.first_name other.state['opponent']['ships'] = game['you']['ships'] other.state['opponent']['designmode'] = game['you']['designmode'] if other.state['yourturn']: other.turn = other.player1 else: other.turn = request.user other.save() # should we send a notification to player1? channel = other.player1.username fanout.publish(other.player1.username, { 'game': other.state, }) return http.JsonResponse({'game': invert_state(other.state)}) # still here :( # have you created one before? games = Game.objects.filter( player1=request.user, player2__isnull=True, gameover=False, ai=False, abandoned=False, ) if invite: games = games.filter(player2__id=invite['id']) for game_obj in games: if game_obj.state['rules'] == game['rules']: print "Found one with the same rules" return http.JsonResponse({'id': game_obj.id}) # really still here, then you haven't created a game before game_obj = Game.objects.create( player1=request.user, state=game, ) if invite: game_obj.player2 = get_user_model().objects.get(id=invite['id']) game_obj.turn = game_obj.player2 game_obj.state['opponent']['name'] = game_obj.player2.first_name game_obj.state['id'] = game_obj.id game_obj.save() return http.JsonResponse({'id': game_obj.id})
def save(request): data = json.loads(request.body) try: game = data['game'] try: game_id = game['id'] except KeyError: return VerboseHttpResponseBadRequest('No game id') except KeyError: return VerboseHttpResponseBadRequest('No game') if game['you']['designmode']: return VerboseHttpResponseBadRequest('Your game is not designed') if game['opponent']['designmode']: return VerboseHttpResponseBadRequest('Opponent game is not designed') opponent = None if game_id < 0: # it's never been saved before opponent_id = game['opponent'].get('id') if opponent_id: opponent = get_user_model().objects.get(id=opponent_id) else: opponent = None game_obj = Game.objects.create( player1=request.user, player2=opponent, state=game, ai=game['opponent']['ai'], ) game_obj.state['id'] = game_obj.id game_obj.save() else: game_obj = Game.objects.get(id=game_id) if game_obj.abandoned: return VerboseHttpResponseBadRequest('Game is abandoned') if not game_obj.ai: if game_obj.turn != request.user: return VerboseHttpResponseBadRequest('Not your turn') if game_obj.player2 == request.user: opponent = game_obj.player1 # If you're player2, expect the 'yourturn' to be the opposite # If you're player2, we need to invert the state. # But had player1 finished designing? game = invert_state(game) if game['yourturn']: game_obj.turn = game_obj.player1 elif game_obj.player2: opponent = game_obj.player2 if not game['yourturn']: game_obj.turn = game_obj.player2 game_obj.state = game if game['gameover']: game_obj.gameover = True if game['you']['winner']: game_obj.winner = request.user elif game['opponent']['winner']: if opponent: if game_obj.player2 == request.user: # player2 said the opponent won, # considering that the state was reveresed, # it actually means player2 won. game_obj.winner = request.user else: game_obj.winner = opponent else: assert game['opponent']['ai'] game_obj.save() # Only send a websocket, to the opponent, if the opponent is not # AI. if opponent: if opponent == game_obj.player2: fanout.publish(opponent.username, { 'game': invert_state(game_obj.state), }) else: fanout.publish(opponent.username, { 'game': game_obj.state, }) return http.JsonResponse({'id': game_obj.id})