diff --git a/src/main/java/xyz/samiker/theendlessweave/Main.java b/src/main/java/xyz/samiker/theendlessweave/Main.java index 537207a..ef1f9e0 100644 --- a/src/main/java/xyz/samiker/theendlessweave/Main.java +++ b/src/main/java/xyz/samiker/theendlessweave/Main.java @@ -6,7 +6,7 @@ import xyz.samiker.theendlessweave.client.assets.ManifestAssetManager; import xyz.samiker.theendlessweave.client.assets.ResourceManifest; import xyz.samiker.theendlessweave.client.screens.LoadingScreen; -import xyz.samiker.theendlessweave.core.settings.SettingsEnum; +import xyz.samiker.theendlessweave.client.settings.ClientSettings; import xyz.samiker.theendlessweave.core.settings.SettingsManager; import java.io.IOException; @@ -47,14 +47,14 @@ public ManifestAssetManager getAssetManager() { } public void applySettings() { - boolean isFullscreen = SettingsManager.getBoolean(SettingsEnum.FULLSCREEN); - boolean isBorderless = SettingsManager.getBoolean(SettingsEnum.BORDERLESS); + boolean isFullscreen = SettingsManager.getBoolean(ClientSettings.FULLSCREEN); + boolean isBorderless = SettingsManager.getBoolean(ClientSettings.BORDERLESS); if (isFullscreen) { Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); } else { - int width = Integer.parseInt(SettingsManager.getString(SettingsEnum.RESOLUTION).split("x")[0]); - int height = Integer.parseInt(SettingsManager.getString(SettingsEnum.RESOLUTION).split("x")[1]); + int width = Integer.parseInt(SettingsManager.getString(ClientSettings.RESOLUTION).split("x")[0]); + int height = Integer.parseInt(SettingsManager.getString(ClientSettings.RESOLUTION).split("x")[1]); Gdx.graphics.setWindowedMode(width, height); if (isBorderless) { diff --git a/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java b/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java index 16b0336..d3f54b4 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; import xyz.samiker.theendlessweave.Main; -import xyz.samiker.theendlessweave.core.settings.SettingsEnum; +import xyz.samiker.theendlessweave.client.settings.ClientSettings; import xyz.samiker.theendlessweave.core.settings.SettingsManager; import java.io.FileWriter; @@ -17,14 +17,17 @@ public static void main(String[] args) { Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); try { SettingsManager.loadSettings(); - String[] parts = SettingsManager.getString(SettingsEnum.RESOLUTION).split("x"); + String[] parts = SettingsManager.getString(ClientSettings.RESOLUTION).split("x"); config.setWindowedMode(Integer.parseInt(parts[0]), Integer.parseInt(parts[1])); - if (!SettingsManager.getBoolean(SettingsEnum.VSYNC)) { - config.useVsync(SettingsManager.getBoolean(SettingsEnum.VSYNC)); - config.setForegroundFPS(SettingsManager.getInt(SettingsEnum.FPS_LIMIT)); + if (SettingsManager.getBoolean(ClientSettings.VSYNC)) { + config.useVsync(SettingsManager.getBoolean(ClientSettings.VSYNC)); + } else { + config.setForegroundFPS(SettingsManager.getInt(ClientSettings.FPS_LIMIT)); } + config.setIdleFPS(15); + new Lwjgl3Application(new Main(), config); } catch (Throwable t) { logError(t); diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/GameScreen.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameScreen.java index 8bc2610..4e1ce5e 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/screens/GameScreen.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameScreen.java @@ -26,8 +26,9 @@ import xyz.samiker.theendlessweave.core.logic.GameState; import xyz.samiker.theendlessweave.core.logic.Loop; import xyz.samiker.theendlessweave.core.network.packets.PacketLoginResponse; -import xyz.samiker.theendlessweave.core.settings.SettingsEnum; +import xyz.samiker.theendlessweave.client.settings.ClientSettings; import xyz.samiker.theendlessweave.core.settings.SettingsManager; +import xyz.samiker.theendlessweave.server.ServerLauncher; import java.io.IOException; @@ -51,6 +52,7 @@ public class GameScreen implements Screen { private Touchpad moveStick; private Touchpad aimStick; + private TextButton attackBtn; private boolean isMobile; private Game gameLogic; @@ -70,8 +72,8 @@ public GameScreen(Main mainApp) { public void show() { batch = new SpriteBatch(); - float worldWidth = 1920; - float worldHeight = 1080; + float worldWidth = Gdx.graphics.getWidth(); + float worldHeight = Gdx.graphics.getHeight(); gameCamera = new OrthographicCamera(); gameViewport = new ExtendViewport(worldWidth, worldHeight, gameCamera); @@ -111,15 +113,14 @@ private void setupUI() { uiStage.addActor(hudTable); - isMobile = SettingsManager.getString(SettingsEnum.CONTROL).equals("touch");// || Main.isMobile(); + isMobile = !SettingsManager.getString(ClientSettings.CONTROL).equals("touch");// || Main.isMobile(); if (isMobile) { setupMobileControls(); } - setupPauseMenu(); debugLabel = new Label("", skin); - debugLabel.setPosition(10, Gdx.graphics.getHeight() - 30); + debugLabel.setPosition(10, Gdx.graphics.getHeight() / 2f); debugLabel.setAlignment(Align.left); uiStage.addActor(debugLabel); } @@ -132,9 +133,9 @@ private void setupMobileControls() { aimStick = new Touchpad(10, touchpadStyle); aimStick.setBounds(Gdx.graphics.getWidth() - 250, 50, 200, 200); - TextButton attackBtn = new TextButton("ATK", skin); + attackBtn = new TextButton("ATK", skin); attackBtn.setSize(100, 100); - attackBtn.setPosition(Gdx.graphics.getWidth() - 150, 300); + attackBtn.setPosition(Gdx.graphics.getWidth() - 150, Gdx.graphics.getHeight() - 300); attackBtn.addListener(new ClickListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { @@ -152,6 +153,14 @@ public void touchUp(InputEvent event, float x, float y, int pointer, int button) uiStage.addActor(attackBtn); } + private void updateUI() { + debugLabel.setPosition(10, Gdx.graphics.getHeight() / 2f); + if (isMobile) { + aimStick.setBounds(Gdx.graphics.getWidth() - 250, 50, 200, 200); + attackBtn.setPosition(Gdx.graphics.getWidth() - 150, Gdx.graphics.getHeight() - 300); + } + } + private void setupPauseMenu() { pauseMenuTable = new Table(); pauseMenuTable.setFillParent(true); @@ -191,6 +200,11 @@ private void connectToServer() { client = new GameClient(); new Thread(() -> { try { + String[] args = new String[]{"--integrated"}; //TODO: я что-то хотел сделать с этим. ладно + ServerLauncher.main(args); + while (true) { + if (ServerLauncher.isStarted) break; + } client.connect("127.0.0.1", (response) -> { Gdx.app.postRunnable(() -> initializeGameSession(response)); }); @@ -285,9 +299,7 @@ public void render(float delta) { public void resize(int width, int height) { gameViewport.update(width, height, false); uiStage.getViewport().update(width, height, true); - if (isMobile) { - setupMobileControls(); - } + updateUI(); } @Override diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java index e06869b..f93ef5d 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java @@ -11,7 +11,6 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.badlogic.gdx.utils.viewport.ScreenViewport; import xyz.samiker.theendlessweave.Main; -import xyz.samiker.theendlessweave.core.settings.SettingsManager; public class LoadingScreen extends ScreenAdapter { private final Main game; @@ -39,7 +38,6 @@ public void show() { table.add(statusLabel).padBottom(10).row(); table.add(progressBar).width(Gdx.graphics.getWidth() * 0.8f); - SettingsManager.loadSettings(); game.getAssetManager().queueAll(); assetsQueued = true; } diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/SettingsScreen.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/SettingsScreen.java index 8c89970..3a3485d 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/screens/SettingsScreen.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/SettingsScreen.java @@ -12,7 +12,7 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.badlogic.gdx.utils.viewport.ScreenViewport; import xyz.samiker.theendlessweave.Main; -import xyz.samiker.theendlessweave.core.settings.SettingsEnum; +import xyz.samiker.theendlessweave.client.settings.ClientSettings; import xyz.samiker.theendlessweave.core.settings.SettingsManager; public class SettingsScreen implements Screen { @@ -100,7 +100,7 @@ private void showGeneralSettings() { table.pad(20); Label dirLabel = new Label("Mods Directory:", skin); - TextField modsDirField = new TextField(SettingsManager.getString(SettingsEnum.MODS_DIR), skin); + TextField modsDirField = new TextField(SettingsManager.getString(ClientSettings.MODS_DIR), skin); TextButton chooseBtn = new TextButton("...", skin); TextButton saveBtn = new TextButton("Save", skin); @@ -119,7 +119,7 @@ public void clicked(InputEvent event, float x, float y) { saveBtn.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - SettingsManager.set(SettingsEnum.MODS_DIR, modsDirField.getText()); + SettingsManager.set(ClientSettings.MODS_DIR, modsDirField.getText()); SettingsManager.saveSettings(); System.out.println("General settings saved."); } @@ -143,26 +143,26 @@ private void showVideoSettings() { table.add(new Label("Resolution:", skin)); SelectBox resolutionSelect = new SelectBox<>(skin); resolutionSelect.setItems("1920x1200", "1920x1080", "1600x900", "1366x768", "1280x720", "800x600"); - resolutionSelect.setSelected(SettingsManager.getString(SettingsEnum.RESOLUTION)); + resolutionSelect.setSelected(SettingsManager.getString(ClientSettings.RESOLUTION)); table.add(resolutionSelect).width(200).row(); CheckBox fullscreenCheck = new CheckBox(" Fullscreen", skin); - fullscreenCheck.setChecked(SettingsManager.getBoolean(SettingsEnum.FULLSCREEN)); + fullscreenCheck.setChecked(SettingsManager.getBoolean(ClientSettings.FULLSCREEN)); CheckBox borderlessCheck = new CheckBox(" Borderless Window", skin); - borderlessCheck.setChecked(SettingsManager.getBoolean(SettingsEnum.BORDERLESS)); + borderlessCheck.setChecked(SettingsManager.getBoolean(ClientSettings.BORDERLESS)); table.add(fullscreenCheck).colspan(2).row(); table.add(borderlessCheck).colspan(2).row(); CheckBox vsyncCheck = new CheckBox(" VSync", skin); - vsyncCheck.setChecked(SettingsManager.getBoolean(SettingsEnum.VSYNC)); + vsyncCheck.setChecked(SettingsManager.getBoolean(ClientSettings.VSYNC)); table.add(vsyncCheck).colspan(2).row(); CheckBox fpsLimitCheck = new CheckBox(" Limit FPS", skin); - fpsLimitCheck.setChecked(SettingsManager.getBoolean(SettingsEnum.FPS_LIMIT_ENABLED)); + fpsLimitCheck.setChecked(SettingsManager.getBoolean(ClientSettings.FPS_LIMIT_ENABLED)); - TextField fpsField = new TextField(String.valueOf(SettingsManager.getInt(SettingsEnum.FPS_LIMIT)), skin); + TextField fpsField = new TextField(String.valueOf(SettingsManager.getInt(ClientSettings.FPS_LIMIT)), skin); fpsField.setTextFieldFilter(new TextField.TextFieldFilter.DigitsOnlyFilter()); fpsField.setDisabled(!fpsLimitCheck.isChecked()); @@ -180,7 +180,7 @@ public void changed(ChangeEvent event, Actor actor) { table.add(new Label("Brightness:", skin)); Slider brightnessSlider = new Slider(0, 100, 1, false, skin); - brightnessSlider.setValue((float) SettingsManager.getDouble(SettingsEnum.BRIGHTNESS)); + brightnessSlider.setValue((float) SettingsManager.getDouble(ClientSettings.BRIGHTNESS)); Label brightnessValLabel = new Label((int)brightnessSlider.getValue() + "%", skin); brightnessSlider.addListener(new ChangeListener() { @@ -199,15 +199,15 @@ public void changed(ChangeEvent event, Actor actor) { applyBtn.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - SettingsManager.set(SettingsEnum.RESOLUTION, resolutionSelect.getSelected()); - SettingsManager.set(SettingsEnum.FULLSCREEN, fullscreenCheck.isChecked()); - SettingsManager.set(SettingsEnum.BORDERLESS, borderlessCheck.isChecked()); - SettingsManager.set(SettingsEnum.VSYNC, vsyncCheck.isChecked()); - SettingsManager.set(SettingsEnum.FPS_LIMIT_ENABLED, fpsLimitCheck.isChecked()); + SettingsManager.set(ClientSettings.RESOLUTION, resolutionSelect.getSelected()); + SettingsManager.set(ClientSettings.FULLSCREEN, fullscreenCheck.isChecked()); + SettingsManager.set(ClientSettings.BORDERLESS, borderlessCheck.isChecked()); + SettingsManager.set(ClientSettings.VSYNC, vsyncCheck.isChecked()); + SettingsManager.set(ClientSettings.FPS_LIMIT_ENABLED, fpsLimitCheck.isChecked()); try { - SettingsManager.set(SettingsEnum.FPS_LIMIT, Integer.parseInt(fpsField.getText())); + SettingsManager.set(ClientSettings.FPS_LIMIT, Integer.parseInt(fpsField.getText())); } catch (NumberFormatException ignored) {} - SettingsManager.set(SettingsEnum.BRIGHTNESS, brightnessSlider.getValue()); + SettingsManager.set(ClientSettings.BRIGHTNESS, brightnessSlider.getValue()); SettingsManager.saveSettings(); applyGraphicsSettings(); @@ -220,13 +220,13 @@ public void clicked(InputEvent event, float x, float y) { } private void applyGraphicsSettings() { - String resStr = SettingsManager.getString(SettingsEnum.RESOLUTION); + String resStr = SettingsManager.getString(ClientSettings.RESOLUTION); String[] parts = resStr.split("x"); int width = Integer.parseInt(parts[0]); int height = Integer.parseInt(parts[1]); - boolean isFullscreen = SettingsManager.getBoolean(SettingsEnum.FULLSCREEN); - boolean isBorderless = SettingsManager.getBoolean(SettingsEnum.BORDERLESS); - boolean vsync = SettingsManager.getBoolean(SettingsEnum.VSYNC); + boolean isFullscreen = SettingsManager.getBoolean(ClientSettings.FULLSCREEN); + boolean isBorderless = SettingsManager.getBoolean(ClientSettings.BORDERLESS); + boolean vsync = SettingsManager.getBoolean(ClientSettings.VSYNC); Gdx.graphics.setVSync(vsync); @@ -250,8 +250,8 @@ private void applyGraphicsSettings() { } } - if (SettingsManager.getBoolean(SettingsEnum.FPS_LIMIT_ENABLED)) { - Gdx.graphics.setForegroundFPS(SettingsManager.getInt(SettingsEnum.FPS_LIMIT)); + if (SettingsManager.getBoolean(ClientSettings.FPS_LIMIT_ENABLED)) { + Gdx.graphics.setForegroundFPS(SettingsManager.getInt(ClientSettings.FPS_LIMIT)); } else { Gdx.graphics.setForegroundFPS(0); } diff --git a/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsEnum.java b/src/main/java/xyz/samiker/theendlessweave/client/settings/ClientSettings.java similarity index 84% rename from src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsEnum.java rename to src/main/java/xyz/samiker/theendlessweave/client/settings/ClientSettings.java index dc0897c..9c79a55 100644 --- a/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsEnum.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/settings/ClientSettings.java @@ -1,6 +1,6 @@ -package xyz.samiker.theendlessweave.core.settings; +package xyz.samiker.theendlessweave.client.settings; -public enum SettingsEnum { +public enum ClientSettings { RESOLUTION("video.resolution", "1280x720"), FULLSCREEN("video.fullscreen", false), BORDERLESS("video.borderless", false), @@ -16,11 +16,10 @@ public enum SettingsEnum { MUSIC_VOLUME("audio.music", 100), SFX_VOLUME("audio.sfx", 100); - private final String key; private final Object defaultValue; - SettingsEnum(String key, Object defaultValue) { + ClientSettings(String key, Object defaultValue) { this.key = key; this.defaultValue = defaultValue; } diff --git a/src/main/java/xyz/samiker/theendlessweave/core/logic/Game.java b/src/main/java/xyz/samiker/theendlessweave/core/logic/Game.java index 4950be5..3d29f9c 100644 --- a/src/main/java/xyz/samiker/theendlessweave/core/logic/Game.java +++ b/src/main/java/xyz/samiker/theendlessweave/core/logic/Game.java @@ -24,7 +24,7 @@ public class Game { private final PerformanceMonitor profiler = new PerformanceMonitor(); private final Array logicSystems = new Array<>(5); - private final Array renderSystems = new Array<>(7); + private final Array renderSystems = new Array<>(10); private final Array entities = new Array<>(2048); public final Array queueAddEntities = new Array<>(512); private int nextEntityId = 0; diff --git a/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsManager.java b/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsManager.java index ba8bd9b..791ddbb 100644 --- a/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsManager.java +++ b/src/main/java/xyz/samiker/theendlessweave/core/settings/SettingsManager.java @@ -1,5 +1,7 @@ package xyz.samiker.theendlessweave.core.settings; +import xyz.samiker.theendlessweave.client.settings.ClientSettings; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -35,21 +37,21 @@ public static void saveSettings() { System.err.println("Ошибка сохранения: " + e.getMessage()); } } - public static void set(SettingsEnum setting, Object value) { + public static void set(ClientSettings setting, Object value) { properties.setProperty(setting.getKey(), String.valueOf(value)); } - public static String getString(SettingsEnum setting) { + public static String getString(ClientSettings setting) { return properties.getProperty(setting.getKey(), (String) setting.getDefaultValue()); } - public static boolean getBoolean(SettingsEnum setting) { + public static boolean getBoolean(ClientSettings setting) { String val = properties.getProperty(setting.getKey()); if (val == null) return (boolean) setting.getDefaultValue(); return Boolean.parseBoolean(val); } - public static int getInt(SettingsEnum setting) { + public static int getInt(ClientSettings setting) { String val = properties.getProperty(setting.getKey()); if (val == null) return (int) setting.getDefaultValue(); try { @@ -59,7 +61,7 @@ public static int getInt(SettingsEnum setting) { } } - public static double getDouble(SettingsEnum setting) { + public static double getDouble(ClientSettings setting) { String val = properties.getProperty(setting.getKey()); if (val == null) return (double) setting.getDefaultValue(); try { @@ -78,9 +80,12 @@ public static void setModEnabled(String modName, boolean isEnabled) { saveSettings(); } + /** + * @Deprecated вероятно, больше не нужен в силу Gdx.graphic + */ public static class Resolution { private final String resolution; - private final Map width_height = new HashMap<>(); + private static final Map width_height = new HashMap<>(); public Resolution(String resolution) { this.resolution = resolution; @@ -95,28 +100,28 @@ private void parse() { } catch (NumberFormatException e) { /*ignore*/ } } } - public void setResolution(String resolution) { + public static void setResolution(String resolution) { String[] parts = resolution.split("x"); if (parts.length == 2) { try { - this.width_height.put("width", Integer.parseInt(parts[0])); - this.width_height.put("height", Integer.parseInt(parts[1])); + width_height.put("width", Integer.parseInt(parts[0])); + width_height.put("height", Integer.parseInt(parts[1])); } catch (NumberFormatException e) { /*ignore*/ } } } - public int getWidth() { - return this.width_height.get("width"); + public static int getWidth() { + return width_height.get("width"); } - public int getHeight() { - return this.width_height.get("height"); + public static int getHeight() { + return width_height.get("height"); } - public void setWidth(int width) { - this.width_height.put("width", width); + public static void setWidth(int width) { + width_height.put("width", width); } - public void setHeight(int height) { - System.out.println(this.width_height); - this.width_height.put("height", height); + public static void setHeight(int height) { + System.out.println(width_height); + width_height.put("height", height); } @Override diff --git a/src/main/java/xyz/samiker/theendlessweave/server/ServerLauncher.java b/src/main/java/xyz/samiker/theendlessweave/server/ServerLauncher.java index ee630f8..8eeafb4 100644 --- a/src/main/java/xyz/samiker/theendlessweave/server/ServerLauncher.java +++ b/src/main/java/xyz/samiker/theendlessweave/server/ServerLauncher.java @@ -14,41 +14,24 @@ import java.util.concurrent.Executors; public class ServerLauncher { + private static GameServer server; + + public static boolean isIntegrated = false; + public static boolean isStarted = false; + public static void main(String[] args) { - Random rnd = new Random(); - Game game = createServerGame(new GameData( - MapGeneratorSettings.openMap(), 200, 200, rnd.nextLong()) - ); - GameServer server = new GameServer(game); - ServerLoop loop = new ServerLoop(game); + if (args.length > 0 && args[0].equalsIgnoreCase("--integrated")) isIntegrated = true; + init(); + } - initSystems(game, server); - loop.start(); + public static void init() { + server = new GameServer(); try { server.start(); + isStarted = true; + System.out.println("Server started as " + (isIntegrated ? "integrated" : "dedicated")); } catch (IOException e) { throw new RuntimeException("Unable to start server"+e); } - - } - - public static Game createServerGame(GameData data) { - return new Game(data); - } - - public static void initSystems(Game game, GameServer server) { - var map = game.getGameMap(); - ExecutorService aiExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - - game.addLogicSystem(new ServerInputSystem(server, game)); - game.addLogicSystem(new ServerDebugSystem(game.getProfiler())); - game.addLogicSystem(new WeaponSystem()); - game.addLogicSystem(new AISystem(map, aiExecutor)); - game.addLogicSystem(new AttackSystem(game)); - game.addLogicSystem(new ProjectileSystem()); - game.addLogicSystem(new MovementSystem(map)); - game.addLogicSystem(new DamageSystem()); - game.addLogicSystem(new ServerSnapshotSenderSystem(server)); - game.addLogicSystem(new ServerEntityEventSystem(server, game)); } } diff --git a/src/main/java/xyz/samiker/theendlessweave/server/ServerLoop.java b/src/main/java/xyz/samiker/theendlessweave/server/ServerLoop.java index ac2298f..646c291 100644 --- a/src/main/java/xyz/samiker/theendlessweave/server/ServerLoop.java +++ b/src/main/java/xyz/samiker/theendlessweave/server/ServerLoop.java @@ -6,7 +6,7 @@ import static xyz.samiker.theendlessweave.core.utils.Constants.TIME_PER_TICK; public class ServerLoop { - private final Game game; + private Game game; private Thread logicThread; private volatile boolean running = false; @@ -73,6 +73,16 @@ private void runLogicLoop() { } } + public void dispose() { + stop(); + this.logicThread = null; + this.game = null; + } + + public void setGame(Game game) { + this.game = game; + } + public void togglePause() { currentState = (currentState == GameState.PLAYING) ? GameState.PAUSED : GameState.PLAYING; } diff --git a/src/main/java/xyz/samiker/theendlessweave/server/network/GameServer.java b/src/main/java/xyz/samiker/theendlessweave/server/network/GameServer.java index ca4633b..bd89bf3 100644 --- a/src/main/java/xyz/samiker/theendlessweave/server/network/GameServer.java +++ b/src/main/java/xyz/samiker/theendlessweave/server/network/GameServer.java @@ -3,27 +3,35 @@ import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.Listener; import com.esotericsoftware.kryonet.Server; +import xyz.samiker.theendlessweave.core.GameData; import xyz.samiker.theendlessweave.core.entities.Entity; import xyz.samiker.theendlessweave.core.entities.components.PositionComponent; +import xyz.samiker.theendlessweave.core.gamemap.MapGeneratorSettings; import xyz.samiker.theendlessweave.core.logic.Game; import xyz.samiker.theendlessweave.core.network.NetworkRegister; import xyz.samiker.theendlessweave.core.network.packets.PacketInput; import xyz.samiker.theendlessweave.core.network.packets.PacketLoginRequest; import xyz.samiker.theendlessweave.core.network.packets.PacketLoginResponse; import xyz.samiker.theendlessweave.core.network.packets.PacketSnapshot; +import xyz.samiker.theendlessweave.server.ServerLauncher; +import xyz.samiker.theendlessweave.server.ServerLoop; +import xyz.samiker.theendlessweave.server.systems.*; import java.io.IOException; import java.util.Map; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class GameServer { private final Server server; - private final Game game; - public final Map players = new ConcurrentHashMap<>(); + private Game game; + private ServerLoop loop; + public final Map players = new ConcurrentHashMap<>(4); public final Map inputs = new ConcurrentHashMap<>(); - public GameServer(Game game) { - this.game = game; + public GameServer() { this.server = new Server(32768, 32768); } @@ -31,6 +39,7 @@ public void start() throws IOException { NetworkRegister.register(server); server.bind(54555, 54777); server.start(); + initGame(); server.addListener(new Listener() { @Override @@ -45,22 +54,32 @@ public void received(Connection connection, Object object) { @Override public void disconnected(Connection connection) { - Integer entityId = players.remove(connection.getID()); - if (entityId != null) { - // TODO: Удалить сущность игрока из мира (game.removeEntity(entityId)) - System.out.println("Player " + entityId + " disconnected."); + Entity entity = players.remove(connection.getID()); + if (entity != null) { + entity.dead = true; + System.out.println("Player " + entity.id + " disconnected."); + if (players.isEmpty() && ServerLauncher.isIntegrated) { + //TODO: логика сохранения когда-нибудь данных в будущем, но вероятно это стоит делать на клиенте (?) + System.out.println("Closing integrated server"); + dispose(); + } } } }); } + public void dispose() { + server.stop(); + loop.dispose(); + } + private void handleLogin(Connection connection, PacketLoginRequest req) { System.out.println("Login Request: " + req.username); Entity player = game.createPlayer(); PositionComponent pos = player.getComponent(PositionComponent.class); - players.put(connection.getID(), player.id); + players.put(connection.getID(), player); PacketLoginResponse response = new PacketLoginResponse(); response.accepted = true; @@ -79,4 +98,42 @@ public void sendToAll(Object object) { server.sendToAllTCP(object); } } + + public void initGame(Game game) { + this.game = game; + loop = new ServerLoop(game); + initSystems(); + loop.start(); + } + + public void initGame(GameData data) { + initGame(createServerGame(data)); + } + + public void initGame() { + Random rnd = new Random(); + initGame(createServerGame(new GameData( + MapGeneratorSettings.openMap(), 200, 200, rnd.nextLong()) + )); + } + + public Game createServerGame(GameData data) { + return new Game(data); + } + + public void initSystems() { + var map = game.getGameMap(); + ExecutorService aiExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + game.addLogicSystem(new ServerInputSystem(this, game)); + game.addLogicSystem(new ServerDebugSystem(game.getProfiler())); + game.addLogicSystem(new WeaponSystem()); + game.addLogicSystem(new AISystem(map, aiExecutor)); + game.addLogicSystem(new AttackSystem(game)); + game.addLogicSystem(new ProjectileSystem()); + game.addLogicSystem(new MovementSystem(map)); + game.addLogicSystem(new DamageSystem()); + game.addLogicSystem(new ServerSnapshotSenderSystem(this)); + game.addLogicSystem(new ServerEntityEventSystem(this, game)); + } } \ No newline at end of file diff --git a/src/main/java/xyz/samiker/theendlessweave/server/settings/ServerSettings.java b/src/main/java/xyz/samiker/theendlessweave/server/settings/ServerSettings.java new file mode 100644 index 0000000..7caa44c --- /dev/null +++ b/src/main/java/xyz/samiker/theendlessweave/server/settings/ServerSettings.java @@ -0,0 +1,16 @@ +package xyz.samiker.theendlessweave.server.settings; + +public enum ServerSettings { + MODS_DIR("general.mods_dir", ""); + + private final String key; + private final Object defaultValue; + + ServerSettings(String key, Object defaultValue) { + this.key = key; + this.defaultValue = defaultValue; + } + + public String getKey() { return key; } + public Object getDefaultValue() { return defaultValue; } +} diff --git a/src/main/java/xyz/samiker/theendlessweave/server/systems/ServerInputSystem.java b/src/main/java/xyz/samiker/theendlessweave/server/systems/ServerInputSystem.java index cd040e9..2001464 100644 --- a/src/main/java/xyz/samiker/theendlessweave/server/systems/ServerInputSystem.java +++ b/src/main/java/xyz/samiker/theendlessweave/server/systems/ServerInputSystem.java @@ -30,10 +30,9 @@ public void update(Array entities, double dt) { for (Map.Entry entry : server.inputs.entrySet()) { int connectionId = entry.getKey(); PacketInput input = entry.getValue(); - Integer entityId = server.players.get(connectionId); - if (entityId == null) continue; - - getPlayerCache(entities, entityId); + Entity entity = server.players.get(connectionId); + if (entity == null) continue; + getPlayerCache(entities, entity.id); if (playerEntity != null) { applyInput(playerEntity, input); }