diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
index c8935fc..630f9c6 100644
--- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
+++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
@@ -15,21 +15,32 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia;
+import ru.windcorp.progressia.client.ClientProxy;
+import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
import ru.windcorp.progressia.common.util.crash.providers.*;
+import ru.windcorp.progressia.test.LayerTitle;
public class ProgressiaLauncher {
public static String[] arguments;
+ private static ClientProxy proxy;
- public static void launch(String[] args, Proxy proxy) {
+ public static void launch(String[] args, ClientProxy inProxy) {
arguments = args.clone();
setupCrashReports();
- proxy.initialize();
+
+ inProxy.initialize();
+ proxy = inProxy;
+ GUI.addTopLayer(new LayerTitle("Title"));
+ }
+
+ public static void play() {
+ proxy.setupServer();
}
private static void setupCrashReports() {
diff --git a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
index 1d154e7..ffb9bd7 100644
--- a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
+++ b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.Proxy;
@@ -38,7 +38,9 @@ public class ClientProxy implements Proxy {
@Override
public void initialize() {
+
GraphicsBackend.initialize();
+
try {
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
@@ -58,10 +60,12 @@ public class ClientProxy implements Proxy {
AudioSystem.initialize();
- ServerState.startServer();
- ClientState.connectToLocalServer();
-
TestMusicPlayer.start();
}
+ public void setupServer() {
+ ServerState.startServer();
+ ClientState.connectToLocalServer();
+ }
+
}
diff --git a/src/main/java/ru/windcorp/progressia/client/ClientState.java b/src/main/java/ru/windcorp/progressia/client/ClientState.java
index 31c366e..f473eb4 100644
--- a/src/main/java/ru/windcorp/progressia/client/ClientState.java
+++ b/src/main/java/ru/windcorp/progressia/client/ClientState.java
@@ -15,15 +15,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
import ru.windcorp.progressia.client.graphics.GUI;
+import ru.windcorp.progressia.client.graphics.Layer;
import ru.windcorp.progressia.client.graphics.world.LayerWorld;
import ru.windcorp.progressia.common.world.DefaultWorldData;
+import ru.windcorp.progressia.client.localization.MutableStringLocalized;
import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.LayerAbout;
+import ru.windcorp.progressia.test.LayerTestText;
import ru.windcorp.progressia.test.LayerTestUI;
import ru.windcorp.progressia.test.TestContent;
@@ -52,11 +55,39 @@ public class ClientState {
channel.connect(TestContent.PLAYER_LOGIN);
setInstance(client);
+ displayLoadingScreen();
- GUI.addBottomLayer(new LayerWorld(client));
- GUI.addTopLayer(new LayerTestUI());
- GUI.addTopLayer(new LayerAbout());
+ }
+ private static void displayLoadingScreen() {
+ GUI.addTopLayer(new LayerTestText("Text", new MutableStringLocalized("LayerText.Load"), layer -> {
+ Client client = ClientState.getInstance();
+
+ // TODO refacetor and remove
+ if (client != null) {
+ client.getComms().processPackets();
+ }
+
+ if (client != null && client.getLocalPlayer().hasEntity()) {
+ GUI.removeLayer(layer);
+
+ // TODO refactor, this shouldn't be here
+ LayerWorld layerWorld = new LayerWorld(client);
+ LayerTestUI layerUI = new LayerTestUI();
+ LayerAbout layerAbout = new LayerAbout();
+ GUI.addBottomLayer(layerWorld);
+ GUI.addTopLayer(layerUI);
+ GUI.addTopLayer(layerAbout);
+ }
+ }));
+ }
+
+ public static void disconnectFromLocalServer() {
+ getInstance().getComms().disconnect();
+
+ for (Layer layer : GUI.getLayers()) {
+ GUI.removeLayer(layer);
+ }
}
private ClientState() {
diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java
index 816fba8..9fc0e47 100644
--- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java
+++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.client.comms.localhost;
import java.io.IOException;
diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java
index 194a2a1..fcf8dd0 100644
--- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java
+++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java
@@ -15,12 +15,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.client.comms.localhost;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.server.Server;
+import ru.windcorp.progressia.server.ServerState;
public class LocalServerCommsChannel extends ServerCommsChannel {
@@ -54,7 +55,7 @@ public class LocalServerCommsChannel extends ServerCommsChannel {
@Override
public void disconnect() {
- // Do nothing
+ ServerState.getInstance().getClientManager().disconnectClient(localClient);
}
}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java b/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java
index bb4d85b..59b89da 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java
@@ -15,12 +15,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.client.graphics;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import com.google.common.eventbus.Subscribe;
@@ -58,6 +59,7 @@ public class GUI {
}
public static void addBottomLayer(Layer layer) {
+ Objects.requireNonNull(layer, "layer");
modify(layers -> {
layers.add(layer);
layer.onAdded();
@@ -65,6 +67,7 @@ public class GUI {
}
public static void addTopLayer(Layer layer) {
+ Objects.requireNonNull(layer, "layer");
modify(layers -> {
layers.add(0, layer);
layer.onAdded();
@@ -72,6 +75,7 @@ public class GUI {
}
public static void removeLayer(Layer layer) {
+ Objects.requireNonNull(layer, "layer");
modify(layers -> {
layers.remove(layer);
layer.onRemoved();
@@ -88,33 +92,33 @@ public class GUI {
public static void render() {
synchronized (LAYERS) {
-
+
if (!MODIFICATION_QUEUE.isEmpty()) {
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
MODIFICATION_QUEUE.clear();
-
+
boolean isMouseCurrentlyCaptured = GraphicsInterface.isMouseCaptured();
Layer.CursorPolicy policy = Layer.CursorPolicy.REQUIRE;
-
+
for (Layer layer : LAYERS) {
Layer.CursorPolicy currentPolicy = layer.getCursorPolicy();
-
+
if (currentPolicy != Layer.CursorPolicy.INDIFFERENT) {
policy = currentPolicy;
break;
}
}
-
+
boolean shouldCaptureMouse = (policy == Layer.CursorPolicy.FORBID);
if (shouldCaptureMouse != isMouseCurrentlyCaptured) {
GraphicsInterface.setMouseCaptured(shouldCaptureMouse);
}
}
-
+
for (int i = LAYERS.size() - 1; i >= 0; --i) {
LAYERS.get(i).render();
}
-
+
}
}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/BasicButton.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/BasicButton.java
index cd30152..14c0e36 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/BasicButton.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/BasicButton.java
@@ -37,15 +37,15 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
public abstract class BasicButton extends Component {
-
+
private final Label label;
private boolean isPressed = false;
private final Collection> actions = Collections.synchronizedCollection(new ArrayList<>());
- public BasicButton(String name, String label, Font labelFont) {
+ public BasicButton(String name, Label label) {
super(name);
- this.label = new Label(name + ".Label", labelFont, label);
+ this.label = label;
setLayout(new LayoutAlign(10));
addChild(this.label);
@@ -59,8 +59,8 @@ public abstract class BasicButton extends Component {
return false;
} else if (
e.isLeftMouseButton() ||
- e.getKey() == GLFW.GLFW_KEY_SPACE ||
- e.getKey() == GLFW.GLFW_KEY_ENTER
+ e.getKey() == GLFW.GLFW_KEY_SPACE ||
+ e.getKey() == GLFW.GLFW_KEY_ENTER
) {
setPressed(e.isPress());
return true;
@@ -68,9 +68,9 @@ public abstract class BasicButton extends Component {
return false;
}
});
-
+
addListener(new Object() {
-
+
// Release when losing focus
@Subscribe
public void onFocusChange(FocusEvent e) {
@@ -78,7 +78,7 @@ public abstract class BasicButton extends Component {
setPressed(false);
}
}
-
+
// Release when hover ends
@Subscribe
public void onHoverEnded(HoverEvent e) {
@@ -86,7 +86,7 @@ public abstract class BasicButton extends Component {
setPressed(false);
}
}
-
+
// Release when disabled
@Subscribe
public void onDisabled(EnableEvent e) {
@@ -94,16 +94,20 @@ public abstract class BasicButton extends Component {
setPressed(false);
}
}
-
+
// Trigger virtualClick when button is released
@Subscribe
public void onRelease(ButtonEvent.Release e) {
virtualClick();
}
-
+
});
}
+ public BasicButton(String name, String label, Font labelFont) {
+ this(name, new Label(name + ".Label", labelFont, label));
+ }
+
public BasicButton(String name, String label) {
this(name, label, new Font());
}
@@ -111,7 +115,7 @@ public abstract class BasicButton extends Component {
public boolean isPressed() {
return isPressed;
}
-
+
public void click() {
setPressed(true);
setPressed(false);
@@ -120,7 +124,7 @@ public abstract class BasicButton extends Component {
public void setPressed(boolean isPressed) {
if (this.isPressed != isPressed) {
this.isPressed = isPressed;
-
+
if (isPressed) {
takeFocus();
}
@@ -128,16 +132,16 @@ public abstract class BasicButton extends Component {
dispatchEvent(ButtonEvent.create(this, this.isPressed));
}
}
-
+
public BasicButton addAction(Consumer action) {
this.actions.add(Objects.requireNonNull(action, "action"));
return this;
}
-
+
public boolean removeAction(Consumer action) {
return this.actions.remove(action);
}
-
+
public void virtualClick() {
this.actions.forEach(action -> {
action.accept(this);
@@ -147,5 +151,5 @@ public abstract class BasicButton extends Component {
public Label getLabel() {
return label;
}
-
+
}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Button.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Button.java
index bbeb361..5d42241 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Button.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Button.java
@@ -28,7 +28,11 @@ public class Button extends BasicButton {
public Button(String name, String label, Font labelFont) {
super(name, label, labelFont);
}
-
+
+ public Button(String name, Label label) {
+ super(name, label);
+ }
+
public Button(String name, String label) {
this(name, label, new Font());
}
@@ -36,7 +40,7 @@ public class Button extends BasicButton {
@Override
protected void assembleSelf(RenderTarget target) {
// Border
-
+
Vec4 borderColor;
if (isPressed() || isHovered() || isFocused()) {
borderColor = Colors.BLUE;
@@ -44,9 +48,9 @@ public class Button extends BasicButton {
borderColor = Colors.LIGHT_GRAY;
}
target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
-
+
// Inside area
-
+
if (isPressed()) {
// Do nothing
} else {
@@ -58,20 +62,20 @@ public class Button extends BasicButton {
}
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
}
-
+
// Change label font color
-
+
if (isPressed()) {
getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
} else {
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
}
}
-
+
@Override
protected void postAssembleSelf(RenderTarget target) {
// Apply disable tint
-
+
if (!isEnabled()) {
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Checkbox.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Checkbox.java
index 5f9d0df..990ed43 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Checkbox.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Checkbox.java
@@ -27,24 +27,24 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
public class Checkbox extends BasicButton {
-
+
private class Tick extends Component {
public Tick() {
super(Checkbox.this.getName() + ".Tick");
-
+
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
}
-
+
@Override
protected void assembleSelf(RenderTarget target) {
-
+
int size = getPreferredSize().x;
int x = getX();
int y = getY() + (getHeight() - size) / 2;
-
+
// Border
-
+
Vec4 borderColor;
if (Checkbox.this.isPressed() || Checkbox.this.isHovered() || Checkbox.this.isFocused()) {
borderColor = Colors.BLUE;
@@ -52,9 +52,9 @@ public class Checkbox extends BasicButton {
borderColor = Colors.LIGHT_GRAY;
}
target.fill(x, y, size, size, borderColor);
-
+
// Inside area
-
+
if (Checkbox.this.isPressed()) {
// Do nothing
} else {
@@ -66,9 +66,9 @@ public class Checkbox extends BasicButton {
}
target.fill(x + 2, y + 2, size - 4, size - 4, backgroundColor);
}
-
+
// "Tick"
-
+
if (Checkbox.this.isChecked()) {
target.fill(x + 4, y + 4, size - 8, size - 8, Colors.BLUE);
}
@@ -81,10 +81,10 @@ public class Checkbox extends BasicButton {
public Checkbox(String name, String label, Font labelFont, boolean check) {
super(name, label, labelFont);
this.checked = check;
-
+
assert getChildren().size() == 1 : "Checkbox expects that BasicButton contains exactly one child";
Component basicChild = getChild(0);
-
+
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
removeChild(basicChild);
setLayout(new LayoutAlign(0, 0.5f, 10));
@@ -92,18 +92,18 @@ public class Checkbox extends BasicButton {
group.addChild(new Tick());
group.addChild(basicChild);
addChild(group);
-
+
addAction(b -> switchState());
}
-
+
public Checkbox(String name, String label, Font labelFont) {
this(name, label, labelFont, false);
}
-
+
public Checkbox(String name, String label, boolean check) {
this(name, label, new Font(), check);
}
-
+
public Checkbox(String name, String label) {
this(name, label, false);
}
@@ -111,14 +111,14 @@ public class Checkbox extends BasicButton {
public void switchState() {
setChecked(!isChecked());
}
-
+
/**
* @return the checked
*/
public boolean isChecked() {
return checked;
}
-
+
/**
* @param checked the checked to set
*/
@@ -129,21 +129,21 @@ public class Checkbox extends BasicButton {
@Override
protected void assembleSelf(RenderTarget target) {
// Change label font color
-
+
if (isPressed()) {
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
} else {
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
}
}
-
+
@Override
protected void postAssembleSelf(RenderTarget target) {
// Apply disable tint
-
+
if (!isEnabled()) {
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
}
}
-
+
}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/RadioButton.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/RadioButton.java
index 471efb6..1ee7f66 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/RadioButton.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/RadioButton.java
@@ -30,30 +30,30 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
public class RadioButton extends BasicButton {
-
+
private class Tick extends Component {
public Tick() {
super(RadioButton.this.getName() + ".Tick");
-
+
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
}
-
+
private void cross(RenderTarget target, int x, int y, int size, Vec4 color) {
target.fill(x + 4, y, size - 8, size, color);
target.fill(x + 2, y + 2, size - 4, size - 4, color);
target.fill(x, y + 4, size, size - 8, color);
}
-
+
@Override
protected void assembleSelf(RenderTarget target) {
-
+
int size = getPreferredSize().x;
int x = getX();
int y = getY() + (getHeight() - size) / 2;
-
+
// Border
-
+
Vec4 borderColor;
if (RadioButton.this.isPressed() || RadioButton.this.isHovered() || RadioButton.this.isFocused()) {
borderColor = Colors.BLUE;
@@ -61,9 +61,9 @@ public class RadioButton extends BasicButton {
borderColor = Colors.LIGHT_GRAY;
}
cross(target, x, y, size, borderColor);
-
+
// Inside area
-
+
if (RadioButton.this.isPressed()) {
// Do nothing
} else {
@@ -75,9 +75,9 @@ public class RadioButton extends BasicButton {
}
cross(target, x + 2, y + 2, size - 4, backgroundColor);
}
-
+
// "Tick"
-
+
if (RadioButton.this.isChecked()) {
cross(target, x + 4, y + 4, size - 8, Colors.BLUE);
}
@@ -86,16 +86,16 @@ public class RadioButton extends BasicButton {
}
private boolean checked;
-
+
private RadioButtonGroup group = null;
public RadioButton(String name, String label, Font labelFont, boolean check) {
super(name, label, labelFont);
this.checked = check;
-
+
assert getChildren().size() == 1 : "RadioButton expects that BasicButton contains exactly one child";
Component basicChild = getChild(0);
-
+
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
removeChild(basicChild);
setLayout(new LayoutAlign(0, 0.5f, 10));
@@ -103,16 +103,17 @@ public class RadioButton extends BasicButton {
group.addChild(new Tick());
group.addChild(basicChild);
addChild(group);
-
+
addListener(KeyEvent.class, e -> {
- if (e.isRelease()) return false;
-
+ if (e.isRelease())
+ return false;
+
if (e.getKey() == GLFW.GLFW_KEY_LEFT || e.getKey() == GLFW.GLFW_KEY_UP) {
if (this.group != null) {
this.group.selectPrevious();
this.group.getSelected().takeFocus();
}
-
+
return true;
} else if (e.getKey() == GLFW.GLFW_KEY_RIGHT || e.getKey() == GLFW.GLFW_KEY_DOWN) {
if (this.group != null) {
@@ -121,85 +122,87 @@ public class RadioButton extends BasicButton {
}
return true;
}
-
+
return false;
});
-
+
addAction(b -> setChecked(true));
}
-
+
public RadioButton(String name, String label, Font labelFont) {
this(name, label, labelFont, false);
}
-
+
public RadioButton(String name, String label, boolean check) {
this(name, label, new Font(), check);
}
-
+
public RadioButton(String name, String label) {
this(name, label, false);
}
-
+
/**
* @param group the group to set
*/
public RadioButton setGroup(RadioButtonGroup group) {
-
+
if (this.group != null) {
group.selectNext();
removeAction(group.listener);
group.buttons.remove(this);
- group.getSelected(); // Clear reference if this was the only button in the group
+ group.getSelected(); // Clear reference if this was the only button
+ // in the group
}
-
+
this.group = group;
-
+
if (this.group != null) {
group.buttons.add(this);
addAction(group.listener);
}
-
+
setChecked(false);
-
+
return this;
}
-
+
/**
* @return the checked
*/
public boolean isChecked() {
return checked;
}
-
+
/**
* @param checked the checked to set
*/
public void setChecked(boolean checked) {
this.checked = checked;
-
+
if (group != null) {
- group.listener.accept(this); // Failsafe for manual invocations of setChecked()
+ group.listener.accept(this); // Failsafe for manual invocations of
+ // setChecked()
}
}
@Override
protected void assembleSelf(RenderTarget target) {
// Change label font color
-
+
if (isPressed()) {
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
} else {
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
}
}
-
+
@Override
protected void postAssembleSelf(RenderTarget target) {
// Apply disable tint
-
+
if (!isEnabled()) {
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
}
}
-
+
}
diff --git a/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java b/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java
new file mode 100644
index 0000000..b94f79d
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java
@@ -0,0 +1,35 @@
+package ru.windcorp.progressia.common.util;
+
+import glm.vec._3.i.Vec3i;
+
+public class HashableVec3i {
+
+ public Vec3i value;
+
+ public HashableVec3i(Vec3i inValue)
+ {
+ value = inValue;
+ }
+
+ @Override
+ public int hashCode() // Uses first 3 primes greater than 2**30
+ {
+ return 1073741827 * value.x + 1073741831 * value.y + 1073741833 * value.z;
+ }
+
+ @Override
+ public boolean equals(Object comparee)
+ {
+ if (comparee == null)
+ {
+ return false;
+ }
+ if (comparee.getClass() != HashableVec3i.class)
+ {
+ return false;
+ }
+ HashableVec3i compareeCast = (HashableVec3i) comparee;
+ return compareeCast.value == value;
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
index f762778..a7184e9 100644
--- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
+++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java
@@ -27,6 +27,7 @@ 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 {
@@ -47,6 +48,11 @@ public class PlayerManager {
this.players.add(player);
getServer().postEvent(new PlayerJoinedEvent.Immutable(getServer(), player));
}
+
+ public void removePlayer(Player player) {
+ this.players.remove(player);
+ getServer().postEvent(new PlayerLeftEvent.Immutable(getServer(), player));
+ }
public EntityData conjurePlayerEntity(String login) {
// TODO Live up to the name
diff --git a/src/main/java/ru/windcorp/progressia/server/ServerThread.java b/src/main/java/ru/windcorp/progressia/server/ServerThread.java
index 90f3ce9..aa0ff67 100644
--- a/src/main/java/ru/windcorp/progressia/server/ServerThread.java
+++ b/src/main/java/ru/windcorp/progressia/server/ServerThread.java
@@ -15,7 +15,7 @@
* 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 java.util.concurrent.Executors;
@@ -26,10 +26,13 @@ import org.apache.logging.log4j.LogManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
+@SuppressWarnings("unused")
public class ServerThread implements Runnable {
private static final ThreadLocal SERVER_THREADS_MAP = new ThreadLocal<>();
+ private static boolean isShuttingDown;
+
public static Server getCurrentServer() {
return SERVER_THREADS_MAP.get();
}
@@ -63,6 +66,7 @@ public class ServerThread implements Runnable {
}
public void start() {
+ isShuttingDown = false;
ticker.start();
executor.scheduleAtFixedRate(this, 0, 1000 / 20, TimeUnit.MILLISECONDS);
}
@@ -70,6 +74,11 @@ public class ServerThread implements Runnable {
@Override
public void run() {
try {
+ if (isShuttingDown) {
+ getTicker().stop();
+ executor.shutdown();
+ return;
+ }
server.tick();
ticker.runOneTick();
} catch (Throwable e) {
@@ -78,13 +87,10 @@ public class ServerThread implements Runnable {
}
public void stop() {
- try {
- executor.awaitTermination(10, TimeUnit.MINUTES);
- } catch (InterruptedException e) {
- LogManager.getLogger().warn("Received interrupt in ServerThread.stop(), aborting wait");
- }
- getTicker().stop();
+ isShuttingDown = true;
+
+ // getTicker().stop();
}
public Server getServer() {
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 935e846..fc55cbb 100644
--- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java
+++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java
@@ -92,6 +92,9 @@ public class ClientManager {
public void disconnectClient(Client client) {
client.disconnect();
clientsById.remove(client.getId());
+ if (client instanceof ClientPlayer) {
+ getServer().getPlayerManager().removePlayer(((ClientPlayer) client).getPlayer());
+ }
}
public void processPackets() {
diff --git a/src/main/java/ru/windcorp/progressia/test/LayerButtonTest.java b/src/main/java/ru/windcorp/progressia/test/LayerButtonTest.java
index e505291..a9812ea 100644
--- a/src/main/java/ru/windcorp/progressia/test/LayerButtonTest.java
+++ b/src/main/java/ru/windcorp/progressia/test/LayerButtonTest.java
@@ -17,7 +17,11 @@
*/
package ru.windcorp.progressia.test;
+import java.util.Collection;
+
+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.Button;
import ru.windcorp.progressia.client.graphics.gui.Checkbox;
@@ -25,45 +29,71 @@ import ru.windcorp.progressia.client.graphics.gui.Label;
import ru.windcorp.progressia.client.graphics.gui.RadioButton;
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
import ru.windcorp.progressia.client.graphics.gui.menu.MenuLayer;
+import ru.windcorp.progressia.client.localization.MutableStringLocalized;
+import ru.windcorp.progressia.server.Player;
+import ru.windcorp.progressia.server.Server;
+import ru.windcorp.progressia.server.ServerState;
public class LayerButtonTest extends MenuLayer {
+ boolean alive = true;
+
public LayerButtonTest() {
super("ButtonTest");
-
+
addTitle();
-
+
Button blockableButton;
getContent().addChild((blockableButton = new Button("BlockableButton", "Blockable")).addAction(b -> {
System.out.println("Button Blockable!");
}));
blockableButton.setEnabled(false);
-
+
getContent().addChild(new Checkbox("EnableButton", "Enable").addAction(b -> {
blockableButton.setEnabled(((Checkbox) b).isChecked());
}));
-
+
RadioButtonGroup group = new RadioButtonGroup().addAction(g -> {
System.out.println("RBG! " + g.getSelected().getLabel().getCurrentText());
});
-
+
getContent().addChild(new RadioButton("RB1", "Moon").setGroup(group));
getContent().addChild(new RadioButton("RB2", "Type").setGroup(group));
getContent().addChild(new RadioButton("RB3", "Ice").setGroup(group));
getContent().addChild(new RadioButton("RB4", "Cream").setGroup(group));
-
+
getContent().getChild(getContent().getChildren().size() - 1).setEnabled(false);
-
+
getContent().addChild(new Label("Hint", new Font().withColor(Colors.LIGHT_GRAY), "This is a MenuLayer"));
-
+
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
getCloseAction().run();
}));
-
- getContent().addChild(new Button("Quit", "Quit").addAction(b -> {
- System.exit(0);
+
+ getContent().addChild(new Button("Menu", "Back To Menu").addAction(b -> {
+ getCloseAction().run();
+
+ Collection players = ServerState.getInstance().getPlayerManager().getPlayers();
+ players.clear();
+
+ ClientState.disconnectFromLocalServer();
+
+ GUI.addTopLayer(new LayerTestText("Text", new MutableStringLocalized("LayerText.Save"), layer -> {
+ Server server = ServerState.getInstance();
+ if (server != null && server.getWorld().getChunks().isEmpty()) {
+ GUI.removeLayer(layer);
+
+ // TODO Refactor, this shouldn't be here
+ GUI.addTopLayer(new LayerTitle("Title"));
+ ServerState.getInstance().shutdown("Safe Exit");
+ ServerState.setInstance(null);
+ TestPlayerControls.resetInstance();
+ }
+ }));
+
+ ClientState.setInstance(null);
}));
-
+
getContent().takeFocus();
}
diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestText.java b/src/main/java/ru/windcorp/progressia/test/LayerTestText.java
new file mode 100644
index 0000000..a4d202b
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/LayerTestText.java
@@ -0,0 +1,29 @@
+package ru.windcorp.progressia.test;
+
+import java.util.function.Consumer;
+import ru.windcorp.progressia.client.graphics.Colors;
+import ru.windcorp.progressia.client.graphics.font.Font;
+import ru.windcorp.progressia.client.graphics.gui.GUILayer;
+import ru.windcorp.progressia.client.graphics.gui.Label;
+import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
+import ru.windcorp.progressia.client.localization.MutableString;
+
+public class LayerTestText extends GUILayer {
+
+ private final Consumer remover;
+
+ public LayerTestText(String name, MutableString value, Consumer remover) {
+ super(name, new LayoutAlign(15));
+ this.remover = remover;
+
+ Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
+ getRoot().addChild(new Label(name + ".Text", titleFont, value));
+ }
+
+ @Override
+ protected void doRender() {
+ super.doRender();
+ remover.accept(this);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTitle.java b/src/main/java/ru/windcorp/progressia/test/LayerTitle.java
new file mode 100644
index 0000000..d2ba139
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/LayerTitle.java
@@ -0,0 +1,37 @@
+package ru.windcorp.progressia.test;
+
+import ru.windcorp.progressia.ProgressiaLauncher;
+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.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;
+
+public class LayerTitle extends GUILayer {
+
+ public LayerTitle(String name) {
+ super(name, new LayoutVertical(20, 10));
+
+ MutableString title = new MutableStringLocalized("Layer" + name + ".Title");
+ Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
+ getRoot().addChild(new Label(name + ".Title", titleFont, title));
+
+ 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();
+ }));
+
+ MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
+ getRoot().addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> {
+ System.exit(0);
+ }));
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java
index ee42396..4ca0ea6 100644
--- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java
+++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java
@@ -46,10 +46,10 @@ import ru.windcorp.progressia.server.ServerState;
public class TestPlayerControls {
- private static final TestPlayerControls INSTANCE = new TestPlayerControls();
+ private static TestPlayerControls instance = new TestPlayerControls();
public static TestPlayerControls getInstance() {
- return INSTANCE;
+ return instance;
}
private static final double MODE_SWITCH_MAX_DELAY = 300 * Units.MILLISECONDS;
@@ -90,6 +90,10 @@ public class TestPlayerControls {
private LayerTestGUI debugLayer = null;
private Runnable updateCallback = null;
+
+ public static void resetInstance() {
+ instance = new TestPlayerControls();
+ }
public void applyPlayerControls() {
if (ClientState.getInstance() == null || !ClientState.getInstance().isReady()) {
diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java
index ebfafde..b79a90e 100644
--- a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java
+++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java
@@ -15,17 +15,30 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Scanner;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
@@ -34,6 +47,7 @@ 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.HashableVec3i;
import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.DecodingException;
import ru.windcorp.progressia.common.world.DefaultWorldData;
@@ -42,47 +56,342 @@ import ru.windcorp.progressia.server.Server;
public class TestWorldDiskIO {
- private static final Path SAVE_DIR = Paths.get("tmp_world");
+ private static Path SAVE_DIR = Paths.get("tmp_world");
+ private static final String formatFile = "world.format";
private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO");
+
+ private static HashMap mappedByteMap;
+ private static final boolean ENABLE = true;
- private static final boolean ENABLE = false;
+ private static int maxSize = 1048576;
+ private static int sectorSize = maxSize / 256;
+
+ private static final int bestFormat = 65536;
+
+ // private Map regions = new HashMap();
+ private static Vec3i regionSize;
+ private static int chunksPerRegion;
+ private static int offsetBytes;
+
+ private static int currentFormat = -1;
+ private static String extension = ".null";
+
+ private static int natFromInt(int loc) {
+ if (loc < 0)
+ return -2*loc - 1;
+ return 2*loc;
+ }
+
+ /*
+ * private static int intFromNat(int loc) // Possibly unused
+ * {
+ * if ((loc & 1) == 1)
+ * return -loc >> 1;
+ * return loc >> 1;
+ * }
+ */
+
+ private static Vec3i getRegion(Vec3i chunkLoc) {
+ int x = chunkLoc.x;
+ if (x<0)
+ {
+ x /= regionSize.x;
+ x--;
+ }
+ else
+ {
+ x /= regionSize.x;
+ }
+ int y = chunkLoc.y;
+ if (y<0)
+ {
+ y /= regionSize.y;
+ y--;
+ }
+ else
+ {
+ y /= regionSize.y;
+ }
+ int z = chunkLoc.z;
+ if (z<0)
+ {
+ z /= regionSize.z;
+ z--;
+ }
+ else
+ {
+ z /= regionSize.z;
+ }
+ return new Vec3i(
+ natFromInt(x),
+ natFromInt(y),
+ natFromInt(z)
+ );
+ }
+
+ private static int mod(int a, int m) {
+ return ((a % m) + m) % m;
+ }
+
+ private static Vec3i getRegionLoc(Vec3i chunkLoc) {
+ return new Vec3i(mod(chunkLoc.x, regionSize.x), mod(chunkLoc.y, regionSize.y), mod(chunkLoc.z, regionSize.z));
+ }
+
+ public static void initRegions() {
+ initRegions(null);
+ }
+
+ public static void initRegions(Path worldPath) {
+ if (worldPath != null) {
+ SAVE_DIR = worldPath;
+ }
+
+ // regions.put(new Vec3i(0,0,0), new Vec3i(1,1,1));
+ }
+
+ public static int getAvailableSector(MappedByteBuffer mbb)
+ {
+ int sectorsUsed = 0;
+ for (int i=offsetBytes; i<(offsetBytes+1)*chunksPerRegion; i+= (offsetBytes+1))
+ {
+ sectorsUsed += mbb.get(i);
+ }
+ return sectorsUsed;
+ }
+
+ private static void setRegionSize(int format) {
+ mappedByteMap = new HashMap();
+ switch (format) {
+ case 0:
+ case 1:
+ regionSize = new Vec3i(1);
+ chunksPerRegion = 1;
+ currentFormat = format;
+ extension = ".progressia_chunk";
+ break;
+ case 65536:
+ regionSize = new Vec3i(16);
+ chunksPerRegion = 16 * 16 * 16;
+ currentFormat = 65536;
+ offsetBytes = 3;
+ extension = ".progressia_region";
+ break;
+ }
+ }
+
+ /*private static void expand(int sectors) {
+
+ }*/
public static void saveChunk(DefaultChunkData chunk, Server server) {
if (!ENABLE)
return;
try {
- LOG.debug(
- "Saving {} {} {}",
- chunk.getPosition().x,
- chunk.getPosition().y,
- chunk.getPosition().z
- );
- Files.createDirectories(SAVE_DIR);
-
- Path path = SAVE_DIR.resolve(
- String.format(
- "chunk_%+d_%+d_%+d.progressia_chunk",
+ if (currentFormat == 0) {
+ LOG.debug(
+ "Saving {} {} {}",
chunk.getPosition().x,
chunk.getPosition().y,
chunk.getPosition().z
- )
- );
+ );
+
+ Files.createDirectories(SAVE_DIR);
+
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "chunk_%+d_%+d_%+d" + extension,
+ chunk.getPosition().x,
+ chunk.getPosition().y,
+ chunk.getPosition().z
+ )
+ );
+
+ try (
+ DataOutputStream output = new DataOutputStream(
+ new DeflaterOutputStream(new BufferedOutputStream(Files.newOutputStream(path)))
+ )
+ ) {
+ ChunkIO.save(chunk, output, IOContext.SAVE);
+ writeGenerationHint(chunk, output, server);
+ }
+ } else if (currentFormat == 1) {
+ LOG.debug(
+ "Saving {} {} {}",
+ chunk.getPosition().x,
+ chunk.getPosition().y,
+ chunk.getPosition().z
+ );
+
+ Files.createDirectories(SAVE_DIR);
+
+ Vec3i saveCoords = getRegion(chunk.getPosition());
+
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "chunk_%d_%d_%d" + extension,
+ saveCoords.x,
+ saveCoords.y,
+ saveCoords.z
+ )
+ );
+
+ try (
+ DataOutputStream output = new DataOutputStream(
+ new DeflaterOutputStream(new BufferedOutputStream(Files.newOutputStream(path)))
+ )
+ ) {
+ ChunkIO.save(chunk, output, IOContext.SAVE);
+ writeGenerationHint(chunk, output, server);
+ }
+ } else if (currentFormat == 65536) {
+ LOG.debug(
+ "Saving {} {} {}",
+ chunk.getPosition().x,
+ chunk.getPosition().y,
+ chunk.getPosition().z
+ );
+
+ Files.createDirectories(SAVE_DIR);
+
+ Vec3i saveCoords = getRegion(chunk.getPosition());
+
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "%d_%d_%d" + extension,
+ saveCoords.x,
+ saveCoords.y,
+ saveCoords.z
+ )
+ );
+
+ /*
+ * if (!dosave)
+ * {
+ * return;
+ * }
+ * dosave = false;
+ */
+
+
+ MappedByteBuffer output = mappedByteMap.get(new HashableVec3i(saveCoords));
+ LOG.info("saveCoords {},{},{}", saveCoords.x, saveCoords.y, saveCoords.z);
+ if (output == null)
+ {
+ output = makeNew(path, new HashableVec3i(saveCoords));
+ }
+ // LOG.debug(output.read());
+ if (output.get() < 0) {
+ LOG.info("Making header");
+ ByteBuffer headerBytes = ByteBuffer.allocate((offsetBytes + 1) * chunksPerRegion);
+ for (int i=0;i<(offsetBytes + 1) * chunksPerRegion;i++)
+ {
+ headerBytes.put(i, (byte) 0);
+ }
+ output.put(headerBytes);
+ }
+
+ Vec3i pos = getRegionLoc(chunk.getPosition());
+ int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
+ int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
+ output.position(shortOffset);
+ int offset = 0;
+ for (int i = 0; i < offsetBytes; i++) {
+ offset *= 256;
+ offset += output.get();
+ }
+ ByteBuffer readOffset = ByteBuffer.allocate(offsetBytes);
+ int sectorLength = output.get();
+ if (sectorLength == 0) {
+ //int outputLen = (int) output.size();
+ //offset = (int) (outputLen - fullOffset) / sectorSize + 1;
+ offset = getAvailableSector(output);
+ output.position(shortOffset);
+
+ //readInt.putInt(offset<<8);
+ for (int i=0;i> 24);
+ LOG.debug(bfClone >> 24);
+ bfClone = bfClone << 8;
+ }
+
+ /*
+ * bw.write(
+ * new char[] {
+ * (char) bestFormat / (256 * 256 * 256),
+ * (char) (bestFormat % 256) / (256 * 256),
+ * (char) (bestFormat % (256 * 256)) / (256),
+ * (char) (bestFormat % (256 * 256 * 256)) }
+ * );
+ */
+
+ bw.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
}
- try {
- DefaultChunkData result = load(path, chunkPos, world, server);
+ if (currentFormat == 0) {
- LOG.debug(
- "Loaded {} {} {}",
- chunkPos.x,
- chunkPos.y,
- chunkPos.z
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "chunk_%+d_%+d_%+d" + extension,
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ )
);
- return result;
- } catch (Exception e) {
- e.printStackTrace();
- LOG.debug(
- "Could not load {} {} {}",
- chunkPos.x,
- chunkPos.y,
- chunkPos.z
+ if (!Files.exists(path)) {
+ LOG.debug(
+ "Not found {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return null;
+ }
+
+ try {
+ DefaultChunkData result = load(path, chunkPos, world, server);
+
+ LOG.debug(
+ "Loaded {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.debug(
+ "Could not load {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+ return null;
+ }
+ } else if (currentFormat == 1) {
+ Vec3i saveCoords = getRegion(chunkPos);
+
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "chunk_%d_%d_%d" + extension,
+ saveCoords.x,
+ saveCoords.y,
+ saveCoords.z
+ )
);
- return null;
+
+ if (!Files.exists(path)) {
+ LOG.debug(
+ "Not found {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return null;
+ }
+
+ try {
+ DefaultChunkData result = load(path, chunkPos, world, server);
+
+ LOG.debug(
+ "Loaded {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.debug(
+ "Could not load {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+ return null;
+ }
+ } else if (currentFormat == 65536) {
+ Vec3i saveCoords = getRegion(chunkPos);
+
+ Path path = SAVE_DIR.resolve(
+ String.format(
+ "%d_%d_%d" + extension,
+ saveCoords.x,
+ saveCoords.y,
+ saveCoords.z
+ )
+ );
+
+ if (!Files.exists(path)) {
+ LOG.debug(
+ "Not found {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return null;
+ }
+
+ try {
+ DefaultChunkData result = loadRegion(path, chunkPos, world, server);
+
+ LOG.debug(
+ "Loaded {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.debug(
+ "Could not load {} {} {}",
+ chunkPos.x,
+ chunkPos.y,
+ chunkPos.z
+ );
+ return null;
+ }
}
+ return null;
}
private static DefaultChunkData load(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
@@ -149,6 +608,56 @@ public class TestWorldDiskIO {
}
}
+ private static DefaultChunkData loadRegion(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
+ throws IOException,
+ DecodingException {
+ try
+ {
+ Vec3i streamCoords = getRegion(chunkPos);
+
+ MappedByteBuffer input = mappedByteMap.get(new HashableVec3i(streamCoords));
+ LOG.info("streamCoords {},{},{}", streamCoords.x,streamCoords.y,streamCoords.z);
+ if (input == null)
+ {
+ //input = new RandomAccessFile(path.toFile(), "rw");
+ //input = Files.newByteChannel(path);
+ input = makeNew(path, new HashableVec3i(streamCoords));
+ }
+
+ // LOG.info(path.toString());
+ Vec3i pos = getRegionLoc(chunkPos);
+
+ int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
+ int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
+ input.position(shortOffset);
+ int offset = 0;
+ for (int i = 0; i < offsetBytes; i++) {
+ offset *= 256;
+ offset += input.get();
+ }
+ int sectorLength = input.get();
+ input.position(fullOffset + sectorSize * offset);
+
+ // LOG.info("Read {} sectors", sectorLength);
+
+ byte tempData[] = new byte[sectorSize * sectorLength];
+ input.get(tempData);
+
+ DataInputStream trueInput = new DataInputStream(
+ new InflaterInputStream(new BufferedInputStream(new ByteArrayInputStream(tempData)))
+ );
+ DefaultChunkData chunk = ChunkIO.load(world, chunkPos, trueInput, IOContext.SAVE);
+ readGenerationHint(chunk, trueInput, server);
+ return chunk;
+ }
+ catch (EOFException e)
+ {
+ LOG.warn("Reached end of file");
+ e.printStackTrace();
+ }
+ return null;
+ }
+
private static void readGenerationHint(DefaultChunkData chunk, DataInputStream input, Server server)
throws IOException,
DecodingException {
diff --git a/src/main/resources/assets/languages/en-US.lang b/src/main/resources/assets/languages/en-US.lang
index e2ff70b..e6ab183 100644
--- a/src/main/resources/assets/languages/en-US.lang
+++ b/src/main/resources/assets/languages/en-US.lang
@@ -21,4 +21,13 @@ LayerTestGUI.PlacementModeHint = (Blocks %s Tiles: Ctrl + Mouse Wheel)
LayerTestGUI.IsFullscreen = Fullscreen: %5s (F11)
LayerTestGUI.IsVSync = VSync: %5s (F12)
-LayerButtonTest.Title = Button Test
\ No newline at end of file
+LayerButtonTest.Title = Button Test
+LayerButtonTest.Return = Back To Menu
+
+LayerTitle.Title = Progressia
+LayerTitle.Play = Play World
+LayerTitle.Options = Options
+LayerTitle.Quit = Quit
+
+LayerText.Load = Loading...
+LayerText.Save = Saving...
\ No newline at end of file
diff --git a/src/main/resources/assets/languages/ru-RU.lang b/src/main/resources/assets/languages/ru-RU.lang
index 97935d6..09c9c33 100644
--- a/src/main/resources/assets/languages/ru-RU.lang
+++ b/src/main/resources/assets/languages/ru-RU.lang
@@ -21,4 +21,13 @@ LayerTestGUI.PlacementModeHint = (Блок %s плитки: Ctrl + прокру
LayerTestGUI.IsFullscreen = Полный экран: %5s (F11)
LayerTestGUI.IsVSync = Верт. синхр.: %5s (F12)
-LayerButtonTest.Title = Тест Кнопок
\ No newline at end of file
+LayerButtonTest.Title = Тест Кнопок
+LayerButtonTest.Return = Back To Menu [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
+
+LayerTitle.Title = Прогрессия
+LayerTitle.Play = ???????
+LayerTitle.Options = ????????
+LayerTitle.Quit = ????????
+
+LayerText.Load = Loading... (Change)
+LayerText.Save = Saving...(Cahnsf)
\ No newline at end of file
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index ce70734..b249e72 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -26,6 +26,7 @@
-->
+