Added InviteCode system
This commit is contained in:
parent
d91681a7ec
commit
3d98f297d9
@ -31,7 +31,7 @@ def load_insecure_key():
|
||||
|
||||
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY") or load_insecure_key()
|
||||
|
||||
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ") or "*"
|
||||
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "*").split(" ")
|
||||
|
||||
# Application definition
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
|
||||
from .models import Player, Log
|
||||
from .models import Player, Log, InviteCode
|
||||
|
||||
admin.site.register(Log)
|
||||
admin.site.register(Player)
|
||||
admin.site.register(InviteCode)
|
||||
@ -8,7 +8,7 @@ from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Submit
|
||||
|
||||
from users.models import Player
|
||||
from users.validators import usernameValidator, username_change_validator
|
||||
from users.validators import username_validator, username_change_validator, invitecode_validator
|
||||
from bloonsa_game.models import Config as BloonsaConfig
|
||||
|
||||
class UserRegisterForm(UserCreationForm):
|
||||
@ -23,12 +23,20 @@ class UserRegisterForm(UserCreationForm):
|
||||
self.helper.form_action = '/users/register'
|
||||
self.helper.add_input(Submit('submit', 'Create'))
|
||||
|
||||
invite_code = forms.CharField(max_length=64,
|
||||
label="invite_code",
|
||||
empty_value="code",
|
||||
# help_text="",
|
||||
required=True,
|
||||
validators=[invitecode_validator,])
|
||||
|
||||
username = forms.CharField(min_length=3,
|
||||
max_length=16,
|
||||
label="Username",
|
||||
required=True,
|
||||
validators=[usernameValidator,],
|
||||
help_text=_("3-16 chars, alphanumeric and _- pls"))
|
||||
validators=[username_validator,],
|
||||
#help_text=_("3-16 chars, alphanumeric and _- pls")
|
||||
)
|
||||
|
||||
password1 = forms.CharField(
|
||||
label="Password",
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-20 21:11
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0025_alter_player_avatar'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InviteCode',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.TextField(max_length=64)),
|
||||
('code', models.TextField(max_length=64)),
|
||||
('active', models.BooleanField(default=True)),
|
||||
],
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='log',
|
||||
name='action',
|
||||
field=models.IntegerField(choices=[(0, 'Logged in'), (1, 'Registered'), (2, 'Logged out'), (3, 'Edited account settings'), (100, 'Loaded a level via ingame ID box'), (101, 'Loaded a level via URL'), (102, 'Loaded a random level'), (103, 'Submitted a score on level_id'), (104, 'Rated a level')]),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='player',
|
||||
name='invite_code',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.invitecode'),
|
||||
),
|
||||
]
|
||||
@ -4,10 +4,18 @@ from django.contrib.auth.models import User
|
||||
from django_resized import ResizedImageField
|
||||
|
||||
|
||||
class InviteCode(models.Model):
|
||||
title = models.TextField(max_length=64)
|
||||
code = models.TextField(max_length=64)
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} | code: {self.code}"
|
||||
|
||||
class Player(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="player")
|
||||
# Profile
|
||||
bio = models.TextField(max_length=128, null=True)
|
||||
bio = models.TextField(max_length=128, null=True, blank=True)
|
||||
avatar = ResizedImageField(default="defaults/avatars.jpg",
|
||||
size=[256, 256],
|
||||
upload_to="avatars",
|
||||
@ -21,6 +29,7 @@ class Player(models.Model):
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
latest_activity = models.DateTimeField(default=timezone.now)
|
||||
suspected_cheater = models.BooleanField(default=False) # This should be set when tripping the anti-cheat
|
||||
invite_code = models.ForeignKey(InviteCode, null=True, blank=True, on_delete=models.CASCADE)
|
||||
# States
|
||||
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
|
||||
@ -50,6 +59,8 @@ class Player(models.Model):
|
||||
return f"{states}{self.user} - {self.latest_ip}".strip(" ")
|
||||
|
||||
|
||||
|
||||
|
||||
class Log(models.Model):
|
||||
class Actions(models.IntegerChoices):
|
||||
login = 0, "Logged in"
|
||||
@ -69,3 +80,4 @@ class Log(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.player.user.username} - {self.get_action_display()} <{self.note or ''}>"
|
||||
|
||||
|
||||
@ -25,6 +25,9 @@ class BloonsaUtil:
|
||||
if not request.user.is_authenticated:
|
||||
return
|
||||
if hasattr(request.user, "player"):
|
||||
if not hasattr(request.user.player, "bloonsa_config"):
|
||||
bloonsa_config = Config(player=request.user.player)
|
||||
bloonsa_config.save()
|
||||
return request.user.player
|
||||
ip = self.get_ip(request=request)
|
||||
player = Player(user=request.user,
|
||||
|
||||
@ -3,9 +3,10 @@ import string
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from users.models import Player
|
||||
from users.models import Player, InviteCode
|
||||
|
||||
def usernameValidator(username):
|
||||
|
||||
def username_validator(username):
|
||||
if User.objects.filter(username__iexact=username).first() is not None:
|
||||
raise ValidationError("Sorry, this username is already in use")
|
||||
|
||||
@ -23,3 +24,10 @@ def username_change_validator(username):
|
||||
charset = set(string.ascii_letters + string.digits + "_-")
|
||||
if not all(x in charset for x in username):
|
||||
raise ValidationError("Username may only contain normal letters, numbers and _-")
|
||||
|
||||
def invitecode_validator(invitecode):
|
||||
if len(invitecode) > 64:
|
||||
raise ValidationError("Invite code too long")
|
||||
|
||||
if not InviteCode.objects.filter(code=invitecode).exists():
|
||||
raise ValidationError("Invite code doesn't exist")
|
||||
@ -5,7 +5,7 @@ from django.shortcuts import render, redirect
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from users.forms import UserRegisterForm, UserLoginForm, PlayerUpdateForm, UserUpdateForm, BloonsaConfigUpdateForm
|
||||
from users.models import Player
|
||||
from users.models import Player, InviteCode
|
||||
from users.util import bloonsa_util, actions
|
||||
|
||||
|
||||
@ -37,9 +37,14 @@ class RegisterView(TemplateView):
|
||||
form = UserRegisterForm(request.POST)
|
||||
if not form.is_valid():
|
||||
return render(request=request, template_name="users/register.html", context={"form": form})
|
||||
|
||||
invite_code = InviteCode.objects.get(code=form.cleaned_data["invite_code"])
|
||||
user = form.save()
|
||||
player = bloonsa_util.init_player(request=request)
|
||||
login(request=request, user=user)
|
||||
player = bloonsa_util.init_player(request=request)
|
||||
player.invite_code = invite_code
|
||||
player.save()
|
||||
|
||||
bloonsa_util.log(player=player,
|
||||
action=actions.login)
|
||||
return redirect("bloonsa_game:game")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user