finished all game logic and add points

This commit is contained in:
TUTOR03 2020-11-29 04:34:34 +05:00
parent 8a778be4d2
commit b068359e58
11 changed files with 200 additions and 10 deletions

View File

@ -145,6 +145,7 @@ STATIC_ROOT = BASE_DIR / 'static'
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
MAX_CHECK_RADIUS = 1
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'

View File

@ -7,4 +7,5 @@ admin.site.register(models.Game)
admin.site.register(models.InvitationToken)
admin.site.register(models.Gamer)
admin.site.register(models.Team)
admin.site.register(models.CurrentCheckPoint)
# Register your models here.

View File

@ -0,0 +1,27 @@
# Generated by Django 3.1.3 on 2020-11-29 02:26
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('back', '0006_invitationtoken'),
]
operations = [
migrations.AlterField(
model_name='team',
name='game',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teams', to='back.game'),
),
migrations.CreateModel(
name='CurrentCheckPoint',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('check_point', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='back.checkpoint')),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='back.team')),
],
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.1.3 on 2020-11-29 02:30
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('back', '0007_auto_20201129_0226'),
]
operations = [
migrations.AlterField(
model_name='checkpoint',
name='next_checkpoint_id',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='back.checkpoint'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2020-11-29 02:31
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('back', '0008_auto_20201129_0230'),
]
operations = [
migrations.RenameField(
model_name='checkpoint',
old_name='next_checkpoint_id',
new_name='next_checkpoint',
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.1.3 on 2020-11-29 02:39
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('back', '0009_auto_20201129_0231'),
]
operations = [
migrations.AddField(
model_name='checkpoint',
name='game',
field=models.ForeignKey(default=2, on_delete=django.db.models.deletion.CASCADE, to='back.game'),
preserve_default=False,
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.1.3 on 2020-11-29 04:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('back', '0010_checkpoint_game'),
]
operations = [
migrations.AddField(
model_name='game',
name='points',
field=models.DecimalField(decimal_places=0, default=50, max_digits=3),
preserve_default=False,
),
]

View File

@ -23,6 +23,7 @@ class Game(models.Model):
co_op = models.BooleanField(blank = False, null = False)
max_gamers = models.DecimalField(max_digits = 3, decimal_places = 0, blank = False, null = False)
active = models.BooleanField(default = True)
points = models.DecimalField(max_digits = 3, decimal_places = 0, blank = False, null = False)
slug = models.SlugField(unique = True, blank = True, null = False)
class CheckPoint(models.Model):
@ -31,11 +32,12 @@ class CheckPoint(models.Model):
coordinates_lat = models.DecimalField(max_digits = 8, decimal_places = 6, blank = True, null = True)
coordinates_lon = models.DecimalField(max_digits = 8, decimal_places = 6, blank = True, null = True)
description = models.TextField(blank = False, null = False)
next_checkpoint_id = models.DecimalField(max_digits = 4, decimal_places = 0, blank = True, null = True)
next_checkpoint = models.ForeignKey('self', on_delete = models.CASCADE, blank = True, null = True)
qr_data = models.TextField(blank = True, null = True)
last = models.BooleanField(default = False)
start = models.BooleanField(default = False)
address = models.CharField(max_length = 200, blank = True, null = True)
game = models.ForeignKey(Game, on_delete = models.CASCADE, blank = False, null = False)
class Team(models.Model):
game = models.ForeignKey(Game, on_delete= models.CASCADE,related_name = 'teams', blank = False, null = False)
@ -53,9 +55,9 @@ class Gamer(models.Model):
profile = models.ForeignKey(Profile, on_delete = models.CASCADE, blank = False, null = False)
team = models.ForeignKey(Team, on_delete = models.CASCADE, related_name = 'gamers', blank = False, null = False)
# class CurrentCheckPoint(models.Model):
# team = models.ForeignKey(Team, on_delete = models.CASCADE, blank = False, null = False)
# check_point = models.ForeignKey()
class CurrentCheckPoint(models.Model):
team = models.ForeignKey(Team, on_delete = models.CASCADE, blank = False, null = False)
check_point = models.ForeignKey(CheckPoint, on_delete = models.CASCADE, blank = False, null = False)
@receiver(post_save, sender = User)
def create_profile(sender, instance, created, **kwargs):

View File

@ -1,6 +1,6 @@
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Game, Team, Gamer
from .models import Game, Team, Gamer, CheckPoint
class GameListSerializer(serializers.ModelSerializer):
class Meta:
@ -17,6 +17,30 @@ class UserRegisterSerializer(serializers.ModelSerializer):
'email'
]
class CheckPointCoordinatesSerializer(serializers.ModelSerializer):
class Meta:
model = CheckPoint
fields = [
'coordinates_lon',
'coordinates_lat',
'start',
'last'
]
class CurrentCheckPointSerializer(serializers.ModelSerializer):
class Meta:
model = CheckPoint
fields = [
'check_type',
'name',
'description',
'address',
]
# def get_done_check_points(self, obj):
# return(CheckPointCoordinatesSerializer(obj).data)
class TeamSerializer(serializers.ModelSerializer):
game = serializers.SerializerMethodField()
gamers = serializers.SerializerMethodField()

View File

@ -7,6 +7,7 @@ urlpatterns = [
path('game/<slug>', views.SingleGameAPIView, name = 'SingleGame'),
path('game/<slug>/take_part',views.GameTakePartAPIView, name = 'GameTakePartAPIView'),
path('game/<slug>/start', views.StartGameAPIView, name = 'StartGame'),
path('game/<slug>/close_check_point', views.CloseCheckPointAPIView, name = 'CloseCheckPoint'),
path('game/<slug>/join_team/<token>',views.JoinTeamAPIView, name = 'JoinTeam'),
path('register', views.UserRegisterAPIView, name = 'UserRegister'),
path('login', obtain_auth_token, name = 'UserLogin'),

View File

@ -10,16 +10,18 @@ from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core.mail import EmailMultiAlternatives
from .serializers import UserRegisterSerializer, UserResetPasswordSerializer, UserPasswordSerializer, GameListSerializer, TeamSerializer
from .serializers import UserRegisterSerializer, UserResetPasswordSerializer, UserPasswordSerializer, GameListSerializer, TeamSerializer, CurrentCheckPointSerializer, CheckPointCoordinatesSerializer
from django.utils.html import strip_tags
from django.contrib.auth.password_validation import validate_password
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter, SearchFilter
from .models import Game, Team, Gamer, Profile, InvitationToken
from .models import Game, Team, Gamer, Profile, InvitationToken, CurrentCheckPoint, CheckPoint
from django.conf import settings
from django.utils import timezone
from hashlib import sha1
import six
import threading
import math
class EmailTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
@ -81,15 +83,69 @@ def SingleGameAPIView(request, slug):
if(invite.exists()):
invite = invite.first()
invite_token = invite.token
if(team.finished):
done_chepoints = []
cur_checkpoint = CurrentCheckPoint.objects.get(team = team).check_point
temp_check_point = CheckPoint.objects.get(game = team.game, start = True)
done_chepoints.append(CheckPointCoordinatesSerializer(temp_check_point).data)
while temp_check_point.id!=cur_checkpoint.id:
temp_check_point = temp_check_point.next_checkpoint
done_chepoints.append(CheckPointCoordinatesSerializer(temp_check_point).data)
return Response({'ok':True, 'can_take_part':False, 'can_start':can_start, 'invite_token':invite_token, **data, 'done_chepoints':done_chepoints}, status = status.HTTP_200_OK)
return Response({'ok':True, 'can_take_part':False, 'can_start':can_start, 'invite_token':invite_token, **data}, status = status.HTTP_200_OK)
else:
pass
return Response({'ok':True, 'can_take_part':False, 'can_start':can_start, 'invite_token':invite_token, **data}, status = status.HTTP_200_OK)
done_chepoints = []
cur_checkpoint = CurrentCheckPoint.objects.get(team = team).check_point
cur_checkpoint_serializer = CurrentCheckPointSerializer(cur_checkpoint)
temp_check_point = CheckPoint.objects.get(game = team.game, start = True)
done_chepoints.append(CheckPointCoordinatesSerializer(temp_check_point).data)
while temp_check_point.id!=cur_checkpoint.id:
temp_check_point = temp_check_point.next_checkpoint
done_chepoints.append(CheckPointCoordinatesSerializer(temp_check_point).data)
return Response({'ok':True, 'can_take_part':False, 'can_start':can_start, 'invite_token':invite_token, **data, 'current_checkpoint':cur_checkpoint_serializer.data, 'done_chepoints':done_chepoints}, status = status.HTTP_200_OK)
else:
serializer = GameListSerializer(game)
data = serializer.data
return Response({'ok':True, 'can_take_part':True, **serializer.data}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'Game does not exist'}, status = status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def CloseCheckPointAPIView(request, slug):
game = Game.objects.filter(slug = slug)
if(game.exists()):
profile = Profile.objects.get(user = request.user)
game = game.first()
teams = Team.objects.filter(game = game)
team = []
for team_i in teams:
if(Gamer.objects.filter(profile = profile, team = team_i).exists()):
team = team_i
break
if(team):
temp_check_point = CheckPointCoordinatesSerializer(data = request.data)
if(temp_check_point.is_valid() and team.active and not team.finished):
temp_check_point = temp_check_point.validated_data
cur_checkpoint = CurrentCheckPoint.objects.get(team = team)
dest = math.sqrt((temp_check_point['coordinates_lat']-cur_checkpoint.check_point.next_checkpoint.coordinates_lat)**2 + (temp_check_point['coordinates_lon']-cur_checkpoint.check_point.next_checkpoint.coordinates_lon)**2)
if(dest<settings.MAX_CHECK_RADIUS):
cur_checkpoint.check_point = cur_checkpoint.check_point.next_checkpoint
cur_checkpoint.save()
if(cur_checkpoint.check_point.last):
team.active = False
team.finished = True
team.end = timezone.now()
team.save()
for gamer in team.gamers.all():
temp_prof = gamer.profile
temp_prof.points += game.points
temp_prof.save()
return Response({'ok':True}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'You are too far from the place'}, status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':temp_check_point.errors if temp_check_point.errors else 'Game finished' }, status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':'You do not take part in game'}, status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':'Game does not exist'}, status = status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def GameTakePartAPIView(request, slug):
@ -147,9 +203,11 @@ def StartGameAPIView(request,slug):
break
if(team):
if(team.captain == profile and not team.finished and not team.active):
team.is_active = True
team.active = True
team.start = timezone.now()
team.save()
first_check_point = CheckPoint.objects.get(game = team.game, start = True)
cur_checkpoint = CurrentCheckPoint.objects.create(team = team, check_point = first_check_point)
return Response({'ok':True}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'You are not a captain or game finished or game in progress'}, status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':'You do not take part in game'}, status = status.HTTP_400_BAD_REQUEST)