diff --git a/app/bloonsa_api/views.py b/app/bloonsa_api/views.py index be33800..084aebb 100644 --- a/app/bloonsa_api/views.py +++ b/app/bloonsa_api/views.py @@ -5,6 +5,7 @@ from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from bloonsa_game.models import Level +from users.models import Player, Bloonsa_LevelRating from users.util import tag_player @@ -15,40 +16,71 @@ class CSRFexemptTemplateView(TemplateView): class LoadLevel(CSRFexemptTemplateView): - def post(self, request, *args, **kwargs): - tag_player(request=request) - levelNum = request.POST.get("level_num") - if levelNum is None or not levelNum.isdigit(): + levelId = request.POST.get("levelId") + if levelId is None or not levelId.isdigit(): return HttpResponseBadRequest() - level = Level.objects.filter(id=int(levelNum)).first() + level = Level.objects.filter(levelId=int(levelId)).first() if level is None: return HttpResponseBadRequest() + if request.user.is_authenticated: + tag_player(request=request) + player = Player.objects.get(user=request.user) + player.bloonsa_levelsPlayed.add(level) + flashVars = level.getFlashVars(seperator="&") return HttpResponse(flashVars) class RandomLevel(CSRFexemptTemplateView): def post(self, request, *args, **kwargs): - tag_player(request=request) level = Level.objects.order_by("?").first() flashVars = level.getFlashVars(seperator="&") + + if request.user.is_authenticated: + tag_player(request=request) + player = Player.objects.get(user=request.user) + player.bloonsa_levelsPlayed.add(level) + return HttpResponse(flashVars) def get(self, request, *args, **kwargs): - tag_player(request=request) - level = Level.objects.order_by("?").first() - flashVars = level.getFlashVars(seperator="&") - return HttpResponse(flashVars) + return self.post(request=request, *args, **kwargs) class CompleteLevel(CSRFexemptTemplateView): def post(self, request, *args, **kwargs): - tag_player(request=request) - pass + if request.user.is_authenticated: + tag_player(request=request) + levelId = int(request.POST.get("levelId")) + level = Level.objects.get(levelId=levelId) + player = Player.objects.get(user=request.user) + player.bloonsa_levelsBeaten.add(level) + + # Sending empty content means error in as3 + return HttpResponse(content="GG", status=200) class RateLevel(CSRFexemptTemplateView): def post(self, request, *args, **kwargs): - tag_player(request=request) - pass + if request.user.is_authenticated: + tag_player(request=request) + rating = int(request.POST.get("rating")) + levelId = int(request.POST.get("levelId")) + level = Level.objects.get(levelId=levelId) + player = Player.objects.get(user=request.user) + ratingObject = Bloonsa_LevelRating.objects.filter(player=player, + level=level).first() + if ratingObject: + ratingObject.rating = rating + ratingObject.save() + return HttpResponse(content="OK", status=200) + + else: + rating = Bloonsa_LevelRating.objects.create(player=player, + level=level, + rating=rating) + rating.save() + return HttpResponse(content="OK", status=200) + + return HttpResponse(status=400) diff --git a/app/game/migrations/0001_initial.py b/app/bloonsa_game/migrations/0001_initial.py similarity index 58% rename from app/game/migrations/0001_initial.py rename to app/bloonsa_game/migrations/0001_initial.py index 2f97e62..5aecf4b 100644 --- a/app/game/migrations/0001_initial.py +++ b/app/bloonsa_game/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 3.2.7 on 2021-09-28 17:44 +# Generated by Django 5.1.6 on 2025-02-07 00:21 +import django.db.models.deletion from django.db import migrations, models @@ -12,19 +13,11 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Level', + name='Author', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('author', models.TextField()), - ('title', models.CharField(max_length=16)), - ('author_id', models.IntegerField()), - ('level_id', models.IntegerField()), - ('darts', models.IntegerField()), - ('target', models.IntegerField()), - ('plays', models.IntegerField()), - ('completions', models.IntegerField()), - ('rating', models.IntegerField(blank=True, null=True)), - ('data', models.CharField(max_length=288)), + ('name', models.CharField(max_length=255)), + ('authorId', models.IntegerField()), ], ), migrations.CreateModel( @@ -33,4 +26,19 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ], ), + migrations.CreateModel( + name='Level', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=16)), + ('levelId', models.IntegerField()), + ('darts', models.IntegerField()), + ('target', models.IntegerField()), + ('plays', models.IntegerField()), + ('completions', models.IntegerField()), + ('rating', models.FloatField(blank=True, null=True)), + ('data', models.CharField(max_length=288)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='bloonsa_game.author')), + ], + ), ] diff --git a/app/bloonsa_game/migrations/0002_bloonsa_levelratings_delete_player.py b/app/bloonsa_game/migrations/0002_bloonsa_levelratings_delete_player.py new file mode 100644 index 0000000..be222fd --- /dev/null +++ b/app/bloonsa_game/migrations/0002_bloonsa_levelratings_delete_player.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Bloonsa_LevelRatings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rating', models.SmallIntegerField()), + ('level', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.level')), + ], + ), + migrations.DeleteModel( + name='Player', + ), + ] diff --git a/app/bloonsa_game/migrations/0003_remove_bloonsa_levelratings_level.py b/app/bloonsa_game/migrations/0003_remove_bloonsa_levelratings_level.py new file mode 100644 index 0000000..44ea955 --- /dev/null +++ b/app/bloonsa_game/migrations/0003_remove_bloonsa_levelratings_level.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:43 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0002_bloonsa_levelratings_delete_player'), + ] + + operations = [ + migrations.RemoveField( + model_name='bloonsa_levelratings', + name='level', + ), + ] diff --git a/app/bloonsa_game/migrations/0004_delete_bloonsa_levelratings.py b/app/bloonsa_game/migrations/0004_delete_bloonsa_levelratings.py new file mode 100644 index 0000000..d86c9d2 --- /dev/null +++ b/app/bloonsa_game/migrations/0004_delete_bloonsa_levelratings.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:43 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0003_remove_bloonsa_levelratings_level'), + ('users', '0007_remove_player_bloonsa_levelratings_and_more'), + ] + + operations = [ + migrations.DeleteModel( + name='Bloonsa_LevelRatings', + ), + ] diff --git a/app/bloonsa_game/migrations/0005_remove_level_completions_alter_level_author.py b/app/bloonsa_game/migrations/0005_remove_level_completions_alter_level_author.py new file mode 100644 index 0000000..be98925 --- /dev/null +++ b/app/bloonsa_game/migrations/0005_remove_level_completions_alter_level_author.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:21 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0004_delete_bloonsa_levelratings'), + ] + + operations = [ + migrations.RemoveField( + model_name='level', + name='completions', + ), + migrations.AlterField( + model_name='level', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.author'), + ), + ] diff --git a/app/bloonsa_game/migrations/0006_alter_level_author_alter_level_darts_and_more.py b/app/bloonsa_game/migrations/0006_alter_level_author_alter_level_darts_and_more.py new file mode 100644 index 0000000..e5d5a6b --- /dev/null +++ b/app/bloonsa_game/migrations/0006_alter_level_author_alter_level_darts_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:23 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0005_remove_level_completions_alter_level_author'), + ] + + operations = [ + migrations.AlterField( + model_name='level', + name='author', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.author'), + ), + migrations.AlterField( + model_name='level', + name='darts', + field=models.SmallIntegerField(), + ), + migrations.AlterField( + model_name='level', + name='target', + field=models.SmallIntegerField(), + ), + ] diff --git a/app/bloonsa_game/migrations/0007_level_beats_alter_level_author_alter_level_plays.py b/app/bloonsa_game/migrations/0007_level_beats_alter_level_author_alter_level_plays.py new file mode 100644 index 0000000..f3b44cc --- /dev/null +++ b/app/bloonsa_game/migrations/0007_level_beats_alter_level_author_alter_level_plays.py @@ -0,0 +1,29 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:32 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0006_alter_level_author_alter_level_darts_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='level', + name='beats', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='level', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.author'), + ), + migrations.AlterField( + model_name='level', + name='plays', + field=models.IntegerField(null=True), + ), + ] diff --git a/app/bloonsa_game/migrations/0008_alter_level_beats_alter_level_plays.py b/app/bloonsa_game/migrations/0008_alter_level_beats_alter_level_plays.py new file mode 100644 index 0000000..9c12a8f --- /dev/null +++ b/app/bloonsa_game/migrations/0008_alter_level_beats_alter_level_plays.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0007_level_beats_alter_level_author_alter_level_plays'), + ] + + operations = [ + migrations.AlterField( + model_name='level', + name='beats', + field=models.IntegerField(), + ), + migrations.AlterField( + model_name='level', + name='plays', + field=models.IntegerField(), + ), + ] diff --git a/app/bloonsa_game/migrations/0009_alter_author_authorid.py b/app/bloonsa_game/migrations/0009_alter_author_authorid.py new file mode 100644 index 0000000..5d74ef7 --- /dev/null +++ b/app/bloonsa_game/migrations/0009_alter_author_authorid.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0008_alter_level_beats_alter_level_plays'), + ] + + operations = [ + migrations.AlterField( + model_name='author', + name='authorId', + field=models.IntegerField(null=True), + ), + ] diff --git a/app/bloonsa_game/migrations/0010_alter_author_authorid.py b/app/bloonsa_game/migrations/0010_alter_author_authorid.py new file mode 100644 index 0000000..6ce9b71 --- /dev/null +++ b/app/bloonsa_game/migrations/0010_alter_author_authorid.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0009_alter_author_authorid'), + ] + + operations = [ + migrations.AlterField( + model_name='author', + name='authorId', + field=models.IntegerField(default=None), + preserve_default=False, + ), + ] diff --git a/app/bloonsa_game/models.py b/app/bloonsa_game/models.py index 2ea6ea3..b78931d 100644 --- a/app/bloonsa_game/models.py +++ b/app/bloonsa_game/models.py @@ -1,22 +1,20 @@ from django.db import models -# Create your models here. - class Author(models.Model): name = models.CharField(max_length=255) authorId = models.IntegerField() def __str__(self): - return self.name + return f"{self.authorId} - {self.name}" class Level(models.Model): - author = models.ForeignKey(Author, on_delete=models.DO_NOTHING) + author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=16) levelId = models.IntegerField() - darts = models.IntegerField() - target = models.IntegerField() + darts = models.SmallIntegerField() + target = models.SmallIntegerField() plays = models.IntegerField() - completions = models.IntegerField() + beats = models.IntegerField() rating = models.FloatField(null=True, blank=True) data = models.CharField(max_length=288) @@ -32,13 +30,8 @@ class Level(models.Model): "target": self.target, "data": self.data, "authorID": self.author.authorId, - "numCompleted": self.completions, "rating": self.rating if self.rating else 0.0, } flashVarsStr = f"{seperator}".join([f"{k}={v}" for k, v in flashVars.items()]) return flashVarsStr - - -class Player(models.Model): - pass \ No newline at end of file diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf index 22c95ad..6b78839 100644 Binary files a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_backup.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_backup.swf deleted file mode 100644 index eed5bb0..0000000 Binary files a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_backup.swf and /dev/null differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit1.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit1.swf index 98b71ef..0dcfb50 100644 Binary files a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit1.swf and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit1.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit2.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit2.swf index 22c95ad..0dcfb50 100644 Binary files a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit2.swf and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit2.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit3.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit3.swf new file mode 100644 index 0000000..5ab3751 Binary files /dev/null and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit3.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit4.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit4.swf new file mode 100644 index 0000000..6b78839 Binary files /dev/null and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit4.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_original.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_original.swf new file mode 100644 index 0000000..da480a3 Binary files /dev/null and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_original.swf differ diff --git a/app/bloonsa_game/static/bloonsa_game/misc/crossdomain.xml b/app/bloonsa_game/static/bloonsa_game/misc/crossdomain.xml new file mode 100644 index 0000000..81ee67c --- /dev/null +++ b/app/bloonsa_game/static/bloonsa_game/misc/crossdomain.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/bloonsa_game/views.py b/app/bloonsa_game/views.py index b409823..06e73dd 100644 --- a/app/bloonsa_game/views.py +++ b/app/bloonsa_game/views.py @@ -1,5 +1,8 @@ +import os + from django.shortcuts import render from django.views.generic import TemplateView +from django.views.static import serve from bloonsa_game.models import Level from users.util import tag_player diff --git a/app/game/migrations/0002_auto_20210928_2006.py b/app/game/migrations/0002_auto_20210928_2006.py deleted file mode 100644 index 5e5b34d..0000000 --- a/app/game/migrations/0002_auto_20210928_2006.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 3.2.7 on 2021-09-28 18:06 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('game', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Author', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('authorId', models.IntegerField()), - ], - ), - migrations.RenameField( - model_name='level', - old_name='level_id', - new_name='levelId', - ), - migrations.RemoveField( - model_name='level', - name='author_id', - ), - migrations.AlterField( - model_name='level', - name='author', - field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='game.author'), - ), - ] diff --git a/app/game/migrations/0003_auto_20210928_2039.py b/app/game/migrations/0003_auto_20210928_2039.py deleted file mode 100644 index d73ebd1..0000000 --- a/app/game/migrations/0003_auto_20210928_2039.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.7 on 2021-09-28 18:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('game', '0002_auto_20210928_2006'), - ] - - operations = [ - migrations.RemoveField( - model_name='level', - name='rating', - ), - migrations.AddField( - model_name='level', - name='rating9', - field=models.IntegerField(blank=True, null=True), - ), - ] diff --git a/app/game/migrations/0004_rename_rating9_level_rating.py b/app/game/migrations/0004_rename_rating9_level_rating.py deleted file mode 100644 index f0e63ab..0000000 --- a/app/game/migrations/0004_rename_rating9_level_rating.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.7 on 2021-09-28 18:39 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('game', '0003_auto_20210928_2039'), - ] - - operations = [ - migrations.RenameField( - model_name='level', - old_name='rating9', - new_name='rating', - ), - ] diff --git a/app/game/migrations/0005_alter_level_rating.py b/app/game/migrations/0005_alter_level_rating.py deleted file mode 100644 index d636fac..0000000 --- a/app/game/migrations/0005_alter_level_rating.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.7 on 2021-09-28 18:43 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('game', '0004_rename_rating9_level_rating'), - ] - - operations = [ - migrations.AlterField( - model_name='level', - name='rating', - field=models.FloatField(blank=True, null=True), - ), - ] diff --git a/app/requirements.txt b/app/requirements.txt index 0fed029..4c3dd87 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -1,3 +1,5 @@ django==5.1.* django-crispy-forms -crispy-bulma \ No newline at end of file +crispy-bulma +django-extensions +django-cors-headers \ No newline at end of file diff --git a/app/scripts/__init__.py b/app/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/scripts/database_migration.py b/app/scripts/database_migration.py new file mode 100644 index 0000000..0b5d2f2 --- /dev/null +++ b/app/scripts/database_migration.py @@ -0,0 +1,36 @@ +import sqlite3 +import django +django.setup() +from tqdm import tqdm + +from bloonsa_game.models import Level, Author + + +def run(): + print("yes") + + with sqlite3.connect("bloonsworld_levels.db") as db: + cursor = db.cursor() + cursor.execute("SELECT * FROM Levels") + + for (levelNum, title, authorname, authorID, numPlays, numCompleted, rating, target, darts, data) in tqdm(cursor.fetchall()): + authorObj = Author.objects.filter(authorId=authorID).first() + if not authorObj: + authorObj = Author.objects.create(authorId=authorID, + name=authorname) + authorObj.save() + + levelObj = Level.objects.filter(levelId=levelNum).first() + if not levelObj: + levelObj = Level.objects.create(author=authorObj, + levelId=levelNum, + title=title, + plays=numPlays, + beats=numCompleted, + rating=rating, + target=target, + darts=darts, + data=data) + + levelObj.save() + diff --git a/app/settings/settings.py b/app/settings/settings.py index 9385d03..eeb809e 100644 --- a/app/settings/settings.py +++ b/app/settings/settings.py @@ -25,8 +25,7 @@ SECRET_KEY = 'django-insecure-)e!wy4)=xinnd!d(iuw6*-tf^-)ptiwnttwf+9ql%*jy63wtd8 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] - +ALLOWED_HOSTS = ["*"] # Application definition @@ -41,6 +40,7 @@ INSTALLED_APPS = [ # Plugins "crispy_forms", "crispy_bulma", + "django_extensions", # Global "users", @@ -139,3 +139,5 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' CRISPY_ALLOWED_TEMPLATE_PACKS = ("bulma",) CRISPY_TEMPLATE_PACK = 'bulma' + + diff --git a/app/settings/urls.py b/app/settings/urls.py index 1f8c801..a040c54 100644 --- a/app/settings/urls.py +++ b/app/settings/urls.py @@ -14,11 +14,17 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path, include +from django.urls import path, include, re_path +from django.views.generic.base import RedirectView + +crossdomain_view = RedirectView.as_view(url='/static/bloonsa_game/misc/crossdomain.xml', permanent=True) + + urlpatterns = [ path('admin/', admin.site.urls), - path("web_service/", include("bloonsa_api.urls", namespace="bloonsa_api")), + path("bloonsa_api/", include("bloonsa_api.urls", namespace="bloonsa_api")), path("a/", include("bloonsa_game.urls", namespace="bloonsa_game")), - path("users/", include("users.urls", namespace="users")) + path("users/", include("users.urls", namespace="users")), + re_path(r'^crossdomain\.xml$', crossdomain_view) ] diff --git a/app/users/admin.py b/app/users/admin.py index f8e31c5..0be5c49 100644 --- a/app/users/admin.py +++ b/app/users/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin -from .models import Player, User +from .models import Player, Bloonsa_LevelRating admin.site.register(Player) +admin.site.register(Bloonsa_LevelRating) diff --git a/app/users/migrations/0001_initial.py b/app/users/migrations/0001_initial.py new file mode 100644 index 0000000..e0f93dc --- /dev/null +++ b/app/users/migrations/0001_initial.py @@ -0,0 +1,52 @@ +# Generated by Django 5.1.6 on 2025-02-07 01:25 + +import django.contrib.auth.models +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ('bloonsa_game', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('user_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + bases=('auth.user',), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='Player', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('creationIP', models.GenericIPAddressField()), + ('latestIP', models.GenericIPAddressField()), + ('creationDate', models.DateTimeField(default=django.utils.timezone.now)), + ('latestActivity', models.DateTimeField(default=django.utils.timezone.now)), + ('suspectedCheater', models.BooleanField(default=False)), + ('suspended', models.BooleanField(default=False)), + ('banned', models.BooleanField(default=False)), + ('admin', models.BooleanField(default=False)), + ('levelsBeaten', models.ManyToManyField(blank=True, related_name='levelsBeaten', to='bloonsa_game.level')), + ('levelsPlayed', models.ManyToManyField(blank=True, related_name='levelsPlayed', to='bloonsa_game.level')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.customuser')), + ], + ), + ] diff --git a/app/users/migrations/0002_alter_player_user_delete_customuser.py b/app/users/migrations/0002_alter_player_user_delete_customuser.py new file mode 100644 index 0000000..005bad4 --- /dev/null +++ b/app/users/migrations/0002_alter_player_user_delete_customuser.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.6 on 2025-02-07 02:15 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterField( + model_name='player', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.DeleteModel( + name='CustomUser', + ), + ] diff --git a/app/users/migrations/0003_customuser_alter_player_user.py b/app/users/migrations/0003_customuser_alter_player_user.py new file mode 100644 index 0000000..8e1c060 --- /dev/null +++ b/app/users/migrations/0003_customuser_alter_player_user.py @@ -0,0 +1,37 @@ +# Generated by Django 5.1.6 on 2025-02-07 05:12 + +import django.contrib.auth.models +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ('users', '0002_alter_player_user_delete_customuser'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('user_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + bases=('auth.user',), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.AlterField( + model_name='player', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.customuser'), + ), + ] diff --git a/app/users/migrations/0004_rename_customuser_bloonsuser.py b/app/users/migrations/0004_rename_customuser_bloonsuser.py new file mode 100644 index 0000000..a3c82e4 --- /dev/null +++ b/app/users/migrations/0004_rename_customuser_bloonsuser.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-07 05:17 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_customuser_alter_player_user'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RenameModel( + old_name='CustomUser', + new_name='BloonsUser', + ), + ] diff --git a/app/users/migrations/0005_alter_player_user_delete_bloonsuser.py b/app/users/migrations/0005_alter_player_user_delete_bloonsuser.py new file mode 100644 index 0000000..e5ac8c2 --- /dev/null +++ b/app/users/migrations/0005_alter_player_user_delete_bloonsuser.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.6 on 2025-02-07 05:50 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0004_rename_customuser_bloonsuser'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterField( + model_name='player', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.DeleteModel( + name='BloonsUser', + ), + ] diff --git a/app/users/migrations/0006_rename_levelsbeaten_player_bloonsa_levelsbeaten_and_more.py b/app/users/migrations/0006_rename_levelsbeaten_player_bloonsa_levelsbeaten_and_more.py new file mode 100644 index 0000000..317facb --- /dev/null +++ b/app/users/migrations/0006_rename_levelsbeaten_player_bloonsa_levelsbeaten_and_more.py @@ -0,0 +1,30 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0002_bloonsa_levelratings_delete_player'), + ('users', '0005_alter_player_user_delete_bloonsuser'), + ] + + operations = [ + migrations.RenameField( + model_name='player', + old_name='levelsBeaten', + new_name='bloonsa_levelsBeaten', + ), + migrations.RenameField( + model_name='player', + old_name='levelsPlayed', + new_name='bloonsa_levelsPlayed', + ), + migrations.AddField( + model_name='player', + name='bloonsa_levelRatings', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bloonsa_levelRatings', to='bloonsa_game.bloonsa_levelratings'), + ), + ] diff --git a/app/users/migrations/0007_remove_player_bloonsa_levelratings_and_more.py b/app/users/migrations/0007_remove_player_bloonsa_levelratings_and_more.py new file mode 100644 index 0000000..9b9e1ec --- /dev/null +++ b/app/users/migrations/0007_remove_player_bloonsa_levelratings_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:43 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0003_remove_bloonsa_levelratings_level'), + ('users', '0006_rename_levelsbeaten_player_bloonsa_levelsbeaten_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='player', + name='bloonsa_levelRatings', + ), + migrations.CreateModel( + name='Bloonsa_LevelRatings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rating', models.SmallIntegerField()), + ('level', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.level')), + ('player', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='users.player')), + ], + ), + ] diff --git a/app/users/migrations/0008_rename_bloonsa_levelratings_bloonsa_levelrating.py b/app/users/migrations/0008_rename_bloonsa_levelratings_bloonsa_levelrating.py new file mode 100644 index 0000000..08deb11 --- /dev/null +++ b/app/users/migrations/0008_rename_bloonsa_levelratings_bloonsa_levelrating.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.6 on 2025-02-07 08:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0004_delete_bloonsa_levelratings'), + ('users', '0007_remove_player_bloonsa_levelratings_and_more'), + ] + + operations = [ + migrations.RenameModel( + old_name='Bloonsa_LevelRatings', + new_name='Bloonsa_LevelRating', + ), + ] diff --git a/app/users/migrations/0009_alter_bloonsa_levelrating_player.py b/app/users/migrations/0009_alter_bloonsa_levelrating_player.py new file mode 100644 index 0000000..6b63485 --- /dev/null +++ b/app/users/migrations/0009_alter_bloonsa_levelrating_player.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-07 10:57 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0008_rename_bloonsa_levelratings_bloonsa_levelrating'), + ] + + operations = [ + migrations.AlterField( + model_name='bloonsa_levelrating', + name='player', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.player'), + ), + ] diff --git a/app/users/migrations/0010_alter_bloonsa_levelrating_level.py b/app/users/migrations/0010_alter_bloonsa_levelrating_level.py new file mode 100644 index 0000000..2ed921b --- /dev/null +++ b/app/users/migrations/0010_alter_bloonsa_levelrating_level.py @@ -0,0 +1,20 @@ +# Generated by Django 5.1.6 on 2025-02-07 11:14 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0010_alter_author_authorid'), + ('users', '0009_alter_bloonsa_levelrating_player'), + ] + + operations = [ + migrations.AlterField( + model_name='bloonsa_levelrating', + name='level', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bloonsa_game.level'), + ), + ] diff --git a/app/users/models.py b/app/users/models.py index b55c7ea..b3a4595 100644 --- a/app/users/models.py +++ b/app/users/models.py @@ -5,14 +5,11 @@ from django.contrib.auth.models import User from bloonsa_game.models import Level - - class Player(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # Savedata - levelsPlayed = models.ManyToManyField(Level, blank=True, related_name="levelsPlayed") - levelsBeaten = models.ManyToManyField(Level, blank=True, related_name="levelsBeaten") - # levelsRated = ... + bloonsa_levelsPlayed = models.ManyToManyField(Level, blank=True, related_name="levelsPlayed") + bloonsa_levelsBeaten = models.ManyToManyField(Level, blank=True, related_name="levelsBeaten") # Logging creationIP = models.GenericIPAddressField() latestIP = models.GenericIPAddressField() @@ -25,4 +22,12 @@ class Player(models.Model): admin = models.BooleanField(default=False) def __str__(self): - return f"{self.user} - {self.latestIP}" \ No newline at end of file + return f"{self.user} - {self.latestIP}" + +class Bloonsa_LevelRating(models.Model): + level = models.ForeignKey(Level, on_delete=models.CASCADE) + player = models.ForeignKey(Player, on_delete=models.CASCADE) + rating = models.SmallIntegerField() + + def __str__(self): + return f"{self.player.user} <{self.rating}> {self.level}" \ No newline at end of file diff --git a/app/users/util.py b/app/users/util.py index e3445f9..0e0d8f3 100644 --- a/app/users/util.py +++ b/app/users/util.py @@ -16,7 +16,7 @@ def get_ip(request): def init_player(request, user): if not user.is_authenticated: return - player = Player.objects.get(user=request.user) + player = Player.objects.filter(user=user).first() if player: return ip = get_ip(request=request) @@ -32,7 +32,7 @@ def tag_player(request, user=None): user = user or request.user if not user.is_authenticated: return - player = Player.objects.get(user=request.user) + player = Player.objects.filter(user=request.user).first() if not player: init_player(request=request, user=user) player.latestActivity = timezone.now()