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.lastPlace = Date.now();
this.handlePixel(ack.data); this.handlePixel(ack.data);
} else { } else {
// TODO: handle undo pixel
toast.info(ack.error);
console.warn( console.warn(
"Attempted to place pixel", "Attempted to place pixel",
{ x, y, color: this.Pallete.getSelectedColor()!.id }, { x, y, color: this.Pallete.getSelectedColor()!.id },
"and got error", "and got error",
ack 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: ( ack: (
_: PacketAck< _: PacketAck<
Pixel, 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
) => void; ) => void;

View File

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

View File

@ -229,6 +229,17 @@ export class SocketServer {
return; 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 user.modifyStack(-1);
await Canvas.setPixel(user, pixel.x, pixel.y, paletteColor.hex); await Canvas.setPixel(user, pixel.x, pixel.y, paletteColor.hex);
// give undo capabilities // give undo capabilities