Merge branch 'improve_stack_gain' into 'main'
Improve handling of the user pixel stack See merge request sc07/canvas!8
This commit is contained in:
commit
85dd5d76b8
|
@ -18,6 +18,7 @@ const getTimeLeft = (pixels: { available: number }, config: ClientConfig) => {
|
|||
const cooldown = CanvasLib.getPixelCooldown(pixels.available + 1, config);
|
||||
const pixelExpiresAt =
|
||||
Canvas.instance?.lastPlace && Canvas.instance.lastPlace + cooldown * 1000;
|
||||
|
||||
const pixelCooldown = pixelExpiresAt && (Date.now() - pixelExpiresAt) / 1000;
|
||||
|
||||
if (!pixelCooldown) return undefined;
|
||||
|
@ -43,7 +44,7 @@ const PlaceCountdown = () => {
|
|||
return (
|
||||
<>
|
||||
{timeLeft
|
||||
? pixels.available + 1 < config.canvas.pixel.maxStack && timeLeft + "s"
|
||||
? pixels.available < config.canvas.pixel.maxStack && timeLeft + "s"
|
||||
: ""}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -53,11 +53,9 @@ export class Canvas extends EventEmitter<CanvasEvents> {
|
|||
this.PanZoom.addListener("click", this.handleMouseDown.bind(this));
|
||||
this.PanZoom.addListener("longPress", this.handleLongPress);
|
||||
|
||||
Network.waitForState("pixelLastPlaced").then(
|
||||
([time]) => (this.lastPlace = time)
|
||||
);
|
||||
Network.on("pixel", this.handlePixel);
|
||||
Network.on("square", this.handleSquare);
|
||||
Network.on("pixelLastPlaced", this.handlePixelLastPlaced);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
@ -70,6 +68,7 @@ export class Canvas extends EventEmitter<CanvasEvents> {
|
|||
|
||||
Network.off("pixel", this.handlePixel);
|
||||
Network.off("square", this.handleSquare);
|
||||
Network.off("pixelLastPlaced", this.handlePixelLastPlaced);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -309,6 +308,10 @@ export class Canvas extends EventEmitter<CanvasEvents> {
|
|||
getRenderer().usePixel({ x, y, hex: palette?.hex || "null" });
|
||||
};
|
||||
|
||||
handlePixelLastPlaced = (time: number) => {
|
||||
this.lastPlace = time;
|
||||
};
|
||||
|
||||
Pallete = {
|
||||
getColor: (colorId: number) => {
|
||||
return this.config.pallete.colors.find((c) => c.id === colorId);
|
||||
|
@ -358,7 +361,6 @@ export class Canvas extends EventEmitter<CanvasEvents> {
|
|||
)
|
||||
.then((ack) => {
|
||||
if (ack.success) {
|
||||
this.lastPlace = Date.now();
|
||||
this.handlePixel(ack.data);
|
||||
} else {
|
||||
console.warn(
|
||||
|
|
|
@ -12,7 +12,7 @@ Table User {
|
|||
display_name String
|
||||
picture_url String
|
||||
profile_url String
|
||||
lastPixelTime DateTime [default: `now()`, not null]
|
||||
lastTimeGainStarted DateTime [default: `now()`, not null]
|
||||
pixelStack Int [not null, default: 0]
|
||||
undoExpires DateTime
|
||||
isAdmin Boolean [not null, default: false]
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE "User" RENAME COLUMN "lastPixelTime" TO "lastTimeGainStarted";
|
|
@ -25,7 +25,7 @@ model User {
|
|||
picture_url String?
|
||||
profile_url String?
|
||||
|
||||
lastPixelTime DateTime @default(now()) // the time the last pixel was placed at
|
||||
lastTimeGainStarted DateTime @default(now()) // the time base used to determine the amount of stack the user should gain
|
||||
pixelStack Int @default(0) // amount of pixels stacked for this user
|
||||
undoExpires DateTime? // when the undo for the most recent pixel expires at
|
||||
|
||||
|
|
|
@ -430,11 +430,6 @@ class Canvas {
|
|||
},
|
||||
});
|
||||
|
||||
await prisma.user.update({
|
||||
where: { sub: user.sub },
|
||||
data: { lastPixelTime: new Date() },
|
||||
});
|
||||
|
||||
// maybe only update specific element?
|
||||
// i don't think it needs to be awaited
|
||||
await this.updateCanvasRedisAtPos(x, y);
|
||||
|
|
|
@ -63,7 +63,7 @@ prisma.paletteColor
|
|||
Logger.error("Failed to get pallete colors", e);
|
||||
});
|
||||
|
||||
const getClientConfig = (): ClientConfig => {
|
||||
export const getClientConfig = (): ClientConfig => {
|
||||
return {
|
||||
version: commitHash,
|
||||
pallete: {
|
||||
|
@ -122,12 +122,9 @@ export class SocketServer {
|
|||
continue;
|
||||
}
|
||||
|
||||
// time in seconds since last pixel placement
|
||||
// TODO: this causes a mismatch between placement times
|
||||
// - going from 0 stack to 6 stack has a steady increase between each
|
||||
// - going from 3 stack to 6 stack takes longer
|
||||
// time in seconds since last stack gain (including a potential bonus depending on previously remaining time)
|
||||
const timeSinceLastPlace =
|
||||
(Date.now() - user.lastPixelTime.getTime()) / 1000;
|
||||
(Date.now() - user.lastTimeGainStarted.getTime()) / 1000;
|
||||
const cooldown = CanvasLib.getPixelCooldown(
|
||||
user.pixelStack + 1,
|
||||
getClientConfig()
|
||||
|
@ -180,7 +177,7 @@ export class SocketServer {
|
|||
|
||||
if (user) {
|
||||
socket.emit("availablePixels", user.pixelStack);
|
||||
socket.emit("pixelLastPlaced", user.lastPixelTime.getTime());
|
||||
socket.emit("pixelLastPlaced", user.lastTimeGainStarted.getTime());
|
||||
|
||||
const ban = user.getBan();
|
||||
socket.emit(
|
||||
|
|
|
@ -10,7 +10,8 @@ import {
|
|||
import { Ban, User as UserDB } from "@prisma/client";
|
||||
import { Instance } from "./Instance";
|
||||
import { ConditionalPromise } from "../lib/utils";
|
||||
|
||||
import { CanvasLib } from "@sc07-canvas/lib/src/canvas";
|
||||
import { getClientConfig } from "../lib/SocketServer";
|
||||
const Logger = getLogger();
|
||||
|
||||
/**
|
||||
|
@ -37,7 +38,7 @@ export class User {
|
|||
static instances: Map<string, User> = new Map();
|
||||
|
||||
sub: string;
|
||||
lastPixelTime: Date;
|
||||
lastTimeGainStarted: Date;
|
||||
pixelStack: number;
|
||||
authSession?: AuthSession;
|
||||
undoExpires?: Date;
|
||||
|
@ -54,7 +55,7 @@ export class User {
|
|||
Logger.debug("User class instansiated for " + data.sub);
|
||||
|
||||
this.sub = data.sub;
|
||||
this.lastPixelTime = data.lastPixelTime;
|
||||
this.lastTimeGainStarted = data.lastTimeGainStarted;
|
||||
this.pixelStack = data.pixelStack;
|
||||
this.undoExpires = data.undoExpires || undefined;
|
||||
|
||||
|
@ -80,7 +81,7 @@ export class User {
|
|||
|
||||
if (!userData) throw new UserNotFound();
|
||||
|
||||
this.lastPixelTime = userData.lastPixelTime;
|
||||
this.lastTimeGainStarted = userData.lastTimeGainStarted;
|
||||
this.pixelStack = userData.pixelStack;
|
||||
this.undoExpires = userData.undoExpires || undefined;
|
||||
this.isAdmin = userData.isAdmin;
|
||||
|
@ -120,15 +121,53 @@ export class User {
|
|||
}
|
||||
|
||||
async modifyStack(modifyBy: number): Promise<any> {
|
||||
let new_date = new Date();
|
||||
if (modifyBy > 0) {
|
||||
let cooldown_to_add = 0.0;
|
||||
for (let i = 0; i < modifyBy; i++) {
|
||||
cooldown_to_add += CanvasLib.getPixelCooldown(
|
||||
this.pixelStack + i + 1,
|
||||
getClientConfig()
|
||||
);
|
||||
}
|
||||
|
||||
new_date = new Date(
|
||||
this.lastTimeGainStarted.valueOf() + cooldown_to_add * 1000
|
||||
);
|
||||
} else if (modifyBy < 0) {
|
||||
const cooldown_before_change_s = CanvasLib.getPixelCooldown(
|
||||
this.pixelStack + 1,
|
||||
getClientConfig()
|
||||
);
|
||||
const cooldown_after_change_s = CanvasLib.getPixelCooldown(
|
||||
this.pixelStack + 1 + modifyBy,
|
||||
getClientConfig()
|
||||
);
|
||||
const would_gain_next_at_timestamp_ms =
|
||||
this.lastTimeGainStarted.valueOf() + cooldown_before_change_s * 1000;
|
||||
const time_before_next =
|
||||
would_gain_next_at_timestamp_ms - Date.now().valueOf();
|
||||
// To avoid issue if a negative value is present for some reason
|
||||
if (time_before_next > 0) {
|
||||
if (time_before_next < cooldown_after_change_s * 1000) {
|
||||
new_date = new Date(
|
||||
Date.now() - cooldown_after_change_s * 1000 + time_before_next
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updatedUser = await prisma.user.update({
|
||||
where: { sub: this.sub },
|
||||
data: {
|
||||
pixelStack: { increment: modifyBy },
|
||||
lastTimeGainStarted: new_date,
|
||||
},
|
||||
});
|
||||
|
||||
for (const socket of this.sockets) {
|
||||
socket.emit("availablePixels", updatedUser.pixelStack);
|
||||
socket.emit("pixelLastPlaced", updatedUser.lastTimeGainStarted.getTime());
|
||||
}
|
||||
|
||||
// we just modified the user data, so we should force an update
|
||||
|
|
Loading…
Reference in New Issue