prevent same color & same user pixels to be placed on top of each other (fixes #19)

This commit is contained in:
Grant 2024-06-04 16:02:14 -06:00
parent aed4ac497f
commit ced4bdc2d1
4 changed files with 52 additions and 24 deletions

View File

@ -237,14 +237,34 @@ export class Canvas extends EventEmitter<CanvasEvents> {
this.lastPlace = Date.now();
this.handlePixel(ack.data);
} else {
// TODO: handle undo pixel
toast.info(ack.error);
console.warn(
"Attempted to place pixel",
{ x, y, color: this.Pallete.getSelectedColor()!.id },
"and got error",
ack
);
switch (ack.error) {
case "invalid_pixel":
toast.error(
"Cannot place, invalid pixel location. Are you even on the canvas?"
);
break;
case "no_user":
toast.error("You are not logged in.");
break;
case "palette_color_invalid":
toast.error("This isn't a color that you can use...?");
break;
case "pixel_cooldown":
toast.error("You're on pixel cooldown, cannot place");
break;
case "you_already_placed_that":
toast.error("You already placed this color at this location");
break;
default:
toast.error("Error while placing pixel: " + ack.error);
}
}
});
}

View File

@ -19,7 +19,11 @@ export interface ClientToServerEvents {
ack: (
_: PacketAck<
Pixel,
"no_user" | "invalid_pixel" | "pixel_cooldown" | "palette_color_invalid"
| "no_user"
| "invalid_pixel"
| "pixel_cooldown"
| "palette_color_invalid"
| "you_already_placed_that"
>
) => void
) => void;

View File

@ -82,17 +82,7 @@ class Canvas {
for (let x = 0; x < this.canvasSize[0]; x++) {
for (let y = 0; y < this.canvasSize[1]; y++) {
const pixel = await prisma.pixel.findFirst({
where: {
x,
y,
},
orderBy: [
{
createdAt: "asc",
},
],
});
const pixel = await this.getPixel(x, y);
await redis.set(key(x, y), pixel?.color || "transparent");
}
@ -152,12 +142,18 @@ class Canvas {
}
async getPixel(x: number, y: number) {
return await prisma.pixel.findFirst({
where: {
x,
y,
},
});
return (
await prisma.pixel.findMany({
where: {
x,
y,
},
orderBy: {
createdAt: "desc",
},
take: 1,
})
)?.[0];
}
async setPixel(user: { sub: string }, x: number, y: number, hex: string) {
@ -194,10 +190,7 @@ class Canvas {
const key = Redis.key("pixelColor", x, y);
// find if any pixels exist at this spot, and pick the most recent one
const pixel = await prisma.pixel.findFirst({
where: { x, y },
orderBy: { createdAt: "desc" },
});
const pixel = await this.getPixel(x, y);
let paletteColorID = -1;
// if pixel exists in redis

View File

@ -229,6 +229,17 @@ export class SocketServer {
return;
}
const pixelAtTheSameLocation = await Canvas.getPixel(pixel.x, pixel.y);
if (
pixelAtTheSameLocation &&
pixelAtTheSameLocation.userId === user.sub &&
pixelAtTheSameLocation.color === paletteColor.hex
) {
ack({ success: false, error: "you_already_placed_that" });
return;
}
await user.modifyStack(-1);
await Canvas.setPixel(user, pixel.x, pixel.y, paletteColor.hex);
// give undo capabilities