Big update, mostly profile stuff

This commit is contained in:
Walter 2025-02-13 00:57:53 +01:00
parent 297c02a080
commit 94bf0654a8
14 changed files with 148 additions and 18 deletions

View File

@ -42,4 +42,4 @@ class LevelRating(models.Model):
rating = models.SmallIntegerField() rating = models.SmallIntegerField()
def __str__(self): def __str__(self):
return f"<{self.rating}> {self.level}" return f"{self.player.first()} - [<{int(self.rating) * ''}> - {self.level}]"

View File

@ -13,3 +13,13 @@
#horizontal_header { #horizontal_header {
background: #96d3ff; background: #96d3ff;
} }
#profile_box {
background-color: #28B2FF;
display: block;
float: right;
text-align: center;
margin: 10px;
height: 90px;
width: 244px;
}

View File

@ -0,0 +1,3 @@
function as3_new_level_started(id) {
console.log(id)
}

View File

@ -25,8 +25,19 @@
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/main.css' %}"/> <link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/main.css' %}"/>
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/append.css' %}"/> <link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/append.css' %}"/>
<script>window.RufflePlayer=window.RufflePlayer||{};window.RufflePlayer.config={"autoplay":"on","unmuteOverlay":"hidden"};</script> <script>window.RufflePlayer=window.RufflePlayer||{};
window.RufflePlayer.config={"autoplay":"on",
"unmuteOverlay":"hidden",
"allowScriptAccess": true,
"quality": "high",
"splashScreen": false,
"menu": false,
"polyfills": true,};</script>
<script src="{% static 'bloonsa_game/misc/ruffle/ruffle.js' %}"></script> <script src="{% static 'bloonsa_game/misc/ruffle/ruffle.js' %}"></script>
<script src="{% static 'bloonsa_game/js/flash_handler.js' %}"></script>
{% if head %}
{{ head }}
{% endif %}
</head> </head>
<body id="body"> <body id="body">

View File

@ -5,15 +5,37 @@
{{ levelTitle }} by {{ levelAuthor }} {{ levelTitle }} by {{ levelAuthor }}
{% endblock title %} {% endblock title %}
{% block head %}
{% endblock head %}
{% block content %} {% block content %}
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" <!--<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="{% static 'bloonsa_game/misc/swflash.cab' %}#version=7,0,19,0" codebase="{% static 'bloonsa_game/misc/swflash.cab' %}#version=7,0,19,0"
width="640" height="480" title=""> width="640" height="480" title="" allowScriptAccess=true>
<param name="movie" value="{% static 'bloonsa_game/misc/bloons_unlimited.swf' %}"> <param name="movie" value="{% static 'bloonsa_game/misc/bloons_unlimited.swf' %}">
<param name="quality" value="high"> <param name="quality" value="high">
<embed src="{% static 'bloonsa_game/misc/bloons_unlimited.swf' %}" <embed src="{% static 'bloonsa_game/misc/bloons_unlimited.swf' %}"
quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash" type="application/x-shockwave-flash"
width="640" height="480"> width="640" height="480" allowScriptAccess=true>
</object> </object>-->
<div id="bloonsa-game"></div>
<script>
window.RufflePlayer = window.RufflePlayer || {};
window.addEventListener("load", (event) => {
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
const container = document.getElementById("bloonsa-game");
container.appendChild(player);
player.load({
url: "{% static 'bloonsa_game/misc/bloons_unlimited.swf' %}",
allowScriptAccess: true,
backgroundColor: "#000",
});
player.style.width = "640px";
player.style.height = "480px";
});
</script>
{% endblock content %} {% endblock content %}

View File

@ -1,4 +1,7 @@
{% load bloonsa_game_tags %}
<div id="profile_box"> <div id="profile_box">
<h2>Welcome back {{ user }}!</h2> <h3>{{ user }}</h3>
<p>Levels played: {{ player.levels_played }}<br>
Levels beaten: {{ player.levels_beaten }} / {{ player.total_levels }}</p>
<h3><a href="/users/logout">Logout</a></h3> <h3><a href="/users/logout">Logout</a></h3>
</div> </div>

View File

@ -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}"

View File

@ -25,19 +25,20 @@ class GameView(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
tag_player(request=request) tag_player(request=request)
# This init is for accounts made with 'createsuperuser' or originating from bloonsb # 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 # TODO get player object here with init_player to use in html template03.3.005
if type(kwargs.get("pk")) is int: if type(kwargs.get("pk")) is int:
level = Level.objects.get(id=kwargs["pk"]) level = Level.objects.get(id=kwargs["pk"])
if level: if level:
return render(request, "bloonsa_game/level.html", context={ return render(request, "bloonsa_game/level.html", context={
"player": player,
"flashVars": level.getFlashVars(seperator="&amp;"), "flashVars": level.getFlashVars(seperator="&amp;"),
"levelTitle": level.title, "levelTitle": level.title,
"levelAuthor": level.author, "levelAuthor": level.author,
}) })
return render(request, "bloonsa_game/game.html", context={}) return render(request, "bloonsa_game/game.html", context={"player": player})
class WIPView(TemplateView): class WIPView(TemplateView):

View File

@ -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'),
),
]

View File

@ -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),
),
]

View File

@ -6,23 +6,45 @@ from bloonsa_game.models import Level, LevelRating
class Player(models.Model): 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 # Savedata
bloonsa_levelsPlayed = models.ManyToManyField(Level, blank=True, related_name="levelsPlayed") bloonsa_levelsPlayed = models.ManyToManyField(Level, blank=True, related_name="levelsPlayed")
bloonsa_levelsBeaten = models.ManyToManyField(Level, blank=True, related_name="levelsBeaten") 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 # Logging
creationIP = models.GenericIPAddressField() creationIP = models.GenericIPAddressField()
latestIP = models.GenericIPAddressField() latestIP = models.GenericIPAddressField()
creationDate = models.DateTimeField(default=timezone.now) creationDate = models.DateTimeField(default=timezone.now)
latestActivity = 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 # States
suspended = 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) banned = models.BooleanField(default=False) # Account gets logged out upon logging in
admin = models.BooleanField(default=False) 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): 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}"

View File

@ -1,3 +1,4 @@
from django.contrib.auth import logout
from django.utils import timezone from django.utils import timezone
from users.models import Player from users.models import Player
@ -18,12 +19,13 @@ def init_player(request):
return return
player = Player.objects.filter(user=request.user).first() player = Player.objects.filter(user=request.user).first()
if player: if player:
return return player
ip = get_ip(request=request) ip = get_ip(request=request)
player = Player(user=request.user, player = Player(user=request.user,
creationIP=ip, creationIP=ip,
latestIP=ip) latestIP=ip)
player.save() player.save()
return player
# Update activity timestamp and IP # Update activity timestamp and IP
def tag_player(request): def tag_player(request):
@ -34,6 +36,13 @@ def tag_player(request):
player = Player.objects.filter(user=request.user).first() player = Player.objects.filter(user=request.user).first()
if not player: if not player:
init_player(request=request) init_player(request=request)
if player.banned:
# TODO message popup?
logout(request)
return
player.latestActivity = timezone.now() player.latestActivity = timezone.now()
player.latestIP = get_ip(request=request) player.latestIP = get_ip(request=request)
player.save() player.save()