Compare commits
4 Commits
c116f8dcb1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe4f135b92 | ||
|
|
f05e91c2ce | ||
|
|
9587995354 | ||
|
|
93dafb6a81 |
@@ -1,3 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
name = 'api'
|
||||
@@ -1,22 +0,0 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-10 18:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Building',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('geojson_id', models.IntegerField()),
|
||||
('health', models.FloatField()),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,38 +0,0 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-11 00:00
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("api", "0001_initial"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="PlayerInfo",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("energy", models.PositiveIntegerField()),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="player_info",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,16 +0,0 @@
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Building(models.Model):
|
||||
geojson_id = models.IntegerField()
|
||||
health = models.FloatField()
|
||||
|
||||
|
||||
class PlayerInfo(models.Model):
|
||||
user = models.OneToOneField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="player_info",
|
||||
)
|
||||
energy = models.PositiveIntegerField()
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import prova
|
||||
|
||||
urlpatterns = [path("prova/", prova)]
|
||||
@@ -1,6 +0,0 @@
|
||||
from django.http.request import HttpRequest
|
||||
from django.http.response import JsonResponse
|
||||
|
||||
|
||||
def prova(reques: HttpRequest):
|
||||
return JsonResponse({"message": "OK"})
|
||||
2
build.js
2
build.js
@@ -10,7 +10,7 @@ const config = {
|
||||
format: "iife", // o 'iife' se serve per un tag <script> classico
|
||||
target: "es2020",
|
||||
sourcemap: isDev,
|
||||
minify: !isDev,
|
||||
minify: true,
|
||||
logLevel: "info",
|
||||
};
|
||||
|
||||
|
||||
1
bun.lock
1
bun.lock
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
|
||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@@ -40,12 +40,11 @@ ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"api",
|
||||
"game",
|
||||
"frontend",
|
||||
"rest_framework",
|
||||
"rest_framework_simplejwt",
|
||||
"rest_framework_simplejwt.token_blacklist",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
|
||||
@@ -15,11 +15,8 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path("", include("frontend.urls")),
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/", include("api.urls")),
|
||||
]
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -1,8 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class FrontendConfig(AppConfig):
|
||||
name = "frontend"
|
||||
|
||||
def ready(self) -> None:
|
||||
from . import models # noqa: F401
|
||||
@@ -1,37 +0,0 @@
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="UserProfile",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("display_name", models.CharField(max_length=150)),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,15 +0,0 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("frontend", "0001_userprofile"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="userprofile",
|
||||
name="display_name",
|
||||
field=models.CharField(max_length=150, unique=True),
|
||||
),
|
||||
]
|
||||
@@ -1,6 +1,52 @@
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
--map-ink: #041005;
|
||||
--map-void: #020a03;
|
||||
--map-forest: #0b1f0e;
|
||||
--map-grid: #0f2f17;
|
||||
--map-road: #1de85b;
|
||||
--map-road-soft: #119a3b;
|
||||
--map-node: #6dff9d;
|
||||
--map-label: #7dffa6;
|
||||
--map-glow: rgba(19, 240, 97, 0.35);
|
||||
--map-glow-strong: rgba(19, 240, 97, 0.65);
|
||||
--map-surface: rgba(6, 20, 9, 0.85);
|
||||
--map-surface-strong: rgba(6, 24, 10, 0.96);
|
||||
--map-border: rgba(29, 232, 91, 0.35);
|
||||
--map-border-strong: rgba(29, 232, 91, 0.6);
|
||||
--map-text: #b5ffd0;
|
||||
--map-muted: #6bbf83;
|
||||
--map-accent: #1de85b;
|
||||
--map-accent-hot: #9bff5c;
|
||||
}
|
||||
|
||||
body {
|
||||
background: radial-gradient(
|
||||
circle at top,
|
||||
#0b1f0e 0%,
|
||||
#041005 45%,
|
||||
#020a03 100%
|
||||
);
|
||||
color: var(--map-text);
|
||||
font-family:
|
||||
"JetBrains Mono", "SFMono-Regular", "Menlo", "Monaco", "Consolas",
|
||||
monospace;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background:
|
||||
radial-gradient(
|
||||
circle at 20% 10%,
|
||||
rgba(12, 48, 20, 0.85),
|
||||
rgba(4, 14, 7, 0.9)
|
||||
),
|
||||
linear-gradient(140deg, rgba(5, 24, 10, 0.95), rgba(2, 8, 4, 0.98));
|
||||
}
|
||||
|
||||
.site-header {
|
||||
@@ -15,14 +61,20 @@
|
||||
justify-content: space-between;
|
||||
padding: 0.85rem 1.5rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
rgba(7, 24, 11, 0.9),
|
||||
rgba(6, 20, 9, 0.75)
|
||||
);
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
box-shadow: 0 18px 40px rgba(24, 31, 59, 0.16);
|
||||
border: 1px solid var(--map-border);
|
||||
box-shadow:
|
||||
0 18px 40px rgba(0, 0, 0, 0.45),
|
||||
0 0 24px var(--map-glow);
|
||||
font-family:
|
||||
"JetBrains Mono", "SFMono-Regular", "Menlo", "Monaco", "Consolas",
|
||||
monospace;
|
||||
color: #111827;
|
||||
color: var(--map-text);
|
||||
}
|
||||
|
||||
.site-brand {
|
||||
@@ -32,6 +84,7 @@
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 12px var(--map-glow);
|
||||
}
|
||||
|
||||
.site-actions {
|
||||
@@ -42,16 +95,16 @@
|
||||
}
|
||||
|
||||
.site-user {
|
||||
color: #4b5563;
|
||||
color: var(--map-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.site-link {
|
||||
text-decoration: none;
|
||||
color: #111827;
|
||||
color: var(--map-text);
|
||||
padding: 0.45rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(17, 24, 39, 0.12);
|
||||
border: 1px solid rgba(29, 232, 91, 0.25);
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
@@ -60,15 +113,18 @@
|
||||
|
||||
.site-link:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: rgba(17, 24, 39, 0.28);
|
||||
box-shadow: 0 10px 20px rgba(15, 23, 42, 0.12);
|
||||
border-color: var(--map-border-strong);
|
||||
box-shadow:
|
||||
0 10px 20px rgba(0, 0, 0, 0.35),
|
||||
0 0 16px var(--map-glow);
|
||||
}
|
||||
|
||||
.site-link--accent {
|
||||
border: none;
|
||||
background: linear-gradient(130deg, #f97316, #facc15);
|
||||
color: #1f2937;
|
||||
background: linear-gradient(130deg, #0fd64f, #9bff5c);
|
||||
color: #041005;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 0 18px rgba(15, 214, 79, 0.45);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
@@ -97,12 +153,12 @@
|
||||
padding: 4rem 1.5rem;
|
||||
background: radial-gradient(
|
||||
circle at top,
|
||||
#eef5ff,
|
||||
#f7f0ff 35%,
|
||||
#f7f6ff 65%,
|
||||
#fdf6ef
|
||||
#0e2613,
|
||||
#07180c 35%,
|
||||
#041106 65%,
|
||||
#020a03
|
||||
);
|
||||
color: #1f1f1f;
|
||||
color: var(--map-text);
|
||||
font-family:
|
||||
"JetBrains Mono", "SFMono-Regular", "Menlo", "Monaco", "Consolas",
|
||||
monospace;
|
||||
@@ -110,11 +166,13 @@
|
||||
|
||||
.auth-card {
|
||||
width: min(420px, 100%);
|
||||
background: #ffffff;
|
||||
background: var(--map-surface);
|
||||
border-radius: 24px;
|
||||
padding: 2.5rem;
|
||||
box-shadow: 0 24px 60px rgba(24, 31, 59, 0.12);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
box-shadow:
|
||||
0 24px 60px rgba(0, 0, 0, 0.5),
|
||||
0 0 22px var(--map-glow);
|
||||
border: 1px solid var(--map-border);
|
||||
}
|
||||
|
||||
.auth-header {
|
||||
@@ -125,28 +183,28 @@
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.2em;
|
||||
font-size: 0.7rem;
|
||||
color: #57606a;
|
||||
color: var(--map-muted);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.auth-title {
|
||||
font-size: 1.6rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #111827;
|
||||
color: var(--map-text);
|
||||
}
|
||||
|
||||
.auth-subtitle {
|
||||
font-size: 0.95rem;
|
||||
color: #6b7280;
|
||||
color: var(--map-muted);
|
||||
}
|
||||
|
||||
.auth-messages {
|
||||
margin-bottom: 1.5rem;
|
||||
background: #fff4f4;
|
||||
border: 1px solid #ffccd2;
|
||||
background: rgba(18, 55, 26, 0.75);
|
||||
border: 1px solid rgba(110, 255, 157, 0.35);
|
||||
border-radius: 16px;
|
||||
padding: 0.75rem 1rem;
|
||||
color: #b42318;
|
||||
color: var(--map-accent-hot);
|
||||
}
|
||||
|
||||
.auth-message {
|
||||
@@ -158,6 +216,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.auth-field {
|
||||
@@ -165,20 +224,26 @@
|
||||
flex-direction: column;
|
||||
gap: 0.45rem;
|
||||
font-size: 0.85rem;
|
||||
color: #374151;
|
||||
color: var(--map-muted);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.auth-field input {
|
||||
padding: 0.7rem 0.9rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #d1d5db;
|
||||
border: 1px solid rgba(109, 255, 157, 0.3);
|
||||
font-size: 0.95rem;
|
||||
font-family: inherit;
|
||||
background: var(--map-surface-strong);
|
||||
color: var(--map-text);
|
||||
box-shadow: inset 0 0 0 1px rgba(3, 18, 7, 0.8);
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.auth-field input:focus {
|
||||
outline: 2px solid rgba(76, 110, 245, 0.35);
|
||||
border-color: #6d7bf7;
|
||||
outline: 2px solid rgba(29, 232, 91, 0.35);
|
||||
border-color: var(--map-accent);
|
||||
}
|
||||
|
||||
.auth-submit {
|
||||
@@ -186,8 +251,8 @@
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
background: linear-gradient(130deg, #f97316, #facc15);
|
||||
color: #1f2937;
|
||||
background: linear-gradient(130deg, #0fd64f, #9bff5c);
|
||||
color: #041005;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
@@ -197,17 +262,19 @@
|
||||
|
||||
.auth-submit:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 12px 25px rgba(249, 115, 22, 0.3);
|
||||
box-shadow:
|
||||
0 12px 25px rgba(15, 214, 79, 0.35),
|
||||
0 0 18px var(--map-glow-strong);
|
||||
}
|
||||
|
||||
.auth-footer {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: #6b7280;
|
||||
color: var(--map-muted);
|
||||
}
|
||||
|
||||
.auth-footer a {
|
||||
color: #111827;
|
||||
color: var(--map-text);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
13
frontend/static/frontend/ts/layers.ts
Normal file
13
frontend/static/frontend/ts/layers.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { AddLayerObject } from "maplibre-gl";
|
||||
|
||||
export const HIGHLIGHT_LAYER = {
|
||||
id: "buildings-highlight", // nome arbitrario del layer
|
||||
type: "fill",
|
||||
source: "buildings",
|
||||
"source-layer": "building",
|
||||
paint: {
|
||||
"fill-color": "#41ff44",
|
||||
"fill-opacity": 1,
|
||||
},
|
||||
filter: ["==", ["id"], ""],
|
||||
} as AddLayerObject;
|
||||
@@ -1,14 +1,12 @@
|
||||
import add from "./lib/add";
|
||||
import { HIGHLIGHT_LAYER } from "./layers";
|
||||
|
||||
import { Map } from "maplibre-gl";
|
||||
|
||||
console.log(add(1, 2));
|
||||
|
||||
const map = new Map({
|
||||
style:
|
||||
"https://api.maptiler.com/maps/019be805-c88e-7c8b-9850-bc704d72e604/style.json?key=8nmgHEIZQiIgqQj3RZNa",
|
||||
container: "map",
|
||||
zoom: 15,
|
||||
zoom: 17,
|
||||
});
|
||||
|
||||
map.on("load", () => {
|
||||
@@ -20,17 +18,7 @@ map.on("load", () => {
|
||||
});
|
||||
|
||||
// Il layer per gli highlight
|
||||
map.addLayer({
|
||||
id: "buildings-highlight", // nome arbitrario del layer
|
||||
type: "fill",
|
||||
source: "buildings",
|
||||
"source-layer": "building",
|
||||
paint: {
|
||||
"fill-color": "#41ff44",
|
||||
"fill-opacity": 1,
|
||||
},
|
||||
filter: ["==", ["id"], ""],
|
||||
});
|
||||
map.addLayer(HIGHLIGHT_LAYER);
|
||||
|
||||
map.on("mousemove", (ev) => {
|
||||
const features = map.queryRenderedFeatures(ev.point, {
|
||||
@@ -38,13 +26,16 @@ map.on("load", () => {
|
||||
});
|
||||
|
||||
if (features && features.length > 0) {
|
||||
const hoveredId = features[0].id;
|
||||
const feature = features[0];
|
||||
const hoveredId = feature.id;
|
||||
|
||||
if (hoveredId) {
|
||||
map.setFilter("buildings-highlight", ["==", ["id"], hoveredId]);
|
||||
map.getCanvas().style.cursor = "pointer";
|
||||
}
|
||||
} else {
|
||||
map.setFilter("buildings-highlight", ["==", ["id"], ""]);
|
||||
map.getCanvas().style.cursor = "";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="site-actions">
|
||||
{% if user.is_authenticated %}
|
||||
<span class="site-user">
|
||||
{{ user.profile.display_name|default:user.get_username }}
|
||||
Welcome, <strong>{{ user.profile.display_name|default:user.get_username }}</strong>
|
||||
</span>
|
||||
<a class="site-link" href="{% url 'logout' %}">Logout</a>
|
||||
{% else %}
|
||||
|
||||
@@ -2,7 +2,6 @@ from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.home, name="home"),
|
||||
path("auth/register/", views.register, name="register"),
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.shortcuts import redirect, render
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django_ratelimit.decorators import ratelimit
|
||||
|
||||
from .models import UserProfile
|
||||
from game.models import UserProfile
|
||||
|
||||
|
||||
def home(request):
|
||||
|
||||
5
game/apps.py
Normal file
5
game/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class GameConfig(AppConfig):
|
||||
name = 'game'
|
||||
41
game/migrations/0001_initial.py
Normal file
41
game/migrations/0001_initial.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-11 20:00
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Building',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('geojson_id', models.IntegerField()),
|
||||
('health', models.FloatField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PlayerInfo',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('energy', models.PositiveIntegerField()),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='player_info', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserProfile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('display_name', models.CharField(max_length=150, unique=True)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -4,6 +4,20 @@ from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
|
||||
class Building(models.Model):
|
||||
geojson_id = models.IntegerField()
|
||||
health = models.FloatField()
|
||||
|
||||
|
||||
class PlayerInfo(models.Model):
|
||||
user = models.OneToOneField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="player_info",
|
||||
)
|
||||
energy = models.PositiveIntegerField()
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
user = models.OneToOneField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
@@ -19,7 +33,8 @@ class UserProfile(models.Model):
|
||||
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
|
||||
def create_profile_for_user(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
UserProfile.objects.create( # type: ignore[attr-defined]
|
||||
UserProfile.objects.create(
|
||||
user=instance,
|
||||
display_name=instance.username,
|
||||
)
|
||||
PlayerInfo.objects.create(user=instance, energy=10_000)
|
||||
3
game/views.py
Normal file
3
game/views.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
@@ -7,6 +7,7 @@ requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"django>=6.0.2",
|
||||
"django-ratelimit>=4.1.0",
|
||||
"django-stubs>=5.2.9",
|
||||
"djangorestframework>=3.16.1",
|
||||
"djangorestframework-simplejwt>=5.5.0",
|
||||
"ipython>=9.10.0",
|
||||
|
||||
@@ -5,6 +5,8 @@ click==8.3.1
|
||||
decorator==5.2.1
|
||||
django==6.0.2
|
||||
django-ratelimit==4.1.0
|
||||
django-stubs==5.2.9
|
||||
django-stubs-ext==5.2.9
|
||||
djangorestframework==3.16.1
|
||||
djangorestframework-simplejwt==5.5.1
|
||||
executing==2.2.1
|
||||
@@ -26,6 +28,7 @@ python-dotenv==1.2.1
|
||||
sqlparse==0.5.5
|
||||
stack-data==0.6.3
|
||||
traitlets==5.14.3
|
||||
types-pyyaml==6.0.12.20250915
|
||||
typing-extensions==4.15.0
|
||||
typing-inspection==0.4.2
|
||||
uvicorn==0.40.0
|
||||
|
||||
39
uv.lock
generated
39
uv.lock
generated
@@ -82,6 +82,34 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/78/2c59b30cd8bc8068d02349acb6aeed5c4e05eb01cdf2107ccd76f2e81487/django_ratelimit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d047a31cf94d83ef1465d7543ca66c6fc16695559b5f8d814d1b51df15110b92", size = 11608, upload-time = "2023-07-24T20:34:31.362Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-stubs"
|
||||
version = "5.2.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "django-stubs-ext" },
|
||||
{ name = "types-pyyaml" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9c/01/86c921e0e19c9fa7e705bf795998dbf55eb183e7be0342a3027dc1bcbc9f/django_stubs-5.2.9.tar.gz", hash = "sha256:c192257120b08785cfe6f2f1c91f1797aceae8e9daa689c336e52c91e8f6a493", size = 257970, upload-time = "2026-01-20T23:59:27.018Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/05/4c9c419b7051eb4b350100b086be6df487f968ab672d3d370f8ccf7c3746/django_stubs-5.2.9-py3-none-any.whl", hash = "sha256:2317a7130afdaa76f6ff7f623650d7f3bf1b6c86a60f95840e14e6ec6de1a7cd", size = 508656, upload-time = "2026-01-20T23:59:25.12Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-stubs-ext"
|
||||
version = "5.2.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/55/03/9c2be939490d2282328db4611bc5956899f5ff7eabc3e88bd4b964a87373/django_stubs_ext-5.2.9.tar.gz", hash = "sha256:6db4054d1580657b979b7d391474719f1a978773e66c7070a5e246cd445a25a9", size = 6497, upload-time = "2026-01-20T23:58:59.462Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/f7/0d5f7d7e76fe972d9f560f687fdc0cab4db9e1624fd90728ca29b4ed7a63/django_stubs_ext-5.2.9-py3-none-any.whl", hash = "sha256:230c51575551b0165be40177f0f6805f1e3ebf799b835c85f5d64c371ca6cf71", size = 9974, upload-time = "2026-01-20T23:58:58.438Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "djangorestframework"
|
||||
version = "3.16.1"
|
||||
@@ -115,6 +143,7 @@ source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "django-ratelimit" },
|
||||
{ name = "django-stubs" },
|
||||
{ name = "djangorestframework" },
|
||||
{ name = "djangorestframework-simplejwt" },
|
||||
{ name = "ipython" },
|
||||
@@ -128,6 +157,7 @@ dependencies = [
|
||||
requires-dist = [
|
||||
{ name = "django", specifier = ">=6.0.2" },
|
||||
{ name = "django-ratelimit", specifier = ">=4.1.0" },
|
||||
{ name = "django-stubs", specifier = ">=5.2.9" },
|
||||
{ name = "djangorestframework", specifier = ">=3.16.1" },
|
||||
{ name = "djangorestframework-simplejwt", specifier = ">=5.5.0" },
|
||||
{ name = "ipython", specifier = ">=9.10.0" },
|
||||
@@ -390,6 +420,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-pyyaml"
|
||||
version = "6.0.12.20250915"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz", hash = "sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3", size = 17522, upload-time = "2025-09-15T03:01:00.728Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/e0/1eed384f02555dde685fff1a1ac805c1c7dcb6dd019c916fe659b1c1f9ec/types_pyyaml-6.0.12.20250915-py3-none-any.whl", hash = "sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6", size = 20338, upload-time = "2025-09-15T03:00:59.218Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
|
||||
Reference in New Issue
Block a user