Big update, mostly profile stuff
This commit is contained in:
parent
297c02a080
commit
94bf0654a8
@ -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}]"
|
||||||
@ -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;
|
||||||
|
}
|
||||||
3
app/bloonsa_game/static/bloonsa_game/js/flash_handler.js
Normal file
3
app/bloonsa_game/static/bloonsa_game/js/flash_handler.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function as3_new_level_started(id) {
|
||||||
|
console.log(id)
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
@ -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">
|
||||||
|
|||||||
@ -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 %}
|
||||||
@ -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>
|
||||||
9
app/bloonsa_game/templatetags/bloonsa_game_tags.py
Normal file
9
app/bloonsa_game/templatetags/bloonsa_game_tags.py
Normal 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}"
|
||||||
@ -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="&"),
|
"flashVars": level.getFlashVars(seperator="&"),
|
||||||
"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):
|
||||||
|
|
||||||
|
|||||||
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
21
app/users/migrations/0013_alter_player_user.py
Normal file
21
app/users/migrations/0013_alter_player_user.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -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}"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user