diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
index 630f9c6..e85e2f0 100644
--- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
+++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
@@ -39,10 +39,6 @@ public class ProgressiaLauncher {
GUI.addTopLayer(new LayerTitle("Title"));
}
- public static void play() {
- proxy.setupServer();
- }
-
private static void setupCrashReports() {
// Context providers
CrashReports.registerProvider(new OSContextProvider());
diff --git a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
index ffb9bd7..ac9d61f 100644
--- a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
+++ b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
@@ -30,7 +30,6 @@ import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
-import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.TestContent;
import ru.windcorp.progressia.test.TestMusicPlayer;
@@ -62,10 +61,4 @@ public class ClientProxy implements Proxy {
TestMusicPlayer.start();
}
-
- public void setupServer() {
- ServerState.startServer();
- ClientState.connectToLocalServer();
- }
-
}
diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
index a7184e9..5e94784 100644
--- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
+++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
@@ -15,21 +15,21 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.server;
+import glm.vec._3.Vec3;
+import ru.windcorp.progressia.common.world.entity.EntityData;
+import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
+import ru.windcorp.progressia.server.comms.ClientPlayer;
+import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
+import ru.windcorp.progressia.server.events.PlayerLeftEvent;
+import ru.windcorp.progressia.test.TestContent;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import glm.vec._3.Vec3;
-import ru.windcorp.progressia.common.util.crash.CrashReports;
-import ru.windcorp.progressia.common.world.entity.EntityData;
-import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
-import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
-import ru.windcorp.progressia.server.events.PlayerLeftEvent;
-import ru.windcorp.progressia.test.TestContent;
-
public class PlayerManager {
private final Server server;
@@ -48,36 +48,38 @@ public class PlayerManager {
this.players.add(player);
getServer().postEvent(new PlayerJoinedEvent.Immutable(getServer(), player));
}
-
+
public void removePlayer(Player player) {
+ server.getWorld().getContainer().savePlayer(player, server);
this.players.remove(player);
getServer().postEvent(new PlayerLeftEvent.Immutable(getServer(), player));
}
- public EntityData conjurePlayerEntity(String login) {
- // TODO Live up to the name
- if (TestContent.PLAYER_LOGIN.equals(login)) {
- EntityData entity = spawnPlayerEntity(login);
- return entity;
- } else {
- throw CrashReports.report(null, "Unknown login %s, javahorse stupid", login);
+ public Player conjurePlayer(ClientPlayer clientPlayer, String login) {
+
+ Player player = getServer().getWorld().getContainer().loadPlayer(login, clientPlayer, getServer());
+ if (player == null) { // create new player
+ EntityData entity = spawnPlayerEntity(clientPlayer, login);
+ player = new Player(entity, getServer(), clientPlayer);
}
+
+ getServer().getWorld().getData().addEntity(player.getEntity());
+
+ return player;
}
- private EntityData spawnPlayerEntity(String login) {
+ private EntityData spawnPlayerEntity(ClientPlayer clientPlayer, String login) {
EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
player.setEntityId(TestContent.PLAYER_ENTITY_ID);
player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation());
-
+
player.setUpVector(new Vec3(0, 0, 1));
player.setLookingAt(new Vec3(2, 1, 0));
- getServer().getWorld().getData().addEntity(player);
-
return player;
}
-
+
public Object getMutex() {
return players;
}
diff --git a/src/main/java/ru/windcorp/progressia/server/ServerState.java b/src/main/java/ru/windcorp/progressia/server/ServerState.java
index c38f21b..79844cb 100644
--- a/src/main/java/ru/windcorp/progressia/server/ServerState.java
+++ b/src/main/java/ru/windcorp/progressia/server/ServerState.java
@@ -18,6 +18,7 @@
package ru.windcorp.progressia.server;
+import java.io.IOException;
import java.nio.file.Paths;
import java.util.function.Function;
@@ -39,7 +40,7 @@ public class ServerState {
ServerState.instance = instance;
}
- public static void startServer() {
+ public static void startServer() throws IOException {
Function generator = new TestGenerationConfig().getGenerator();
WorldContainer container = new RegionFormat("Test:Region").create(Paths.get("tmp_world"));
diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java
index fc55cbb..095c403 100644
--- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java
+++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java
@@ -80,12 +80,11 @@ public class ClientManager {
setGravityModelPacket.set(getServer().getWorld().getData().getGravityModel());
client.sendPacket(setGravityModelPacket);
- EntityData entity = getServer().getPlayerManager().conjurePlayerEntity(login);
- Player player = new Player(entity, getServer(), client);
+ Player player = getServer().getPlayerManager().conjurePlayer(client, login);
getServer().getPlayerManager().addPlayer(player);
PacketSetLocalPlayer packet = new PacketSetLocalPlayer();
- packet.set(entity.getEntityId());
+ packet.set(player.getEntity().getEntityId());
client.sendPacket(packet);
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainer.java b/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainer.java
index 07aa7b5..42451ad 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainer.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainer.java
@@ -17,21 +17,27 @@
*/
package ru.windcorp.progressia.server.world.io;
-import java.nio.file.Path;
-
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.DefaultWorldData;
+import ru.windcorp.progressia.server.Player;
import ru.windcorp.progressia.server.Server;
+import ru.windcorp.progressia.server.comms.ClientPlayer;
+
+import java.nio.file.Path;
public interface WorldContainer {
-
+
Path getPath();
-
+
DefaultChunkData load(Vec3i position, DefaultWorldData world, Server server);
-
+
void save(DefaultChunkData chunk, DefaultWorldData world, Server server);
-
+
+ Player loadPlayer(String login, ClientPlayer clientPlayer, Server server);
+
+ void savePlayer(Player player, Server server);
+
void close();
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainerFormat.java b/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainerFormat.java
index 9c8e0c8..4c89621 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainerFormat.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/io/WorldContainerFormat.java
@@ -17,6 +17,7 @@
*/
package ru.windcorp.progressia.server.world.io;
+import java.io.IOException;
import java.nio.file.Path;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
@@ -27,6 +28,6 @@ public abstract class WorldContainerFormat extends Namespaced {
super(id);
}
- public abstract WorldContainer create(Path directory);
+ public abstract WorldContainer create(Path directory) throws IOException;
}
diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTitle.java b/src/main/java/ru/windcorp/progressia/test/LayerTitle.java
index d2ba139..e497252 100644
--- a/src/main/java/ru/windcorp/progressia/test/LayerTitle.java
+++ b/src/main/java/ru/windcorp/progressia/test/LayerTitle.java
@@ -1,15 +1,20 @@
package ru.windcorp.progressia.test;
-import ru.windcorp.progressia.ProgressiaLauncher;
+import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.graphics.Colors;
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.font.Font;
+import ru.windcorp.progressia.client.graphics.gui.BasicButton;
import ru.windcorp.progressia.client.graphics.gui.Button;
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
import ru.windcorp.progressia.client.graphics.gui.Label;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
import ru.windcorp.progressia.client.localization.MutableString;
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
+import ru.windcorp.progressia.common.util.crash.CrashReports;
+import ru.windcorp.progressia.server.ServerState;
+
+import java.io.IOException;
public class LayerTitle extends GUILayer {
@@ -22,11 +27,7 @@ public class LayerTitle extends GUILayer {
Font buttonFont = titleFont;
MutableString playText = new MutableStringLocalized("Layer" + name + ".Play");
- getRoot().addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(b -> {
- GUI.removeLayer(this);
-
- ProgressiaLauncher.play();
- }));
+ getRoot().addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
getRoot().addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> {
@@ -34,4 +35,14 @@ public class LayerTitle extends GUILayer {
}));
}
+ private void startGame(BasicButton basicButton) {
+ GUI.removeLayer(this);
+ try {
+ ServerState.startServer();
+ ClientState.connectToLocalServer();
+ } catch (IOException e) {
+ throw CrashReports.report(e, "Problem with loading server");
+ }
+ }
+
}
diff --git a/src/main/java/ru/windcorp/progressia/test/region/RegionFormat.java b/src/main/java/ru/windcorp/progressia/test/region/RegionFormat.java
index 85d1bbe..ad67074 100644
--- a/src/main/java/ru/windcorp/progressia/test/region/RegionFormat.java
+++ b/src/main/java/ru/windcorp/progressia/test/region/RegionFormat.java
@@ -17,6 +17,7 @@
*/
package ru.windcorp.progressia.test.region;
+import java.io.IOException;
import java.nio.file.Path;
import ru.windcorp.progressia.server.world.io.WorldContainer;
@@ -29,7 +30,7 @@ public class RegionFormat extends WorldContainerFormat {
}
@Override
- public WorldContainer create(Path directory) {
+ public WorldContainer create(Path directory) throws IOException {
return new TestWorldDiskIO(directory);
}
diff --git a/src/main/java/ru/windcorp/progressia/test/region/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/region/TestWorldDiskIO.java
index f8b015f..2bc3f50 100644
--- a/src/main/java/ru/windcorp/progressia/test/region/TestWorldDiskIO.java
+++ b/src/main/java/ru/windcorp/progressia/test/region/TestWorldDiskIO.java
@@ -18,31 +18,37 @@
package ru.windcorp.progressia.test.region;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.file.Files;
-import java.nio.file.Path;
+import glm.vec._3.i.Vec3i;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-
-import glm.vec._3.i.Vec3i;
+import ru.windcorp.progressia.common.state.IOContext;
import ru.windcorp.progressia.common.util.crash.CrashReports;
-import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.Coordinates;
import ru.windcorp.progressia.common.world.DecodingException;
+import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.DefaultWorldData;
+import ru.windcorp.progressia.common.world.entity.EntityData;
+import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
import ru.windcorp.progressia.common.world.generic.ChunkMap;
import ru.windcorp.progressia.common.world.generic.ChunkMaps;
+import ru.windcorp.progressia.server.Player;
import ru.windcorp.progressia.server.Server;
+import ru.windcorp.progressia.server.comms.ClientPlayer;
import ru.windcorp.progressia.server.world.io.WorldContainer;
+import ru.windcorp.progressia.test.TestContent;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
public class TestWorldDiskIO implements WorldContainer {
private static final boolean ENABLE = true;
- private static final String FILE_NAME_FORMAT = "region_%d_%d_%d.progressia_region";
+ private static final String REGION_FOLDER_NAME = "regions";
+ private static final String PLAYERS_FOLDER_NAME = "players";
+ private static final String REGION_NAME_FORMAT = REGION_FOLDER_NAME + "/" + "region_%d_%d_%d.progressia_region";
+ private static final String PLAYER_NAME_FORMAT = PLAYERS_FOLDER_NAME + "/" + "%s.progressia_player";
private static final int BITS_IN_CHUNK_COORDS = 4;
public static final int REGION_DIAMETER = 1 << BITS_IN_CHUNK_COORDS;
@@ -60,8 +66,12 @@ public class TestWorldDiskIO implements WorldContainer {
private final Path path;
private final ChunkMap regions = ChunkMaps.newHashMap();
- public TestWorldDiskIO(Path path) {
+ public TestWorldDiskIO(Path path) throws IOException {
this.path = path;
+
+ Files.createDirectories(getPath());
+ Files.createDirectories(getPath().resolve(REGION_FOLDER_NAME));
+ Files.createDirectories(getPath().resolve(PLAYERS_FOLDER_NAME));
}
@Override
@@ -104,11 +114,53 @@ public class TestWorldDiskIO implements WorldContainer {
}
}
- private Region getRegion(Vec3i position, boolean createIfMissing) throws IOException {
- if (regions.isEmpty()) {
- Files.createDirectories(getPath());
+ @Override
+ public Player loadPlayer(String login, ClientPlayer clientPlayer, Server server) {
+
+ Path path = getPlayerPath(login);
+ if (!Files.exists(path)) {
+ LOG.debug("Could not load player {} because file {} does not exist", login, path);
+ return null;
}
+ EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
+ try (
+ DataInputStream dataInputStream = new DataInputStream(
+ new BufferedInputStream(
+ Files.newInputStream(
+ getPlayerPath(login)
+ )
+ )
+ )
+ ) {
+ player.read(dataInputStream, IOContext.SAVE);
+ player.setEntityId(TestContent.PLAYER_ENTITY_ID);
+ return new Player(player, server, clientPlayer);
+ } catch (IOException ioException) {
+ throw CrashReports.report(ioException, "Could not load player data: " + login);
+ }
+ }
+
+ @Override
+ public void savePlayer(Player player, Server server) {
+ Path path = getPlayerPath(player.getLogin());
+ try (
+ DataOutputStream dataOutputStream = new DataOutputStream(
+ new BufferedOutputStream(
+ Files.newOutputStream(path)
+ )
+ )
+ ) {
+ player.getEntity().
+
+ write(dataOutputStream, IOContext.SAVE);
+ } catch (IOException ioException) {
+ throw CrashReports.report(ioException, "Could not save player %s data in file ", player.getLogin(), path);
+ }
+ }
+
+ private Region getRegion(Vec3i position, boolean createIfMissing) throws IOException {
+
Vec3i regionCoords = getRegionCoords(position);
Region region = regions.get(regionCoords);
@@ -151,11 +203,11 @@ public class TestWorldDiskIO implements WorldContainer {
public Path getPath() {
return path;
}
-
+
private Path getRegionPath(Vec3i regionPos) {
return getPath().resolve(
String.format(
- FILE_NAME_FORMAT,
+ REGION_NAME_FORMAT,
regionPos.x,
regionPos.y,
regionPos.z
@@ -163,6 +215,15 @@ public class TestWorldDiskIO implements WorldContainer {
);
}
+ private Path getPlayerPath(String login) {
+ return getPath().resolve(
+ String.format(
+ PLAYER_NAME_FORMAT,
+ login
+ )
+ );
+ }
+
@Override
public void close() {
try {
@@ -170,16 +231,16 @@ public class TestWorldDiskIO implements WorldContainer {
region.close();
}
} catch (IOException e) {
- CrashReports.report(e, "Could not close region files");
+ throw CrashReports.report(e, "Could not close region files");
}
}
-
+
private static void debug(String message, Vec3i vector) {
if (LOG.isDebugEnabled()) {
LOG.debug(message, vector.x, vector.y, vector.z);
}
}
-
+
private static void warn(String message, Vec3i vector) {
LOG.warn(message, vector.x, vector.y, vector.z);
}