diff --git a/app/bloonsa_game/models.py b/app/bloonsa_game/models.py index 20ccc67..a379e02 100644 --- a/app/bloonsa_game/models.py +++ b/app/bloonsa_game/models.py @@ -42,4 +42,4 @@ class LevelRating(models.Model): rating = models.SmallIntegerField() def __str__(self): - return f"<{self.rating}> {self.level}" \ No newline at end of file + return f"{self.player.first()} - [<{int(self.rating) * '★'}> - {self.level}]" \ No newline at end of file diff --git a/app/bloonsa_game/static/bloonsa_game/css/append.css b/app/bloonsa_game/static/bloonsa_game/css/append.css index 8a6739e..a52b493 100644 --- a/app/bloonsa_game/static/bloonsa_game/css/append.css +++ b/app/bloonsa_game/static/bloonsa_game/css/append.css @@ -12,4 +12,14 @@ #horizontal_header { background: #96d3ff; +} + +#profile_box { + background-color: #28B2FF; + display: block; + float: right; + text-align: center; + margin: 10px; + height: 90px; + width: 244px; } \ No newline at end of file diff --git a/app/bloonsa_game/static/bloonsa_game/js/flash_handler.js b/app/bloonsa_game/static/bloonsa_game/js/flash_handler.js new file mode 100644 index 0000000..715dd29 --- /dev/null +++ b/app/bloonsa_game/static/bloonsa_game/js/flash_handler.js @@ -0,0 +1,3 @@ +function as3_new_level_started(id) { + console.log(id) +} \ 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 6b78839..6fdb344 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_edit5.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit5.swf new file mode 100644 index 0000000..6b78839 Binary files /dev/null and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited_edit5.swf differ diff --git a/app/bloonsa_game/templates/bloonsa_game/base.html b/app/bloonsa_game/templates/bloonsa_game/base.html index 5f9cf23..78d5da8 100644 --- a/app/bloonsa_game/templates/bloonsa_game/base.html +++ b/app/bloonsa_game/templates/bloonsa_game/base.html @@ -25,8 +25,19 @@ - + + + {% if head %} + {{ head }} + {% endif %} diff --git a/app/bloonsa_game/templates/bloonsa_game/game.html b/app/bloonsa_game/templates/bloonsa_game/game.html index c1d2e6e..590d29a 100644 --- a/app/bloonsa_game/templates/bloonsa_game/game.html +++ b/app/bloonsa_game/templates/bloonsa_game/game.html @@ -5,15 +5,37 @@ {{ levelTitle }} by {{ levelAuthor }} {% endblock title %} +{% block head %} + +{% endblock head %} + {% block content %} - + width="640" height="480" title="" allowScriptAccess=true> - + width="640" height="480" allowScriptAccess=true> +--> +
+ + {% endblock content %} \ No newline at end of file diff --git a/app/bloonsa_game/templates/bloonsa_game/profilebox.html b/app/bloonsa_game/templates/bloonsa_game/profilebox.html index 207e051..2402b81 100644 --- a/app/bloonsa_game/templates/bloonsa_game/profilebox.html +++ b/app/bloonsa_game/templates/bloonsa_game/profilebox.html @@ -1,4 +1,7 @@ +{% load bloonsa_game_tags %}
-

Welcome back {{ user }}!

+

{{ user }}

+

Levels played: {{ player.levels_played }}
+ Levels beaten: {{ player.levels_beaten }} / {{ player.total_levels }}

Logout

\ No newline at end of file diff --git a/app/bloonsa_game/templatetags/bloonsa_game_tags.py b/app/bloonsa_game/templatetags/bloonsa_game_tags.py new file mode 100644 index 0000000..92527b6 --- /dev/null +++ b/app/bloonsa_game/templatetags/bloonsa_game_tags.py @@ -0,0 +1,9 @@ +from django import template + +from users.models import Player + +register = template.Library() + +@register.filter +def dummy(text): + return f"dummy {text}" \ No newline at end of file diff --git a/app/bloonsa_game/views.py b/app/bloonsa_game/views.py index 2b08d6f..1218c15 100644 --- a/app/bloonsa_game/views.py +++ b/app/bloonsa_game/views.py @@ -25,19 +25,20 @@ class GameView(TemplateView): def get(self, request, *args, **kwargs): tag_player(request=request) # This init is for accounts made with 'createsuperuser' or originating from bloonsb - init_player(request=request) + player = init_player(request=request) # TODO get player object here with init_player to use in html template03.3.005 if type(kwargs.get("pk")) is int: level = Level.objects.get(id=kwargs["pk"]) if level: return render(request, "bloonsa_game/level.html", context={ + "player": player, "flashVars": level.getFlashVars(seperator="&"), "levelTitle": level.title, "levelAuthor": level.author, }) - return render(request, "bloonsa_game/game.html", context={}) + return render(request, "bloonsa_game/game.html", context={"player": player}) class WIPView(TemplateView): diff --git a/app/users/migrations/0012_alter_player_bloonsa_levelratings.py b/app/users/migrations/0012_alter_player_bloonsa_levelratings.py new file mode 100644 index 0000000..49ee427 --- /dev/null +++ b/app/users/migrations/0012_alter_player_bloonsa_levelratings.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-12 20:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0011_levelrating'), + ('users', '0011_player_bloonsa_levelratings_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='player', + name='bloonsa_levelRatings', + field=models.ManyToManyField(blank=True, related_name='player', to='bloonsa_game.levelrating'), + ), + ] diff --git a/app/users/migrations/0013_alter_player_user.py b/app/users/migrations/0013_alter_player_user.py new file mode 100644 index 0000000..7ac84a9 --- /dev/null +++ b/app/users/migrations/0013_alter_player_user.py @@ -0,0 +1,21 @@ +# Generated by Django 5.1.6 on 2025-02-12 21:52 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0012_alter_player_bloonsa_levelratings'), + 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, related_name='player', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/users/models.py b/app/users/models.py index 5ddc573..56b0ca7 100644 --- a/app/users/models.py +++ b/app/users/models.py @@ -6,23 +6,45 @@ from bloonsa_game.models import Level, LevelRating class Player(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name="player") # Savedata bloonsa_levelsPlayed = models.ManyToManyField(Level, blank=True, related_name="levelsPlayed") bloonsa_levelsBeaten = models.ManyToManyField(Level, blank=True, related_name="levelsBeaten") - bloonsa_levelRatings = models.ManyToManyField(LevelRating, blank=True, related_name="levelRatings") + bloonsa_levelRatings = models.ManyToManyField(LevelRating, blank=True, related_name="player") # Logging creationIP = models.GenericIPAddressField() latestIP = models.GenericIPAddressField() creationDate = models.DateTimeField(default=timezone.now) latestActivity = models.DateTimeField(default=timezone.now) - suspectedCheater = models.BooleanField(default=False) + suspectedCheater = models.BooleanField(default=False) # This should be set when tripping the anti-cheat # States - suspended = models.BooleanField(default=False) - banned = models.BooleanField(default=False) - admin = models.BooleanField(default=False) + suspended = models.BooleanField(default=False) # This is a shadow-ban, stats will still save but not all will show up on leaderboards + banned = models.BooleanField(default=False) # Account gets logged out upon logging in + admin = models.BooleanField(default=False) # Ability to suspend/ban other players + + @property + def levels_played(self): + return self.bloonsa_levelsPlayed.count() + + @property + def levels_beaten(self): + return self.bloonsa_levelsBeaten.count() + + @property + def total_levels(self): + return Level.objects.all().count() def __str__(self): - return f"{self.user} - {self.latestIP}" + statesDict = { + "cheater": "😈" if self.suspectedCheater else "", + "suspended": "🔒" if self.suspended else "", + "banned": "❌" if self.banned else "", + "admin": "👑" if self.admin else "", + } + states = "".join(statesDict.values()) + if states: + states += " " + + return f"{states}{self.user} - {self.latestIP}" diff --git a/app/users/util.py b/app/users/util.py index f79085b..00781d6 100644 --- a/app/users/util.py +++ b/app/users/util.py @@ -1,3 +1,4 @@ +from django.contrib.auth import logout from django.utils import timezone from users.models import Player @@ -18,12 +19,13 @@ def init_player(request): return player = Player.objects.filter(user=request.user).first() if player: - return + return player ip = get_ip(request=request) player = Player(user=request.user, creationIP=ip, latestIP=ip) player.save() + return player # Update activity timestamp and IP def tag_player(request): @@ -34,6 +36,13 @@ def tag_player(request): player = Player.objects.filter(user=request.user).first() if not player: init_player(request=request) + if player.banned: + # TODO message popup? + logout(request) + return + player.latestActivity = timezone.now() player.latestIP = get_ip(request=request) - player.save() \ No newline at end of file + player.save() + +