fix(security & perf): implement bearer session tokens, salted pbkdf2, object pooling and background caching

This commit is contained in:
2026-09-17 13:14:31 +00:00
parent 258b1a9cb1
commit 7cd0792799
15 changed files with 1264 additions and 105 deletions
+17 -8
View File
@@ -153,15 +153,19 @@ window.Plant = class Plant {
this.shootTimer = 0;
if (this.type === 'peashooter' && this.level === 3) {
// Tier 3: Plasma Peashooter
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, 'plasma', 0, this.damage));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, 'plasma', 0, this.damage);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, 'plasma', 0, this.damage));
} else if (this.type === 'snowpea' && this.level === 3) {
// Tier 3: Freeze Snowpea
const deepFreeze = Math.random() < 0.2;
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, deepFreeze ? 'freeze_snowpea' : 'snowpea', 0, this.damage));
const pType = deepFreeze ? 'freeze_snowpea' : 'snowpea';
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, pType, 0, this.damage);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, this.damage));
} else {
const isCrit = this.critChance && Math.random() < this.critChance;
const projType = this.type === 'snowpea' ? 'snowpea' : 'pea';
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, projType, 0, this.damage, isCrit));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, projType, 0, this.damage, isCrit);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, projType, 0, this.damage, isCrit));
}
if (window.PvZAudio) window.PvZAudio.playShoot();
}
@@ -178,7 +182,8 @@ window.Plant = class Plant {
this.shootTimer = 0;
const targetX = targetZombie ? targetZombie.x : (hasBoss ? gameState.boss.x : 750);
const projType = this.type === 'melonpult' ? 'melon' : 'cabbage';
gameState.projectiles.push(new window.Projectile(this.x + 15, this.y - 10, this.row, projType, 0, this.damage, false, targetX));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 15, this.y - 10, this.row, projType, 0, this.damage, false, targetX);
else gameState.projectiles.push(new window.Projectile(this.x + 15, this.y - 10, this.row, projType, 0, this.damage, false, targetX));
if (window.PvZAudio) window.PvZAudio.playShoot();
}
}
@@ -191,14 +196,16 @@ window.Plant = class Plant {
this.repeaterThirdPea -= dt;
if (this.repeaterThirdPea <= 0) {
const pType = this.level === 3 ? 'firepea' : 'pea';
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, pType, 0, 22);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
if (window.PvZAudio) window.PvZAudio.playShoot();
}
} else if (this.repeaterSecondPea > 0) {
this.repeaterSecondPea -= dt;
if (this.repeaterSecondPea <= 0) {
const pType = this.level === 3 ? 'firepea' : 'pea';
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, pType, 0, 22);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
if (window.PvZAudio) window.PvZAudio.playShoot();
}
} else if (this.shootTimer >= this.shootInterval) {
@@ -206,7 +213,8 @@ window.Plant = class Plant {
if (hasZombie) {
this.shootTimer = 0;
const pType = this.level === 3 ? 'firepea' : 'pea';
gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 24, this.y - 12, this.row, pType, 0, 22);
else gameState.projectiles.push(new window.Projectile(this.x + 24, this.y - 12, this.row, pType, 0, 22));
this.repeaterSecondPea = 0.16;
if (this.level >= 2 && Math.random() < 0.25) {
this.repeaterThirdPea = 0.32; // Tier 2+ bonus 3rd pea!
@@ -223,7 +231,8 @@ window.Plant = class Plant {
const hasZombie = gameState.zombies.some(z => z.row === this.row && z.x > this.x && (z.x - this.x) < 330 && z.health > 0 && !z.toRemove);
if (hasZombie) {
this.shootTimer = 0;
gameState.projectiles.push(new window.Projectile(this.x + 20, this.y - 8, this.row, 'fume'));
if (gameState.spawnProjectile) gameState.spawnProjectile(this.x + 20, this.y - 8, this.row, 'fume');
else gameState.projectiles.push(new window.Projectile(this.x + 20, this.y - 8, this.row, 'fume'));
if (window.PvZAudio) window.PvZAudio.playShoot();
}
}