Merge branch 'save-world'
Third time's the charm!
This commit is contained in:
commit
0ccc108ddd
@ -15,21 +15,32 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia;
|
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.CrashReports;
|
||||||
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
|
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
|
||||||
import ru.windcorp.progressia.common.util.crash.providers.*;
|
import ru.windcorp.progressia.common.util.crash.providers.*;
|
||||||
|
import ru.windcorp.progressia.test.LayerTitle;
|
||||||
|
|
||||||
public class ProgressiaLauncher {
|
public class ProgressiaLauncher {
|
||||||
|
|
||||||
public static String[] arguments;
|
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();
|
arguments = args.clone();
|
||||||
setupCrashReports();
|
setupCrashReports();
|
||||||
proxy.initialize();
|
|
||||||
|
inProxy.initialize();
|
||||||
|
proxy = inProxy;
|
||||||
|
GUI.addTopLayer(new LayerTitle("Title"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void play() {
|
||||||
|
proxy.setupServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupCrashReports() {
|
private static void setupCrashReports() {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client;
|
package ru.windcorp.progressia.client;
|
||||||
|
|
||||||
import ru.windcorp.progressia.Proxy;
|
import ru.windcorp.progressia.Proxy;
|
||||||
@ -38,7 +38,9 @@ public class ClientProxy implements Proxy {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
|
||||||
GraphicsBackend.initialize();
|
GraphicsBackend.initialize();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
|
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
|
||||||
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
|
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
|
||||||
@ -58,10 +60,12 @@ public class ClientProxy implements Proxy {
|
|||||||
|
|
||||||
AudioSystem.initialize();
|
AudioSystem.initialize();
|
||||||
|
|
||||||
ServerState.startServer();
|
|
||||||
ClientState.connectToLocalServer();
|
|
||||||
|
|
||||||
TestMusicPlayer.start();
|
TestMusicPlayer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setupServer() {
|
||||||
|
ServerState.startServer();
|
||||||
|
ClientState.connectToLocalServer();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,18 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client;
|
package ru.windcorp.progressia.client;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
|
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
|
||||||
import ru.windcorp.progressia.client.graphics.GUI;
|
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.client.graphics.world.LayerWorld;
|
||||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||||
|
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||||
import ru.windcorp.progressia.server.ServerState;
|
import ru.windcorp.progressia.server.ServerState;
|
||||||
import ru.windcorp.progressia.test.LayerAbout;
|
import ru.windcorp.progressia.test.LayerAbout;
|
||||||
|
import ru.windcorp.progressia.test.LayerTestText;
|
||||||
import ru.windcorp.progressia.test.LayerTestUI;
|
import ru.windcorp.progressia.test.LayerTestUI;
|
||||||
import ru.windcorp.progressia.test.TestContent;
|
import ru.windcorp.progressia.test.TestContent;
|
||||||
|
|
||||||
@ -52,11 +55,39 @@ public class ClientState {
|
|||||||
channel.connect(TestContent.PLAYER_LOGIN);
|
channel.connect(TestContent.PLAYER_LOGIN);
|
||||||
|
|
||||||
setInstance(client);
|
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() {
|
private ClientState() {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client.comms.localhost;
|
package ru.windcorp.progressia.client.comms.localhost;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client.comms.localhost;
|
package ru.windcorp.progressia.client.comms.localhost;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
|
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
|
||||||
import ru.windcorp.progressia.common.comms.packets.Packet;
|
import ru.windcorp.progressia.common.comms.packets.Packet;
|
||||||
import ru.windcorp.progressia.server.Server;
|
import ru.windcorp.progressia.server.Server;
|
||||||
|
import ru.windcorp.progressia.server.ServerState;
|
||||||
|
|
||||||
public class LocalServerCommsChannel extends ServerCommsChannel {
|
public class LocalServerCommsChannel extends ServerCommsChannel {
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ public class LocalServerCommsChannel extends ServerCommsChannel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
// Do nothing
|
ServerState.getInstance().getClientManager().disconnectClient(localClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client.graphics;
|
package ru.windcorp.progressia.client.graphics;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ public class GUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void addBottomLayer(Layer layer) {
|
public static void addBottomLayer(Layer layer) {
|
||||||
|
Objects.requireNonNull(layer, "layer");
|
||||||
modify(layers -> {
|
modify(layers -> {
|
||||||
layers.add(layer);
|
layers.add(layer);
|
||||||
layer.onAdded();
|
layer.onAdded();
|
||||||
@ -65,6 +67,7 @@ public class GUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void addTopLayer(Layer layer) {
|
public static void addTopLayer(Layer layer) {
|
||||||
|
Objects.requireNonNull(layer, "layer");
|
||||||
modify(layers -> {
|
modify(layers -> {
|
||||||
layers.add(0, layer);
|
layers.add(0, layer);
|
||||||
layer.onAdded();
|
layer.onAdded();
|
||||||
@ -72,6 +75,7 @@ public class GUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLayer(Layer layer) {
|
public static void removeLayer(Layer layer) {
|
||||||
|
Objects.requireNonNull(layer, "layer");
|
||||||
modify(layers -> {
|
modify(layers -> {
|
||||||
layers.remove(layer);
|
layers.remove(layer);
|
||||||
layer.onRemoved();
|
layer.onRemoved();
|
||||||
@ -88,33 +92,33 @@ public class GUI {
|
|||||||
|
|
||||||
public static void render() {
|
public static void render() {
|
||||||
synchronized (LAYERS) {
|
synchronized (LAYERS) {
|
||||||
|
|
||||||
if (!MODIFICATION_QUEUE.isEmpty()) {
|
if (!MODIFICATION_QUEUE.isEmpty()) {
|
||||||
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
|
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
|
||||||
MODIFICATION_QUEUE.clear();
|
MODIFICATION_QUEUE.clear();
|
||||||
|
|
||||||
boolean isMouseCurrentlyCaptured = GraphicsInterface.isMouseCaptured();
|
boolean isMouseCurrentlyCaptured = GraphicsInterface.isMouseCaptured();
|
||||||
Layer.CursorPolicy policy = Layer.CursorPolicy.REQUIRE;
|
Layer.CursorPolicy policy = Layer.CursorPolicy.REQUIRE;
|
||||||
|
|
||||||
for (Layer layer : LAYERS) {
|
for (Layer layer : LAYERS) {
|
||||||
Layer.CursorPolicy currentPolicy = layer.getCursorPolicy();
|
Layer.CursorPolicy currentPolicy = layer.getCursorPolicy();
|
||||||
|
|
||||||
if (currentPolicy != Layer.CursorPolicy.INDIFFERENT) {
|
if (currentPolicy != Layer.CursorPolicy.INDIFFERENT) {
|
||||||
policy = currentPolicy;
|
policy = currentPolicy;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldCaptureMouse = (policy == Layer.CursorPolicy.FORBID);
|
boolean shouldCaptureMouse = (policy == Layer.CursorPolicy.FORBID);
|
||||||
if (shouldCaptureMouse != isMouseCurrentlyCaptured) {
|
if (shouldCaptureMouse != isMouseCurrentlyCaptured) {
|
||||||
GraphicsInterface.setMouseCaptured(shouldCaptureMouse);
|
GraphicsInterface.setMouseCaptured(shouldCaptureMouse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = LAYERS.size() - 1; i >= 0; --i) {
|
for (int i = LAYERS.size() - 1; i >= 0; --i) {
|
||||||
LAYERS.get(i).render();
|
LAYERS.get(i).render();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,15 +37,15 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
|
|
||||||
public abstract class BasicButton extends Component {
|
public abstract class BasicButton extends Component {
|
||||||
|
|
||||||
private final Label label;
|
private final Label label;
|
||||||
|
|
||||||
private boolean isPressed = false;
|
private boolean isPressed = false;
|
||||||
private final Collection<Consumer<BasicButton>> actions = Collections.synchronizedCollection(new ArrayList<>());
|
private final Collection<Consumer<BasicButton>> actions = Collections.synchronizedCollection(new ArrayList<>());
|
||||||
|
|
||||||
public BasicButton(String name, String label, Font labelFont) {
|
public BasicButton(String name, Label label) {
|
||||||
super(name);
|
super(name);
|
||||||
this.label = new Label(name + ".Label", labelFont, label);
|
this.label = label;
|
||||||
|
|
||||||
setLayout(new LayoutAlign(10));
|
setLayout(new LayoutAlign(10));
|
||||||
addChild(this.label);
|
addChild(this.label);
|
||||||
@ -59,8 +59,8 @@ public abstract class BasicButton extends Component {
|
|||||||
return false;
|
return false;
|
||||||
} else if (
|
} else if (
|
||||||
e.isLeftMouseButton() ||
|
e.isLeftMouseButton() ||
|
||||||
e.getKey() == GLFW.GLFW_KEY_SPACE ||
|
e.getKey() == GLFW.GLFW_KEY_SPACE ||
|
||||||
e.getKey() == GLFW.GLFW_KEY_ENTER
|
e.getKey() == GLFW.GLFW_KEY_ENTER
|
||||||
) {
|
) {
|
||||||
setPressed(e.isPress());
|
setPressed(e.isPress());
|
||||||
return true;
|
return true;
|
||||||
@ -68,9 +68,9 @@ public abstract class BasicButton extends Component {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addListener(new Object() {
|
addListener(new Object() {
|
||||||
|
|
||||||
// Release when losing focus
|
// Release when losing focus
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onFocusChange(FocusEvent e) {
|
public void onFocusChange(FocusEvent e) {
|
||||||
@ -78,7 +78,7 @@ public abstract class BasicButton extends Component {
|
|||||||
setPressed(false);
|
setPressed(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release when hover ends
|
// Release when hover ends
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onHoverEnded(HoverEvent e) {
|
public void onHoverEnded(HoverEvent e) {
|
||||||
@ -86,7 +86,7 @@ public abstract class BasicButton extends Component {
|
|||||||
setPressed(false);
|
setPressed(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release when disabled
|
// Release when disabled
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDisabled(EnableEvent e) {
|
public void onDisabled(EnableEvent e) {
|
||||||
@ -94,16 +94,20 @@ public abstract class BasicButton extends Component {
|
|||||||
setPressed(false);
|
setPressed(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger virtualClick when button is released
|
// Trigger virtualClick when button is released
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onRelease(ButtonEvent.Release e) {
|
public void onRelease(ButtonEvent.Release e) {
|
||||||
virtualClick();
|
virtualClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BasicButton(String name, String label, Font labelFont) {
|
||||||
|
this(name, new Label(name + ".Label", labelFont, label));
|
||||||
|
}
|
||||||
|
|
||||||
public BasicButton(String name, String label) {
|
public BasicButton(String name, String label) {
|
||||||
this(name, label, new Font());
|
this(name, label, new Font());
|
||||||
}
|
}
|
||||||
@ -111,7 +115,7 @@ public abstract class BasicButton extends Component {
|
|||||||
public boolean isPressed() {
|
public boolean isPressed() {
|
||||||
return isPressed;
|
return isPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void click() {
|
public void click() {
|
||||||
setPressed(true);
|
setPressed(true);
|
||||||
setPressed(false);
|
setPressed(false);
|
||||||
@ -120,7 +124,7 @@ public abstract class BasicButton extends Component {
|
|||||||
public void setPressed(boolean isPressed) {
|
public void setPressed(boolean isPressed) {
|
||||||
if (this.isPressed != isPressed) {
|
if (this.isPressed != isPressed) {
|
||||||
this.isPressed = isPressed;
|
this.isPressed = isPressed;
|
||||||
|
|
||||||
if (isPressed) {
|
if (isPressed) {
|
||||||
takeFocus();
|
takeFocus();
|
||||||
}
|
}
|
||||||
@ -128,16 +132,16 @@ public abstract class BasicButton extends Component {
|
|||||||
dispatchEvent(ButtonEvent.create(this, this.isPressed));
|
dispatchEvent(ButtonEvent.create(this, this.isPressed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicButton addAction(Consumer<BasicButton> action) {
|
public BasicButton addAction(Consumer<BasicButton> action) {
|
||||||
this.actions.add(Objects.requireNonNull(action, "action"));
|
this.actions.add(Objects.requireNonNull(action, "action"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeAction(Consumer<BasicButton> action) {
|
public boolean removeAction(Consumer<BasicButton> action) {
|
||||||
return this.actions.remove(action);
|
return this.actions.remove(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void virtualClick() {
|
public void virtualClick() {
|
||||||
this.actions.forEach(action -> {
|
this.actions.forEach(action -> {
|
||||||
action.accept(this);
|
action.accept(this);
|
||||||
@ -147,5 +151,5 @@ public abstract class BasicButton extends Component {
|
|||||||
public Label getLabel() {
|
public Label getLabel() {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,11 @@ public class Button extends BasicButton {
|
|||||||
public Button(String name, String label, Font labelFont) {
|
public Button(String name, String label, Font labelFont) {
|
||||||
super(name, label, labelFont);
|
super(name, label, labelFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Button(String name, Label label) {
|
||||||
|
super(name, label);
|
||||||
|
}
|
||||||
|
|
||||||
public Button(String name, String label) {
|
public Button(String name, String label) {
|
||||||
this(name, label, new Font());
|
this(name, label, new Font());
|
||||||
}
|
}
|
||||||
@ -36,7 +40,7 @@ public class Button extends BasicButton {
|
|||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Border
|
// Border
|
||||||
|
|
||||||
Vec4 borderColor;
|
Vec4 borderColor;
|
||||||
if (isPressed() || isHovered() || isFocused()) {
|
if (isPressed() || isHovered() || isFocused()) {
|
||||||
borderColor = Colors.BLUE;
|
borderColor = Colors.BLUE;
|
||||||
@ -44,9 +48,9 @@ public class Button extends BasicButton {
|
|||||||
borderColor = Colors.LIGHT_GRAY;
|
borderColor = Colors.LIGHT_GRAY;
|
||||||
}
|
}
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
|
target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
|
||||||
if (isPressed()) {
|
if (isPressed()) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
} else {
|
} else {
|
||||||
@ -58,20 +62,20 @@ public class Button extends BasicButton {
|
|||||||
}
|
}
|
||||||
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
|
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change label font color
|
// Change label font color
|
||||||
|
|
||||||
if (isPressed()) {
|
if (isPressed()) {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
|
||||||
} else {
|
} else {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
protected void postAssembleSelf(RenderTarget target) {
|
||||||
// Apply disable tint
|
// Apply disable tint
|
||||||
|
|
||||||
if (!isEnabled()) {
|
if (!isEnabled()) {
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||||
}
|
}
|
||||||
|
@ -27,24 +27,24 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
|||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
|
||||||
|
|
||||||
public class Checkbox extends BasicButton {
|
public class Checkbox extends BasicButton {
|
||||||
|
|
||||||
private class Tick extends Component {
|
private class Tick extends Component {
|
||||||
|
|
||||||
public Tick() {
|
public Tick() {
|
||||||
super(Checkbox.this.getName() + ".Tick");
|
super(Checkbox.this.getName() + ".Tick");
|
||||||
|
|
||||||
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
|
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
|
|
||||||
int size = getPreferredSize().x;
|
int size = getPreferredSize().x;
|
||||||
int x = getX();
|
int x = getX();
|
||||||
int y = getY() + (getHeight() - size) / 2;
|
int y = getY() + (getHeight() - size) / 2;
|
||||||
|
|
||||||
// Border
|
// Border
|
||||||
|
|
||||||
Vec4 borderColor;
|
Vec4 borderColor;
|
||||||
if (Checkbox.this.isPressed() || Checkbox.this.isHovered() || Checkbox.this.isFocused()) {
|
if (Checkbox.this.isPressed() || Checkbox.this.isHovered() || Checkbox.this.isFocused()) {
|
||||||
borderColor = Colors.BLUE;
|
borderColor = Colors.BLUE;
|
||||||
@ -52,9 +52,9 @@ public class Checkbox extends BasicButton {
|
|||||||
borderColor = Colors.LIGHT_GRAY;
|
borderColor = Colors.LIGHT_GRAY;
|
||||||
}
|
}
|
||||||
target.fill(x, y, size, size, borderColor);
|
target.fill(x, y, size, size, borderColor);
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
|
||||||
if (Checkbox.this.isPressed()) {
|
if (Checkbox.this.isPressed()) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
} else {
|
} else {
|
||||||
@ -66,9 +66,9 @@ public class Checkbox extends BasicButton {
|
|||||||
}
|
}
|
||||||
target.fill(x + 2, y + 2, size - 4, size - 4, backgroundColor);
|
target.fill(x + 2, y + 2, size - 4, size - 4, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Tick"
|
// "Tick"
|
||||||
|
|
||||||
if (Checkbox.this.isChecked()) {
|
if (Checkbox.this.isChecked()) {
|
||||||
target.fill(x + 4, y + 4, size - 8, size - 8, Colors.BLUE);
|
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) {
|
public Checkbox(String name, String label, Font labelFont, boolean check) {
|
||||||
super(name, label, labelFont);
|
super(name, label, labelFont);
|
||||||
this.checked = check;
|
this.checked = check;
|
||||||
|
|
||||||
assert getChildren().size() == 1 : "Checkbox expects that BasicButton contains exactly one child";
|
assert getChildren().size() == 1 : "Checkbox expects that BasicButton contains exactly one child";
|
||||||
Component basicChild = getChild(0);
|
Component basicChild = getChild(0);
|
||||||
|
|
||||||
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
|
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
|
||||||
removeChild(basicChild);
|
removeChild(basicChild);
|
||||||
setLayout(new LayoutAlign(0, 0.5f, 10));
|
setLayout(new LayoutAlign(0, 0.5f, 10));
|
||||||
@ -92,18 +92,18 @@ public class Checkbox extends BasicButton {
|
|||||||
group.addChild(new Tick());
|
group.addChild(new Tick());
|
||||||
group.addChild(basicChild);
|
group.addChild(basicChild);
|
||||||
addChild(group);
|
addChild(group);
|
||||||
|
|
||||||
addAction(b -> switchState());
|
addAction(b -> switchState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Checkbox(String name, String label, Font labelFont) {
|
public Checkbox(String name, String label, Font labelFont) {
|
||||||
this(name, label, labelFont, false);
|
this(name, label, labelFont, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Checkbox(String name, String label, boolean check) {
|
public Checkbox(String name, String label, boolean check) {
|
||||||
this(name, label, new Font(), check);
|
this(name, label, new Font(), check);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Checkbox(String name, String label) {
|
public Checkbox(String name, String label) {
|
||||||
this(name, label, false);
|
this(name, label, false);
|
||||||
}
|
}
|
||||||
@ -111,14 +111,14 @@ public class Checkbox extends BasicButton {
|
|||||||
public void switchState() {
|
public void switchState() {
|
||||||
setChecked(!isChecked());
|
setChecked(!isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the checked
|
* @return the checked
|
||||||
*/
|
*/
|
||||||
public boolean isChecked() {
|
public boolean isChecked() {
|
||||||
return checked;
|
return checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param checked the checked to set
|
* @param checked the checked to set
|
||||||
*/
|
*/
|
||||||
@ -129,21 +129,21 @@ public class Checkbox extends BasicButton {
|
|||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Change label font color
|
// Change label font color
|
||||||
|
|
||||||
if (isPressed()) {
|
if (isPressed()) {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
||||||
} else {
|
} else {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
protected void postAssembleSelf(RenderTarget target) {
|
||||||
// Apply disable tint
|
// Apply disable tint
|
||||||
|
|
||||||
if (!isEnabled()) {
|
if (!isEnabled()) {
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,30 +30,30 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
|
|
||||||
public class RadioButton extends BasicButton {
|
public class RadioButton extends BasicButton {
|
||||||
|
|
||||||
private class Tick extends Component {
|
private class Tick extends Component {
|
||||||
|
|
||||||
public Tick() {
|
public Tick() {
|
||||||
super(RadioButton.this.getName() + ".Tick");
|
super(RadioButton.this.getName() + ".Tick");
|
||||||
|
|
||||||
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
|
setPreferredSize(new Vec2i(Typefaces.getDefault().getLineHeight() * 3 / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cross(RenderTarget target, int x, int y, int size, Vec4 color) {
|
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 + 4, y, size - 8, size, color);
|
||||||
target.fill(x + 2, y + 2, size - 4, size - 4, color);
|
target.fill(x + 2, y + 2, size - 4, size - 4, color);
|
||||||
target.fill(x, y + 4, size, size - 8, color);
|
target.fill(x, y + 4, size, size - 8, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
|
|
||||||
int size = getPreferredSize().x;
|
int size = getPreferredSize().x;
|
||||||
int x = getX();
|
int x = getX();
|
||||||
int y = getY() + (getHeight() - size) / 2;
|
int y = getY() + (getHeight() - size) / 2;
|
||||||
|
|
||||||
// Border
|
// Border
|
||||||
|
|
||||||
Vec4 borderColor;
|
Vec4 borderColor;
|
||||||
if (RadioButton.this.isPressed() || RadioButton.this.isHovered() || RadioButton.this.isFocused()) {
|
if (RadioButton.this.isPressed() || RadioButton.this.isHovered() || RadioButton.this.isFocused()) {
|
||||||
borderColor = Colors.BLUE;
|
borderColor = Colors.BLUE;
|
||||||
@ -61,9 +61,9 @@ public class RadioButton extends BasicButton {
|
|||||||
borderColor = Colors.LIGHT_GRAY;
|
borderColor = Colors.LIGHT_GRAY;
|
||||||
}
|
}
|
||||||
cross(target, x, y, size, borderColor);
|
cross(target, x, y, size, borderColor);
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
|
||||||
if (RadioButton.this.isPressed()) {
|
if (RadioButton.this.isPressed()) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
} else {
|
} else {
|
||||||
@ -75,9 +75,9 @@ public class RadioButton extends BasicButton {
|
|||||||
}
|
}
|
||||||
cross(target, x + 2, y + 2, size - 4, backgroundColor);
|
cross(target, x + 2, y + 2, size - 4, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Tick"
|
// "Tick"
|
||||||
|
|
||||||
if (RadioButton.this.isChecked()) {
|
if (RadioButton.this.isChecked()) {
|
||||||
cross(target, x + 4, y + 4, size - 8, Colors.BLUE);
|
cross(target, x + 4, y + 4, size - 8, Colors.BLUE);
|
||||||
}
|
}
|
||||||
@ -86,16 +86,16 @@ public class RadioButton extends BasicButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checked;
|
private boolean checked;
|
||||||
|
|
||||||
private RadioButtonGroup group = null;
|
private RadioButtonGroup group = null;
|
||||||
|
|
||||||
public RadioButton(String name, String label, Font labelFont, boolean check) {
|
public RadioButton(String name, String label, Font labelFont, boolean check) {
|
||||||
super(name, label, labelFont);
|
super(name, label, labelFont);
|
||||||
this.checked = check;
|
this.checked = check;
|
||||||
|
|
||||||
assert getChildren().size() == 1 : "RadioButton expects that BasicButton contains exactly one child";
|
assert getChildren().size() == 1 : "RadioButton expects that BasicButton contains exactly one child";
|
||||||
Component basicChild = getChild(0);
|
Component basicChild = getChild(0);
|
||||||
|
|
||||||
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
|
Group group = new Group(getName() + ".LabelAndTick", new LayoutHorizontal(0, 10));
|
||||||
removeChild(basicChild);
|
removeChild(basicChild);
|
||||||
setLayout(new LayoutAlign(0, 0.5f, 10));
|
setLayout(new LayoutAlign(0, 0.5f, 10));
|
||||||
@ -103,16 +103,17 @@ public class RadioButton extends BasicButton {
|
|||||||
group.addChild(new Tick());
|
group.addChild(new Tick());
|
||||||
group.addChild(basicChild);
|
group.addChild(basicChild);
|
||||||
addChild(group);
|
addChild(group);
|
||||||
|
|
||||||
addListener(KeyEvent.class, e -> {
|
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 (e.getKey() == GLFW.GLFW_KEY_LEFT || e.getKey() == GLFW.GLFW_KEY_UP) {
|
||||||
if (this.group != null) {
|
if (this.group != null) {
|
||||||
this.group.selectPrevious();
|
this.group.selectPrevious();
|
||||||
this.group.getSelected().takeFocus();
|
this.group.getSelected().takeFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (e.getKey() == GLFW.GLFW_KEY_RIGHT || e.getKey() == GLFW.GLFW_KEY_DOWN) {
|
} else if (e.getKey() == GLFW.GLFW_KEY_RIGHT || e.getKey() == GLFW.GLFW_KEY_DOWN) {
|
||||||
if (this.group != null) {
|
if (this.group != null) {
|
||||||
@ -121,85 +122,87 @@ public class RadioButton extends BasicButton {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
addAction(b -> setChecked(true));
|
addAction(b -> setChecked(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public RadioButton(String name, String label, Font labelFont) {
|
public RadioButton(String name, String label, Font labelFont) {
|
||||||
this(name, label, labelFont, false);
|
this(name, label, labelFont, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RadioButton(String name, String label, boolean check) {
|
public RadioButton(String name, String label, boolean check) {
|
||||||
this(name, label, new Font(), check);
|
this(name, label, new Font(), check);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RadioButton(String name, String label) {
|
public RadioButton(String name, String label) {
|
||||||
this(name, label, false);
|
this(name, label, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param group the group to set
|
* @param group the group to set
|
||||||
*/
|
*/
|
||||||
public RadioButton setGroup(RadioButtonGroup group) {
|
public RadioButton setGroup(RadioButtonGroup group) {
|
||||||
|
|
||||||
if (this.group != null) {
|
if (this.group != null) {
|
||||||
group.selectNext();
|
group.selectNext();
|
||||||
removeAction(group.listener);
|
removeAction(group.listener);
|
||||||
group.buttons.remove(this);
|
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;
|
this.group = group;
|
||||||
|
|
||||||
if (this.group != null) {
|
if (this.group != null) {
|
||||||
group.buttons.add(this);
|
group.buttons.add(this);
|
||||||
addAction(group.listener);
|
addAction(group.listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
setChecked(false);
|
setChecked(false);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the checked
|
* @return the checked
|
||||||
*/
|
*/
|
||||||
public boolean isChecked() {
|
public boolean isChecked() {
|
||||||
return checked;
|
return checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param checked the checked to set
|
* @param checked the checked to set
|
||||||
*/
|
*/
|
||||||
public void setChecked(boolean checked) {
|
public void setChecked(boolean checked) {
|
||||||
this.checked = checked;
|
this.checked = checked;
|
||||||
|
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
group.listener.accept(this); // Failsafe for manual invocations of setChecked()
|
group.listener.accept(this); // Failsafe for manual invocations of
|
||||||
|
// setChecked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Change label font color
|
// Change label font color
|
||||||
|
|
||||||
if (isPressed()) {
|
if (isPressed()) {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
||||||
} else {
|
} else {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
protected void postAssembleSelf(RenderTarget target) {
|
||||||
// Apply disable tint
|
// Apply disable tint
|
||||||
|
|
||||||
if (!isEnabled()) {
|
if (!isEnabled()) {
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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.EntityData;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
|
import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
|
||||||
import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
|
import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
|
||||||
|
import ru.windcorp.progressia.server.events.PlayerLeftEvent;
|
||||||
import ru.windcorp.progressia.test.TestContent;
|
import ru.windcorp.progressia.test.TestContent;
|
||||||
|
|
||||||
public class PlayerManager {
|
public class PlayerManager {
|
||||||
@ -47,6 +48,11 @@ public class PlayerManager {
|
|||||||
this.players.add(player);
|
this.players.add(player);
|
||||||
getServer().postEvent(new PlayerJoinedEvent.Immutable(getServer(), 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) {
|
public EntityData conjurePlayerEntity(String login) {
|
||||||
// TODO Live up to the name
|
// TODO Live up to the name
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.server;
|
package ru.windcorp.progressia.server;
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
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.common.util.crash.CrashReports;
|
||||||
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
|
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class ServerThread implements Runnable {
|
public class ServerThread implements Runnable {
|
||||||
|
|
||||||
private static final ThreadLocal<Server> SERVER_THREADS_MAP = new ThreadLocal<>();
|
private static final ThreadLocal<Server> SERVER_THREADS_MAP = new ThreadLocal<>();
|
||||||
|
|
||||||
|
private static boolean isShuttingDown;
|
||||||
|
|
||||||
public static Server getCurrentServer() {
|
public static Server getCurrentServer() {
|
||||||
return SERVER_THREADS_MAP.get();
|
return SERVER_THREADS_MAP.get();
|
||||||
}
|
}
|
||||||
@ -63,6 +66,7 @@ public class ServerThread implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
isShuttingDown = false;
|
||||||
ticker.start();
|
ticker.start();
|
||||||
executor.scheduleAtFixedRate(this, 0, 1000 / 20, TimeUnit.MILLISECONDS);
|
executor.scheduleAtFixedRate(this, 0, 1000 / 20, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
@ -70,6 +74,11 @@ public class ServerThread implements Runnable {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
if (isShuttingDown) {
|
||||||
|
getTicker().stop();
|
||||||
|
executor.shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
server.tick();
|
server.tick();
|
||||||
ticker.runOneTick();
|
ticker.runOneTick();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -78,13 +87,10 @@ public class ServerThread implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
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() {
|
public Server getServer() {
|
||||||
|
@ -92,6 +92,9 @@ public class ClientManager {
|
|||||||
public void disconnectClient(Client client) {
|
public void disconnectClient(Client client) {
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
clientsById.remove(client.getId());
|
clientsById.remove(client.getId());
|
||||||
|
if (client instanceof ClientPlayer) {
|
||||||
|
getServer().getPlayerManager().removePlayer(((ClientPlayer) client).getPlayer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processPackets() {
|
public void processPackets() {
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.test;
|
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.Colors;
|
||||||
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Checkbox;
|
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.RadioButton;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
|
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.menu.MenuLayer;
|
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 {
|
public class LayerButtonTest extends MenuLayer {
|
||||||
|
|
||||||
|
boolean alive = true;
|
||||||
|
|
||||||
public LayerButtonTest() {
|
public LayerButtonTest() {
|
||||||
super("ButtonTest");
|
super("ButtonTest");
|
||||||
|
|
||||||
addTitle();
|
addTitle();
|
||||||
|
|
||||||
Button blockableButton;
|
Button blockableButton;
|
||||||
getContent().addChild((blockableButton = new Button("BlockableButton", "Blockable")).addAction(b -> {
|
getContent().addChild((blockableButton = new Button("BlockableButton", "Blockable")).addAction(b -> {
|
||||||
System.out.println("Button Blockable!");
|
System.out.println("Button Blockable!");
|
||||||
}));
|
}));
|
||||||
blockableButton.setEnabled(false);
|
blockableButton.setEnabled(false);
|
||||||
|
|
||||||
getContent().addChild(new Checkbox("EnableButton", "Enable").addAction(b -> {
|
getContent().addChild(new Checkbox("EnableButton", "Enable").addAction(b -> {
|
||||||
blockableButton.setEnabled(((Checkbox) b).isChecked());
|
blockableButton.setEnabled(((Checkbox) b).isChecked());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
RadioButtonGroup group = new RadioButtonGroup().addAction(g -> {
|
RadioButtonGroup group = new RadioButtonGroup().addAction(g -> {
|
||||||
System.out.println("RBG! " + g.getSelected().getLabel().getCurrentText());
|
System.out.println("RBG! " + g.getSelected().getLabel().getCurrentText());
|
||||||
});
|
});
|
||||||
|
|
||||||
getContent().addChild(new RadioButton("RB1", "Moon").setGroup(group));
|
getContent().addChild(new RadioButton("RB1", "Moon").setGroup(group));
|
||||||
getContent().addChild(new RadioButton("RB2", "Type").setGroup(group));
|
getContent().addChild(new RadioButton("RB2", "Type").setGroup(group));
|
||||||
getContent().addChild(new RadioButton("RB3", "Ice").setGroup(group));
|
getContent().addChild(new RadioButton("RB3", "Ice").setGroup(group));
|
||||||
getContent().addChild(new RadioButton("RB4", "Cream").setGroup(group));
|
getContent().addChild(new RadioButton("RB4", "Cream").setGroup(group));
|
||||||
|
|
||||||
getContent().getChild(getContent().getChildren().size() - 1).setEnabled(false);
|
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 Label("Hint", new Font().withColor(Colors.LIGHT_GRAY), "This is a MenuLayer"));
|
||||||
|
|
||||||
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
|
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
|
||||||
getCloseAction().run();
|
getCloseAction().run();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
getContent().addChild(new Button("Quit", "Quit").addAction(b -> {
|
getContent().addChild(new Button("Menu", "Back To Menu").addAction(b -> {
|
||||||
System.exit(0);
|
getCloseAction().run();
|
||||||
|
|
||||||
|
Collection<Player> 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();
|
getContent().takeFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
src/main/java/ru/windcorp/progressia/test/LayerTestText.java
Normal file
29
src/main/java/ru/windcorp/progressia/test/LayerTestText.java
Normal file
@ -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<LayerTestText> remover;
|
||||||
|
|
||||||
|
public LayerTestText(String name, MutableString value, Consumer<LayerTestText> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
src/main/java/ru/windcorp/progressia/test/LayerTitle.java
Normal file
37
src/main/java/ru/windcorp/progressia/test/LayerTitle.java
Normal file
@ -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);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -46,10 +46,10 @@ import ru.windcorp.progressia.server.ServerState;
|
|||||||
|
|
||||||
public class TestPlayerControls {
|
public class TestPlayerControls {
|
||||||
|
|
||||||
private static final TestPlayerControls INSTANCE = new TestPlayerControls();
|
private static TestPlayerControls instance = new TestPlayerControls();
|
||||||
|
|
||||||
public static TestPlayerControls getInstance() {
|
public static TestPlayerControls getInstance() {
|
||||||
return INSTANCE;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final double MODE_SWITCH_MAX_DELAY = 300 * Units.MILLISECONDS;
|
private static final double MODE_SWITCH_MAX_DELAY = 300 * Units.MILLISECONDS;
|
||||||
@ -90,6 +90,10 @@ public class TestPlayerControls {
|
|||||||
|
|
||||||
private LayerTestGUI debugLayer = null;
|
private LayerTestGUI debugLayer = null;
|
||||||
private Runnable updateCallback = null;
|
private Runnable updateCallback = null;
|
||||||
|
|
||||||
|
public static void resetInstance() {
|
||||||
|
instance = new TestPlayerControls();
|
||||||
|
}
|
||||||
|
|
||||||
public void applyPlayerControls() {
|
public void applyPlayerControls() {
|
||||||
if (ClientState.getInstance() == null || !ClientState.getInstance().isReady()) {
|
if (ClientState.getInstance() == null || !ClientState.getInstance().isReady()) {
|
||||||
|
@ -15,17 +15,30 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.test;
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
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.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.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
@ -34,6 +47,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.state.IOContext;
|
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.DefaultChunkData;
|
||||||
import ru.windcorp.progressia.common.world.DecodingException;
|
import ru.windcorp.progressia.common.world.DecodingException;
|
||||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||||
@ -42,47 +56,342 @@ import ru.windcorp.progressia.server.Server;
|
|||||||
|
|
||||||
public class TestWorldDiskIO {
|
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 final Logger LOG = LogManager.getLogger("TestWorldDiskIO");
|
||||||
|
|
||||||
|
private static HashMap<HashableVec3i, MappedByteBuffer> 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<Vec3i,Vec3i> regions = new HashMap<Vec3i,Vec3i>();
|
||||||
|
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<HashableVec3i, MappedByteBuffer>();
|
||||||
|
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) {
|
public static void saveChunk(DefaultChunkData chunk, Server server) {
|
||||||
if (!ENABLE)
|
if (!ENABLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOG.debug(
|
|
||||||
"Saving {} {} {}",
|
|
||||||
chunk.getPosition().x,
|
|
||||||
chunk.getPosition().y,
|
|
||||||
chunk.getPosition().z
|
|
||||||
);
|
|
||||||
|
|
||||||
Files.createDirectories(SAVE_DIR);
|
if (currentFormat == 0) {
|
||||||
|
LOG.debug(
|
||||||
Path path = SAVE_DIR.resolve(
|
"Saving {} {} {}",
|
||||||
String.format(
|
|
||||||
"chunk_%+d_%+d_%+d.progressia_chunk",
|
|
||||||
chunk.getPosition().x,
|
chunk.getPosition().x,
|
||||||
chunk.getPosition().y,
|
chunk.getPosition().y,
|
||||||
chunk.getPosition().z
|
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<offsetBytes;i++)
|
||||||
|
{
|
||||||
|
readOffset.put(offsetBytes-i-1, (byte) (offset<<8));
|
||||||
|
}
|
||||||
|
output.put(readOffset);
|
||||||
|
/*output.position(outputLen);
|
||||||
|
|
||||||
|
while (output.size()<fullOffset+sectorSize*offset)
|
||||||
|
{
|
||||||
|
output.write(ByteBuffer.wrap( new byte[]{0} ));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//output.setLength(fullOffset + offset * sectorSize);
|
||||||
|
// output.write(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// int bytestoWrite = output.readInt();
|
||||||
|
// output.mark(sectorSize*sectorLength);
|
||||||
|
|
||||||
|
// BufferedOutputStream counter = new
|
||||||
|
// BufferedOutputStream(Files.newOutputStream(
|
||||||
|
// SAVE_DIR.resolve(tempFile)));
|
||||||
|
ByteArrayOutputStream tempDataStream = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream trueOutput = new DataOutputStream(
|
||||||
|
new DeflaterOutputStream(
|
||||||
|
new BufferedOutputStream(tempDataStream)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// CountingOutputStream countOutput = new
|
||||||
|
// CountingOutputStream(trueOutput);
|
||||||
|
|
||||||
|
// LOG.info("Before: {}",output.);
|
||||||
|
// trueOutput.writeBytes("uh try this");
|
||||||
|
// counter.
|
||||||
|
ChunkIO.save(chunk, trueOutput, IOContext.SAVE);
|
||||||
|
writeGenerationHint(chunk, trueOutput, server);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* while (counter.getCount()%sectorSize != 0) {
|
||||||
|
* counter.write(0);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// LOG.info("Wrote {} bytes to
|
||||||
|
// {},{},{}",trueOutput.size(),chunk.getPosition().x,chunk.getPosition().y,chunk.getPosition().z);
|
||||||
|
|
||||||
|
trueOutput.close();
|
||||||
|
|
||||||
|
byte tempData[] = tempDataStream.toByteArray();
|
||||||
|
|
||||||
|
output.position( fullOffset + sectorSize * offset);
|
||||||
|
output.put(ByteBuffer.wrap( tempData));
|
||||||
|
|
||||||
|
output.position(shortOffset + offsetBytes);
|
||||||
|
output.put(ByteBuffer.wrap( new byte[] {(byte) (tempData.length / sectorSize + 1)}));
|
||||||
|
// LOG.info("Used {} sectors",(int)
|
||||||
|
// tempData.length/sectorSize + 1);
|
||||||
|
|
||||||
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)
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MappedByteBuffer makeNew(Path path, Object hashObj) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");
|
||||||
|
FileChannel fc = raf.getChannel();
|
||||||
|
MappedByteBuffer output = fc.map(FileChannel.MapMode.READ_WRITE, 0, maxSize*chunksPerRegion);
|
||||||
|
output.limit(maxSize*chunksPerRegion);
|
||||||
|
mappedByteMap.put((HashableVec3i) hashObj, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
LOG.warn("bad things");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server)
|
private static void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint());
|
server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint());
|
||||||
@ -92,47 +401,197 @@ public class TestWorldDiskIO {
|
|||||||
if (!ENABLE)
|
if (!ENABLE)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Path path = SAVE_DIR.resolve(
|
if (currentFormat == -1) {
|
||||||
String.format(
|
Path formatPath = SAVE_DIR.resolve(formatFile);
|
||||||
"chunk_%+d_%+d_%+d.progressia_chunk",
|
File format = formatPath.toFile();
|
||||||
chunkPos.x,
|
|
||||||
chunkPos.y,
|
|
||||||
chunkPos.z
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!Files.exists(path)) {
|
if (format.exists()) {
|
||||||
LOG.debug(
|
String data = null;
|
||||||
"Not found {} {} {}",
|
try {
|
||||||
chunkPos.x,
|
Scanner reader = new Scanner(format);
|
||||||
chunkPos.y,
|
|
||||||
chunkPos.z
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
data = reader.next();
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] formatBytes = data.getBytes();
|
||||||
|
int formatNum = formatBytes[0] * 256 * 256 * 256 + formatBytes[1] * 256 * 256 + formatBytes[2] * 256
|
||||||
|
+ formatBytes[3];
|
||||||
|
|
||||||
|
setRegionSize(formatNum);
|
||||||
|
} else {
|
||||||
|
setRegionSize(bestFormat);
|
||||||
|
|
||||||
|
LOG.debug("Making new world with format {}", bestFormat);
|
||||||
|
|
||||||
|
BufferedWriter bw;
|
||||||
|
try {
|
||||||
|
bw = new BufferedWriter(new FileWriter(format));
|
||||||
|
|
||||||
|
int bfClone = bestFormat;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
bw.write(bfClone >> 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 {
|
if (currentFormat == 0) {
|
||||||
DefaultChunkData result = load(path, chunkPos, world, server);
|
|
||||||
|
|
||||||
LOG.debug(
|
Path path = SAVE_DIR.resolve(
|
||||||
"Loaded {} {} {}",
|
String.format(
|
||||||
chunkPos.x,
|
"chunk_%+d_%+d_%+d" + extension,
|
||||||
chunkPos.y,
|
chunkPos.x,
|
||||||
chunkPos.z
|
chunkPos.y,
|
||||||
|
chunkPos.z
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
if (!Files.exists(path)) {
|
||||||
} catch (Exception e) {
|
LOG.debug(
|
||||||
e.printStackTrace();
|
"Not found {} {} {}",
|
||||||
LOG.debug(
|
chunkPos.x,
|
||||||
"Could not load {} {} {}",
|
chunkPos.y,
|
||||||
chunkPos.x,
|
chunkPos.z
|
||||||
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)
|
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)
|
private static void readGenerationHint(DefaultChunkData chunk, DataInputStream input, Server server)
|
||||||
throws IOException,
|
throws IOException,
|
||||||
DecodingException {
|
DecodingException {
|
||||||
|
@ -21,4 +21,13 @@ LayerTestGUI.PlacementModeHint = (Blocks %s Tiles: Ctrl + Mouse Wheel)
|
|||||||
LayerTestGUI.IsFullscreen = Fullscreen: %5s (F11)
|
LayerTestGUI.IsFullscreen = Fullscreen: %5s (F11)
|
||||||
LayerTestGUI.IsVSync = VSync: %5s (F12)
|
LayerTestGUI.IsVSync = VSync: %5s (F12)
|
||||||
|
|
||||||
LayerButtonTest.Title = Button Test
|
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...
|
@ -21,4 +21,13 @@ LayerTestGUI.PlacementModeHint = (Блок %s плитки: Ctrl + прокру
|
|||||||
LayerTestGUI.IsFullscreen = Полный экран: %5s (F11)
|
LayerTestGUI.IsFullscreen = Полный экран: %5s (F11)
|
||||||
LayerTestGUI.IsVSync = Верт. синхр.: %5s (F12)
|
LayerTestGUI.IsVSync = Верт. синхр.: %5s (F12)
|
||||||
|
|
||||||
LayerButtonTest.Title = Тест Кнопок
|
LayerButtonTest.Title = Тест Кнопок
|
||||||
|
LayerButtonTest.Return = Back To Menu [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
|
||||||
|
LayerTitle.Title = Прогрессия
|
||||||
|
LayerTitle.Play = ???????
|
||||||
|
LayerTitle.Options = ????????
|
||||||
|
LayerTitle.Quit = ????????
|
||||||
|
|
||||||
|
LayerText.Load = Loading... (Change)
|
||||||
|
LayerText.Save = Saving...(Cahnsf)
|
@ -26,6 +26,7 @@
|
|||||||
<Logger name="Ticker Coordinator" level="DEBUG" />
|
<Logger name="Ticker Coordinator" level="DEBUG" />
|
||||||
<Logger name="Ticker 0" level="DEBUG" />
|
<Logger name="Ticker 0" level="DEBUG" />
|
||||||
-->
|
-->
|
||||||
|
<!-- <Logger name="TestWorldDiskIO" level="DEBUG" /> -->
|
||||||
|
|
||||||
<Root level="info">
|
<Root level="info">
|
||||||
<AppenderRef ref="FileLog" />
|
<AppenderRef ref="FileLog" />
|
||||||
|
Reference in New Issue
Block a user