Skip to content

Commit

Permalink
feat: save painter's data
Browse files Browse the repository at this point in the history
  • Loading branch information
hamusuke0323 committed Jun 20, 2023
1 parent dcda323 commit e543d75
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 10 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ repositories {
}

dependencies {
implementation 'io.netty:netty-all:4.1.84.Final'
implementation 'io.netty:netty-all:4.1.86.Final'
implementation 'com.google.guava:guava:31.1-jre'
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'it.unimi.dsi:fastutil:8.5.9'
implementation 'com.mojang:brigadier:1.0.18'
implementation 'com.google.code.gson:gson:2.10.1'
}

jar {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/hamusuke/paint/server/PaintServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ private synchronized void loadAll() {
for (File file : files) {
ServerCanvas serverCanvas = null;
try {
serverCanvas = ServerCanvas.load(file);
serverCanvas = ServerCanvas.load(this, file);
} catch (Throwable e) {
LOGGER.warn("Error occurred while loading a canvas", e);
}
Expand Down Expand Up @@ -175,7 +175,7 @@ public ServerCanvas getCanvas(int id) {
}

public void createCanvas(String title, UUID author, int w, int h) {
ServerCanvas serverCanvas = new ServerCanvas(Util.avoidDuplicatingDirectoryName(this.saves, title), UUID.randomUUID(), title, author, w, h);
ServerCanvas serverCanvas = new ServerCanvas(this, Util.avoidDuplicatingDirectoryName(this.saves, title), UUID.randomUUID(), title, author, w, h);
this.serverCanvases.add(serverCanvas);
serverCanvas.save();
this.getPainterManager().sendPacketToAllInLobby(new CanvasInfoResponseS2CPacket(Collections.singletonList(serverCanvas.getInfo())));
Expand Down
68 changes: 61 additions & 7 deletions src/main/java/com/hamusuke/paint/server/canvas/ServerCanvas.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
package com.hamusuke.paint.server.canvas;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import com.hamusuke.paint.canvas.Canvas;
import com.hamusuke.paint.canvas.CanvasInfo;
import com.hamusuke.paint.network.LineData;
import com.hamusuke.paint.server.PaintServer;
import com.hamusuke.paint.server.network.ServerPainter;
import com.hamusuke.paint.server.network.ServerPainterData;
import com.hamusuke.paint.util.ConcurrentFixedDeque;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.*;
import java.nio.file.Files;
import java.util.Deque;
import java.util.UUID;

public class ServerCanvas extends Canvas {
private static final Logger LOGGER = LogManager.getLogger();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private final PaintServer server;
private final File saveDir;
private final File playerSaveDir;
private final Deque<BufferedImage> historic = new ConcurrentFixedDeque<>(10);

public ServerCanvas(File saveDir, UUID uuid, String title, UUID author, int width, int height) {
public ServerCanvas(PaintServer server, File saveDir, UUID uuid, String title, UUID author, int width, int height) {
super(uuid, title, author, width, height);
this.server = server;
this.saveDir = saveDir;
if (!this.saveDir.exists()) {
if (!this.saveDir.isDirectory() || !this.saveDir.exists()) {
this.saveDir.mkdir();
}

this.playerSaveDir = this.saveDir.toPath().resolve("players").toFile();
if (!this.playerSaveDir.isDirectory() || !this.playerSaveDir.exists()) {
this.playerSaveDir.mkdir();
}
}

@Nullable
public static ServerCanvas load(File saveDir) throws Throwable {
public static ServerCanvas load(PaintServer server, File saveDir) throws Throwable {
File[] files = saveDir.listFiles(File::isFile);
if (files != null) {
CanvasInfo info = null;
Expand All @@ -47,7 +61,7 @@ public static ServerCanvas load(File saveDir) throws Throwable {
}

if (info != null && data != null) {
ServerCanvas serverCanvas = new ServerCanvas(saveDir, info.getCanvasUUID(), info.getTitle(), info.getAuthor(), info.getWidth(), info.getHeight());
ServerCanvas serverCanvas = new ServerCanvas(server, saveDir, info.getCanvasUUID(), info.getTitle(), info.getAuthor(), info.getWidth(), info.getHeight());
serverCanvas.setData(data);
return serverCanvas;
}
Expand Down Expand Up @@ -80,5 +94,45 @@ public synchronized void save() {
} catch (Exception e) {
LOGGER.warn("Error occurred while saving the canvas", e);
}

this.savePlayers();
}

private synchronized void savePlayers() {
if (!this.playerSaveDir.exists()) {
this.playerSaveDir.mkdir();
}

this.server.getPainterManager().getPainters().stream().filter(painter -> painter.isInCanvas(this)).forEach(this::savePainter);
}

public void savePainter(ServerPainter painter) {
File data = this.createPlayerDataFile(painter);
try (FileWriter writer = new FileWriter(data)) {
GSON.toJson(painter.serialize(), writer);
} catch (Exception e) {
LOGGER.warn("Error occurred while saving players", e);
}
}

public void loadPainter(ServerPainter painter) {
File data = this.createPlayerDataFile(painter);

if (!data.exists()) {
return;
}

try (FileReader fileReader = new FileReader(data)) {
ServerPainterData painterData = GSON.fromJson(fileReader, ServerPainterData.class);
if (painterData != null) {
painter.deserialize(painterData);
}
} catch (Exception e) {
LOGGER.warn("Error occurred while loading painter data", e);
}
}

private File createPlayerDataFile(ServerPainter painter) {
return this.playerSaveDir.toPath().resolve(painter.getUuid().toString() + ".json").toFile();
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/hamusuke/paint/server/network/ServerPainter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.hamusuke.paint.network.Painter;
import com.hamusuke.paint.network.protocol.packet.Packet;
import com.hamusuke.paint.network.protocol.packet.s2c.main.ChangeColorS2CPacket;
import com.hamusuke.paint.network.protocol.packet.s2c.main.ChangeWidthS2CPacket;
import com.hamusuke.paint.server.PaintServer;
import com.hamusuke.paint.server.canvas.ServerCanvas;
import com.hamusuke.paint.server.network.main.ServerCommonPacketListenerImpl;
Expand Down Expand Up @@ -52,4 +54,19 @@ public void sendPacketToOthers(Packet<?> packet, GenericFutureListener<? extends
public void sendPacketToAllInCanvas(Packet<?> packet) {
this.server.getPainterManager().sendPacketToAllInCanvas(this, packet);
}

public ServerPainterData serialize() {
return new ServerPainterData(this.getColor(), this.getWidth());
}

public void deserialize(ServerPainterData data) {
this.setColor(data.getColor());
this.setWidth(data.getWidth());
this.syncPainterData();
}

private void syncPainterData() {
this.server.sendPacketToAll(new ChangeColorS2CPacket(this));
this.server.sendPacketToAll(new ChangeWidthS2CPacket(this));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.hamusuke.paint.server.network;

import java.awt.*;

public class ServerPainterData {
private final int color;
private final float width;

public ServerPainterData(Color color, float width) {
this.color = color.getRGB();
this.width = width;
}

public Color getColor() {
return new Color(this.color, true);
}

public float getWidth() {
return this.width <= 0.0F ? 5.0F : this.width;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,15 @@ public void handleChangeWidthPacket(ChangeWidthC2SPacket packet) {

@Override
public void handleLeaveCanvasPacket(LeaveCanvasC2SPacket packet) {
ServerCanvas curCanvas = this.painter.getCurrentCanvas();

this.painter.joinCanvas(null);
new ServerLobbyPacketListenerImpl(this.server, this.connection, this.painter);

if (curCanvas != null) {
curCanvas.savePainter(this.painter);
}

this.server.sendPacketToAll(new LeaveCanvasS2CPacket(this.painter));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.hamusuke.paint.network.protocol.packet.s2c.main.PongS2CPacket;
import com.hamusuke.paint.network.protocol.packet.s2c.main.RTTS2CPacket;
import com.hamusuke.paint.server.PaintServer;
import com.hamusuke.paint.server.canvas.ServerCanvas;
import com.hamusuke.paint.server.network.ServerPainter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -53,6 +54,12 @@ public void handleRTTPacket(RTTC2SPacket packet) {
@Override
public void onDisconnected() {
LOGGER.info("{} lost connection", this.connection.getAddress());

ServerCanvas curCanvas = this.painter.getCurrentCanvas();
if (curCanvas != null) {
curCanvas.savePainter(this.painter);
}

this.painter.sendPacketToOthers(new LeavePainterS2CPacket(this.painter.getId()));
this.server.getPainterManager().removePainter(this.painter);
if (this.server.isLocal()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public void handleJoinCanvas(JoinCanvasC2SPacket packet) {
this.painter.joinCanvas(canvas);
new ServerCanvasPacketListenerImpl(this.server, this.connection, this.painter, canvas);
this.server.sendPacketToAll(new JoinCanvasS2CPacket(this.painter, canvas.getInfo()));

canvas.loadPainter(this.painter);
} else {
this.connection.sendPacket(new DisconnectS2CPacket(), future -> this.connection.disconnect());
}
Expand Down

0 comments on commit e543d75

Please sign in to comment.