Added config.
This commit is contained in:
parent
de6e50264b
commit
725659a4a4
|
@ -41,6 +41,12 @@
|
||||||
<artifactId>zero-allocation-hashing</artifactId>
|
<artifactId>zero-allocation-hashing</artifactId>
|
||||||
<version>0.15</version>
|
<version>0.15</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
<version>1.30</version>
|
||||||
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
|
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package nl.andrewl.aos_core.config;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class Config {
|
||||||
|
private static final Yaml yaml = new Yaml();
|
||||||
|
|
||||||
|
private Config() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a configuration YAML object from the first available path.
|
||||||
|
* @param configType The type of the configuration object.
|
||||||
|
* @param paths The paths to load from.
|
||||||
|
* @param fallback A default configuration object to use if no config could
|
||||||
|
* be loaded from any of the paths.
|
||||||
|
* @return The configuration object.
|
||||||
|
* @param <T> The type of the configuration object.
|
||||||
|
*/
|
||||||
|
public static <T> T loadConfig(Class<T> configType, List<Path> paths, T fallback) {
|
||||||
|
for (var path : paths) {
|
||||||
|
if (Files.exists(path) && Files.isRegularFile(path) && Files.isReadable(path)) {
|
||||||
|
try (var reader = Files.newBufferedReader(path)) {
|
||||||
|
return yaml.loadAs(reader, configType);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T loadConfig(Class<T> configType, List<Path> paths) {
|
||||||
|
var cfg = loadConfig(configType, paths, null);
|
||||||
|
if (cfg == null) {
|
||||||
|
throw new RuntimeException("Could not load config from any of the supplied paths.");
|
||||||
|
}
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T loadConfig(Class<T> configType, T fallback, Path... paths) {
|
||||||
|
return loadConfig(configType, List.of(paths), fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Path> getCommonConfigPaths() {
|
||||||
|
List<Path> paths = new ArrayList<>();
|
||||||
|
paths.add(Path.of("config.yaml"));
|
||||||
|
paths.add(Path.of("config.yml"));
|
||||||
|
paths.add(Path.of("cfg.yaml"));
|
||||||
|
paths.add(Path.of("cfg.yml"));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package nl.andrewl.aos2_server;
|
package nl.andrewl.aos2_server;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_server.config.ServerConfig;
|
||||||
|
import nl.andrewl.aos_core.config.Config;
|
||||||
import nl.andrewl.aos_core.model.world.World;
|
import nl.andrewl.aos_core.model.world.World;
|
||||||
import nl.andrewl.aos_core.model.world.WorldIO;
|
|
||||||
import nl.andrewl.aos_core.model.world.Worlds;
|
import nl.andrewl.aos_core.model.world.Worlds;
|
||||||
import nl.andrewl.aos_core.net.UdpReceiver;
|
import nl.andrewl.aos_core.net.UdpReceiver;
|
||||||
import nl.andrewl.aos_core.net.udp.ClientInputState;
|
import nl.andrewl.aos_core.net.udp.ClientInputState;
|
||||||
|
@ -15,6 +16,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
public class Server implements Runnable {
|
public class Server implements Runnable {
|
||||||
|
@ -23,18 +25,19 @@ public class Server implements Runnable {
|
||||||
private final ServerSocket serverSocket;
|
private final ServerSocket serverSocket;
|
||||||
private final DatagramSocket datagramSocket;
|
private final DatagramSocket datagramSocket;
|
||||||
private volatile boolean running;
|
private volatile boolean running;
|
||||||
|
private final ServerConfig config;
|
||||||
private final PlayerManager playerManager;
|
private final PlayerManager playerManager;
|
||||||
private final World world;
|
private final World world;
|
||||||
private final WorldUpdater worldUpdater;
|
private final WorldUpdater worldUpdater;
|
||||||
|
|
||||||
public Server() throws IOException {
|
public Server(ServerConfig config) throws IOException {
|
||||||
this.serverSocket = new ServerSocket(25565, 5);
|
this.config = config;
|
||||||
|
this.serverSocket = new ServerSocket(config.port, config.connectionBacklog);
|
||||||
this.serverSocket.setReuseAddress(true);
|
this.serverSocket.setReuseAddress(true);
|
||||||
this.datagramSocket = new DatagramSocket(25565);
|
this.datagramSocket = new DatagramSocket(config.port);
|
||||||
this.datagramSocket.setReuseAddress(true);
|
this.datagramSocket.setReuseAddress(true);
|
||||||
this.playerManager = new PlayerManager();
|
this.playerManager = new PlayerManager();
|
||||||
this.worldUpdater = new WorldUpdater(this, 20);
|
this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond);
|
||||||
this.world = Worlds.testingWorld();
|
this.world = Worlds.testingWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +110,10 @@ public class Server implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerConfig getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
@ -116,6 +123,11 @@ public class Server implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
new Server().run();
|
List<Path> configPaths = Config.getCommonConfigPaths();
|
||||||
|
if (args.length > 0) {
|
||||||
|
configPaths.add(Path.of(args[0].trim()));
|
||||||
|
}
|
||||||
|
ServerConfig cfg = Config.loadConfig(ServerConfig.class, configPaths, new ServerConfig());
|
||||||
|
new Server(cfg).run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewl.aos2_server;
|
package nl.andrewl.aos2_server;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_server.config.ServerConfig;
|
||||||
import nl.andrewl.aos_core.model.Player;
|
import nl.andrewl.aos_core.model.Player;
|
||||||
import nl.andrewl.aos_core.model.world.World;
|
import nl.andrewl.aos_core.model.world.World;
|
||||||
import nl.andrewl.aos_core.net.udp.ChunkUpdateMessage;
|
import nl.andrewl.aos_core.net.udp.ChunkUpdateMessage;
|
||||||
|
@ -24,17 +25,6 @@ public class ServerPlayer extends Player {
|
||||||
public static final float WIDTH = 0.75f;
|
public static final float WIDTH = 0.75f;
|
||||||
public static final float RADIUS = WIDTH / 2f;
|
public static final float RADIUS = WIDTH / 2f;
|
||||||
|
|
||||||
public static final float GRAVITY = 9.81f * 3;
|
|
||||||
public static final float SPEED_NORMAL = 4f;
|
|
||||||
public static final float SPEED_CROUCH = 1.5f;
|
|
||||||
public static final float SPEED_SPRINT = 9f;
|
|
||||||
public static final float MOVEMENT_ACCELERATION = 2f;
|
|
||||||
public static final float MOVEMENT_DECELERATION = 1f;
|
|
||||||
public static final float JUMP_SPEED = 8f;
|
|
||||||
|
|
||||||
public static final int BLOCK_REMOVE_COOLDOWN = 250;
|
|
||||||
public static final int BLOCK_PLACE_COOLDOWN = 100;
|
|
||||||
|
|
||||||
private ClientInputState lastInputState;
|
private ClientInputState lastInputState;
|
||||||
private long lastBlockRemovedAt = 0;
|
private long lastBlockRemovedAt = 0;
|
||||||
private long lastBlockPlacedAt = 0;
|
private long lastBlockPlacedAt = 0;
|
||||||
|
@ -62,7 +52,7 @@ public class ServerPlayer extends Player {
|
||||||
public void tick(float dt, World world, Server server) {
|
public void tick(float dt, World world, Server server) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
// Check for breaking blocks.
|
// Check for breaking blocks.
|
||||||
if (lastInputState.hitting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) {
|
if (lastInputState.hitting() && now - lastBlockRemovedAt > server.getConfig().actions.blockRemoveCooldown * 1000) {
|
||||||
Vector3f eyePos = new Vector3f(position);
|
Vector3f eyePos = new Vector3f(position);
|
||||||
eyePos.y += getEyeHeight();
|
eyePos.y += getEyeHeight();
|
||||||
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
|
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
|
||||||
|
@ -73,7 +63,7 @@ public class ServerPlayer extends Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for placing blocks.
|
// Check for placing blocks.
|
||||||
if (lastInputState.interacting() && now - lastBlockPlacedAt > BLOCK_PLACE_COOLDOWN) {
|
if (lastInputState.interacting() && now - lastBlockPlacedAt > server.getConfig().actions.blockPlaceCooldown * 1000) {
|
||||||
Vector3f eyePos = new Vector3f(position);
|
Vector3f eyePos = new Vector3f(position);
|
||||||
eyePos.y += getEyeHeight();
|
eyePos.y += getEyeHeight();
|
||||||
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
|
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
|
||||||
|
@ -85,21 +75,21 @@ public class ServerPlayer extends Player {
|
||||||
server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(placePos, world));
|
server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(placePos, world));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tickMovement(dt, world);
|
tickMovement(dt, world, server.getConfig().physics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickMovement(float dt, World world) {
|
private void tickMovement(float dt, World world, ServerConfig.PhysicsConfig config) {
|
||||||
updated = false; // Reset the updated flag. This will be set to true if the player was updated in this tick.
|
updated = false; // Reset the updated flag. This will be set to true if the player was updated in this tick.
|
||||||
boolean grounded = isGrounded(world);
|
boolean grounded = isGrounded(world);
|
||||||
tickHorizontalVelocity(grounded);
|
tickHorizontalVelocity(config, grounded);
|
||||||
|
|
||||||
if (isGrounded(world)) {
|
if (isGrounded(world)) {
|
||||||
if (lastInputState.jumping()) {
|
if (lastInputState.jumping()) {
|
||||||
velocity.y = JUMP_SPEED * (lastInputState.sprinting() ? 1.25f : 1f);
|
velocity.y = config.jumpVerticalSpeed * (lastInputState.sprinting() ? 1.25f : 1f);
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
velocity.y -= GRAVITY * dt;
|
velocity.y -= config.gravity * dt;
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +103,7 @@ public class ServerPlayer extends Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickHorizontalVelocity(boolean doDeceleration) {
|
private void tickHorizontalVelocity(ServerConfig.PhysicsConfig config, boolean doDeceleration) {
|
||||||
Vector3f horizontalVelocity = new Vector3f(
|
Vector3f horizontalVelocity = new Vector3f(
|
||||||
velocity.x == velocity.x ? velocity.x : 0f,
|
velocity.x == velocity.x ? velocity.x : 0f,
|
||||||
0,
|
0,
|
||||||
|
@ -127,15 +117,15 @@ public class ServerPlayer extends Player {
|
||||||
if (acceleration.lengthSquared() > 0) {
|
if (acceleration.lengthSquared() > 0) {
|
||||||
acceleration.normalize();
|
acceleration.normalize();
|
||||||
acceleration.rotateAxis(orientation.x, 0, 1, 0);
|
acceleration.rotateAxis(orientation.x, 0, 1, 0);
|
||||||
acceleration.mul(MOVEMENT_ACCELERATION);
|
acceleration.mul(config.movementAcceleration);
|
||||||
horizontalVelocity.add(acceleration);
|
horizontalVelocity.add(acceleration);
|
||||||
final float maxSpeed;
|
final float maxSpeed;
|
||||||
if (lastInputState.crouching()) {
|
if (lastInputState.crouching()) {
|
||||||
maxSpeed = SPEED_CROUCH;
|
maxSpeed = config.crouchingSpeed;
|
||||||
} else if (lastInputState.sprinting()) {
|
} else if (lastInputState.sprinting()) {
|
||||||
maxSpeed = SPEED_SPRINT;
|
maxSpeed = config.sprintingSpeed;
|
||||||
} else {
|
} else {
|
||||||
maxSpeed = SPEED_NORMAL;
|
maxSpeed = config.walkingSpeed;
|
||||||
}
|
}
|
||||||
if (horizontalVelocity.length() > maxSpeed) {
|
if (horizontalVelocity.length() > maxSpeed) {
|
||||||
horizontalVelocity.normalize(maxSpeed);
|
horizontalVelocity.normalize(maxSpeed);
|
||||||
|
@ -144,7 +134,7 @@ public class ServerPlayer extends Player {
|
||||||
} else if (doDeceleration && horizontalVelocity.lengthSquared() > 0) {
|
} else if (doDeceleration && horizontalVelocity.lengthSquared() > 0) {
|
||||||
Vector3f deceleration = new Vector3f(horizontalVelocity)
|
Vector3f deceleration = new Vector3f(horizontalVelocity)
|
||||||
.negate().normalize()
|
.negate().normalize()
|
||||||
.mul(Math.min(horizontalVelocity.length(), MOVEMENT_DECELERATION));
|
.mul(Math.min(horizontalVelocity.length(), config.movementDeceleration));
|
||||||
horizontalVelocity.add(deceleration);
|
horizontalVelocity.add(deceleration);
|
||||||
if (horizontalVelocity.length() < 0.1f) {
|
if (horizontalVelocity.length() < 0.1f) {
|
||||||
horizontalVelocity.set(0);
|
horizontalVelocity.set(0);
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package nl.andrewl.aos2_server.config;
|
||||||
|
|
||||||
|
public class ServerConfig {
|
||||||
|
public int port = 25565;
|
||||||
|
public int connectionBacklog = 5;
|
||||||
|
public float ticksPerSecond = 20.0f;
|
||||||
|
public PhysicsConfig physics = new PhysicsConfig();
|
||||||
|
public ActionsConfig actions = new ActionsConfig();
|
||||||
|
|
||||||
|
public static class PhysicsConfig {
|
||||||
|
public float gravity = 9.81f * 3;
|
||||||
|
public float walkingSpeed = 4;
|
||||||
|
public float crouchingSpeed = 1.5f;
|
||||||
|
public float sprintingSpeed = 9;
|
||||||
|
public float movementAcceleration = 2;
|
||||||
|
public float movementDeceleration = 1;
|
||||||
|
public float jumpVerticalSpeed = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ActionsConfig {
|
||||||
|
public float blockRemoveCooldown = 0.25f;
|
||||||
|
public float blockPlaceCooldown = 0.1f;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue