From 9e42344d3bc21976ee3fd5e561e918830004a56a Mon Sep 17 00:00:00 2001 From: Sten Laane <21343173+StenAL@users.noreply.github.com> Date: Sun, 4 Jun 2023 19:50:37 +0100 Subject: [PATCH] Server: Add CLI option to specify where to look for tracks This way, the jar and configuration can be stored in separate file hierarchies. This is useful when you have multiple track directories, e.g. a small one with a selection of tracks and a larger one. It's also useful for starting a server with ssh without having to pollute your server's home directory (`ssh user@host java -jar server.jar --tracks-dir=/my/path/tracks`) --- README.md | 7 +++-- .../java/org/moparforia/server/Launcher.java | 14 +++++++-- .../java/org/moparforia/server/Server.java | 8 +++-- .../moparforia/server/LauncherCLITest.java | 31 +++++++++++-------- .../shared/tracks/TrackManager.java | 2 +- .../filesystem/FileSystemStatsManager.java | 11 ++++--- .../filesystem/FileSystemTrackManager.java | 18 +++++------ .../FileSystemStatsManagerTest.java | 4 +-- .../FileSystemTrackManagerTest.java | 8 ++--- .../shared/tracks/filesystem/VersionTest.java | 2 +- .../tracks/parsers/TrackConverterTest.java | 2 +- 11 files changed, 63 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 73936c2e..e4a22823 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Run `mvn install` in the root directory. This builds `client`, `server` and `edi ### Running First, the server application has to be started as it provides resources like sounds, maps and textures which are required for "offline" modes, too. -As I could not manage to include the tracks inside the compiled JAR archive, the `tracks` directory has to be located at the same folder where the `server.jar` is located! There is a symbolic link in the `server/` directory which will likely not work on Windows systems. Please remove it and copy the directory instead! +As I could not manage to include the tracks inside the compiled JAR archive, the `tracks` directory has to be located at the same folder where the `server.jar` is located! There is a symbolic link in the `server/` directory which does not work on Windows systems. Please remove it and copy the directory there instead or launch the server using the `--tracks-dir` option! Assuming that all 3 tools have compiled successfully (or downloaded them from the [Releases Page](https://github.com/PhilippvK/playforia-minigolf/releases)), you have 3 possible ways for running the server binary: 1. Using the IntelliJ IDE: Use the provides build artifacts or run the server by pressing the play button after compiling 2. Using the Maven tool: Run `mvn compile exec:java` in the `./server`, `./client` or `./editor` directory @@ -65,12 +65,15 @@ java -jar client.jar -server 192.168.1.7 -lang en_US # Replace IP with the one o We provide an experimental Dockerfile for easy hosting of the server application. You can either build the image by yourself or download the pre-build images from [quay.io](https://quay.io/repository/philippvk/minigolf) via `docker pull quay.io/philippvk/minigolf:latest`. Running the Editor is quite straightforward as it can be started like expected: `java -jar editor.jar` + ### CLI options Both client and server include CLI options for hostname (`-ip`), port (`-p`) settings. To learn about all the available setting you can include help with `-h` parameter. +To override the default directory where the server looks for tracks, use the `--tracks-dir` option. + If you want to enable debugging messages, add `--verbose` to the list of arguments. -## Compability +## Compatibility Tested: - Ubuntu 22.04 with Java version `17.0.6` diff --git a/server/src/main/java/org/moparforia/server/Launcher.java b/server/src/main/java/org/moparforia/server/Launcher.java index 4fdbf2bc..87753a40 100644 --- a/server/src/main/java/org/moparforia/server/Launcher.java +++ b/server/src/main/java/org/moparforia/server/Launcher.java @@ -18,6 +18,7 @@ public class Launcher implements Callable { public static final String DEFAULT_HOST = "0.0.0.0"; public static final String DEFAULT_PORT = "4242"; + public static final String DEFAULT_TRACKS_DIRECTORY = "tracks"; @CommandLine.Option( names = {"--hostname", "-ip"}, @@ -33,6 +34,13 @@ public class Launcher implements Callable { ) private int port; + @CommandLine.Option( + names = {"--tracks-dir", "-t"}, + description = "Sets where to look for tracks and track sets", + defaultValue = DEFAULT_TRACKS_DIRECTORY + ) + private String tracksDirectory; + public static void main(String... args) { Launcher launcher = new Launcher(); new CommandLine(launcher) @@ -42,11 +50,11 @@ public static void main(String... args) { @Override public Integer call() { - getServer(host, port).start(); + getServer(host, port, tracksDirectory).start(); return 0; } - public Server getServer(String host, int port) { - return new Server(host, port); + public Server getServer(String host, int port, String tracksDirectory) { + return new Server(host, port, tracksDirectory); } } diff --git a/server/src/main/java/org/moparforia/server/Server.java b/server/src/main/java/org/moparforia/server/Server.java index 1a48fb56..6117b58d 100644 --- a/server/src/main/java/org/moparforia/server/Server.java +++ b/server/src/main/java/org/moparforia/server/Server.java @@ -39,6 +39,7 @@ public class Server implements Runnable { private String host; private int port; + private String tracksDirectory; private HashMap lobbies = new HashMap(); //private ArrayList lobbies = new ArrayList(); @@ -48,9 +49,10 @@ public class Server implements Runnable { private int gameIdCounter; - public Server(String host, int port) { + public Server(String host, int port, String tracksDirectory) { this.host = host; this.port = port; + this.tracksDirectory = tracksDirectory; for (LobbyType lt : LobbyType.values()) { lobbies.put(lt, new Lobby(lt)); } @@ -155,8 +157,8 @@ public void addPlayer(Player p) { public void start() { try { - FileSystemTrackManager.getInstance().load(); - FileSystemStatsManager.getInstance().load(); + FileSystemTrackManager.getInstance().load(tracksDirectory); + FileSystemStatsManager.getInstance().load(tracksDirectory); } catch (TrackLoadException | IOException e) { System.err.println("Unable to load tracks: " + e.getMessage()); e.printStackTrace(); diff --git a/server/src/test/java/org/moparforia/server/LauncherCLITest.java b/server/src/test/java/org/moparforia/server/LauncherCLITest.java index 848c6cf3..6aabac4c 100644 --- a/server/src/test/java/org/moparforia/server/LauncherCLITest.java +++ b/server/src/test/java/org/moparforia/server/LauncherCLITest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; import picocli.CommandLine; @@ -35,7 +34,7 @@ void setUp() { .lenient() .withoutAnnotations()); - doReturn(mock(Server.class)).when(launcher).getServer(anyString(), anyInt()); + doReturn(mock(Server.class)).when(launcher).getServer(anyString(), anyInt(), anyString()); when(launcher.call()).thenCallRealMethod(); cmd = new CommandLine(launcher); @@ -59,36 +58,42 @@ void testInvalidPort() { assertNotEquals(0, cmd.execute("--port=test")); assertNotEquals(0, cmd.execute("-p")); - verify(launcher, never()).getServer(anyString(), anyInt()); + verify(launcher, never()).getServer(anyString(), anyInt(), anyString()); } @Test - void testValidPortAndHostname() { - assertEquals(0, cmd.execute("-p", "1111", "-ip", "128.128.128.128")); - verify(launcher).getServer(eq("128.128.128.128"), eq(1111)); + void testValidOptions() { + assertEquals(0, cmd.execute("-p", "1111", "-ip", "128.128.128.128", "--tracks-dir", "/some/path")); + verify(launcher).getServer(eq("128.128.128.128"), eq(1111), eq("/some/path")); - assertEquals(0, cmd.execute("-p=2222", "-ip=127.127.127.127")); - verify(launcher).getServer(eq("127.127.127.127"), eq(2222)); + assertEquals(0, cmd.execute("-p=2222", "-ip=127.127.127.127", "-t=/some/path")); + verify(launcher).getServer(eq("127.127.127.127"), eq(2222), eq("/some/path")); - assertEquals(0, cmd.execute("-p=3333", "-ip=126.126.126.126")); - verify(launcher).getServer(eq("126.126.126.126"), eq(3333)); + assertEquals(0, cmd.execute("--port=3333", "--hostname=126.126.126.126", "--tracks-dir=/some/path")); + verify(launcher).getServer(eq("126.126.126.126"), eq(3333), eq("/some/path")); } @Test void testOnlyPort() { assertEquals(0, cmd.execute("-p", "1111")); - verify(launcher).getServer(eq(Launcher.DEFAULT_HOST), eq(1111)); + verify(launcher).getServer(eq(Launcher.DEFAULT_HOST), eq(1111), eq(Launcher.DEFAULT_TRACKS_DIRECTORY)); } @Test void testOnlyHostname() { assertEquals(0, cmd.execute("-ip", "127.127.127.127")); - verify(launcher).getServer(eq("127.127.127.127"), eq(DEFAULT_PORT)); + verify(launcher).getServer(eq("127.127.127.127"), eq(DEFAULT_PORT), eq(Launcher.DEFAULT_TRACKS_DIRECTORY)); + } + + @Test + void testOnlyTracksDirectory() { + assertEquals(0, cmd.execute("--tracks-dir", "/some/path")); + verify(launcher).getServer(eq(Launcher.DEFAULT_HOST), eq(DEFAULT_PORT), eq("/some/path")); } @Test void testDefaultValues() { assertEquals(0, cmd.execute()); - verify(launcher).getServer(eq(Launcher.DEFAULT_HOST), eq(DEFAULT_PORT)); + verify(launcher).getServer(eq(Launcher.DEFAULT_HOST), eq(DEFAULT_PORT), eq(Launcher.DEFAULT_TRACKS_DIRECTORY)); } } \ No newline at end of file diff --git a/shared/src/main/java/org/moparforia/shared/tracks/TrackManager.java b/shared/src/main/java/org/moparforia/shared/tracks/TrackManager.java index 2608ff57..5d0adbed 100644 --- a/shared/src/main/java/org/moparforia/shared/tracks/TrackManager.java +++ b/shared/src/main/java/org/moparforia/shared/tracks/TrackManager.java @@ -36,7 +36,7 @@ public interface TrackManager { * Loads all Tracks and TrackSets * @throws TrackLoadException Exception */ - void load() throws TrackLoadException; + void load(String tracksDirectory) throws TrackLoadException; /** * @return True, if manager is loaded diff --git a/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManager.java b/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManager.java index fecc5732..fa0de5ce 100644 --- a/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManager.java +++ b/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManager.java @@ -37,16 +37,17 @@ public static FileSystemStatsManager getInstance() { return instance; } - public void load() throws IOException { - stats = loadStats(); + public void load(String tracksDirectory) throws IOException { + stats = loadStats(tracksDirectory); + logger.info("Loaded stats for " + stats.size() + " tracks"); } - public Map loadStats() throws IOException { + public Map loadStats(String tracksDirectory) throws IOException { List tracks = new ArrayList<>(); - Path tracksPath = fileSystem.getPath("tracks", "tracks"); + Path tracksPath = fileSystem.getPath(tracksDirectory, "tracks"); if (!Files.exists(tracksPath)) { - logger.warning("Directory tracks/tracks was not found, ignoring."); + logger.warning("Directory " + tracksDirectory + "/tracks was not found, ignoring."); return Collections.emptyMap(); } DirectoryStream directoryStream = Files.newDirectoryStream( diff --git a/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManager.java b/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManager.java index fd544ad1..f6fb707a 100644 --- a/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManager.java +++ b/shared/src/main/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManager.java @@ -39,11 +39,11 @@ public static FileSystemTrackManager getInstance() { } @Override - public void load() throws TrackLoadException { + public void load(String tracksDirectory) throws TrackLoadException { try { - tracks = loadTracks(); + tracks = loadTracks(tracksDirectory); logger.info("Loaded " + tracks.size() + " tracks"); - trackSets = loadTrackSets(); + trackSets = loadTrackSets(tracksDirectory); logger.info("Loaded " + trackSets.size() + " track sets"); } catch (IOException e) { throw new TrackLoadException("Unable to load tracks and tracksets", e); @@ -70,11 +70,11 @@ public static String convertTrack(Track track) { "T " + track.getMap()); } - private List loadTracks() throws IOException { + private List loadTracks(String tracksDirectory) throws IOException { List tracks = new ArrayList<>(); - Path tracksPath = fileSystem.getPath("tracks", "tracks"); + Path tracksPath = fileSystem.getPath(tracksDirectory, "tracks"); if (!Files.exists(tracksPath)) { - logger.warning("Tracks directory (tracks/tracks) was not found, ignoring."); + logger.warning("Tracks directory (" + tracksDirectory + "/tracks) was not found, ignoring."); return Collections.emptyList(); } DirectoryStream directoryStream = Files.newDirectoryStream(tracksPath, @@ -90,11 +90,11 @@ private List loadTracks() throws IOException { return tracks; } - private List loadTrackSets() throws IOException { + private List loadTrackSets(String tracksDirectory) throws IOException { List trackSets = new ArrayList<>(); - Path sets = fileSystem.getPath("tracks", "sets"); + Path sets = fileSystem.getPath(tracksDirectory, "sets"); if (!Files.exists(sets)) { - logger.warning("Can't load tracksets, directory tracks/sets does not exists, ignoring."); + logger.warning("Can't load tracksets, directory " + tracksDirectory + "/sets does not exist, ignoring."); return trackSets; } diff --git a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManagerTest.java b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManagerTest.java index 05511e8a..5d404e64 100644 --- a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManagerTest.java +++ b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemStatsManagerTest.java @@ -40,7 +40,7 @@ void beforeEach() { void testSimpleLoad() throws IOException, URISyntaxException { extension.copyAll(); - statsManager.load(); + statsManager.load("tracks"); TrackStats stats = statsManager.getStats(single); assertEquals("Sprt", stats.getBestPlayer()); @@ -55,7 +55,7 @@ void testSimpleLoad() throws IOException, URISyntaxException { void testEmptyStats() throws IOException, URISyntaxException { extension.copyAll(); - statsManager.load(); + statsManager.load("tracks"); TrackStats stats = statsManager.getStats(empty_stats); assertEquals("", stats.getBestPlayer()); assertEquals(0, stats.getTotalAttempts()); diff --git a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManagerTest.java b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManagerTest.java index e3cf0089..0e1da7b9 100644 --- a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManagerTest.java +++ b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/FileSystemTrackManagerTest.java @@ -35,7 +35,7 @@ void beforeEach() { void testSimpleSetLoad() throws IOException, URISyntaxException, TrackLoadException { extension.copyAll(); - manager.load(); + manager.load("tracks"); assertEquals(1, manager.getTrackSets().size()); TrackSet birchwood = manager.getTrackSet("Birchwood"); @@ -49,7 +49,7 @@ void testSimpleSetLoad() throws IOException, URISyntaxException, TrackLoadExcept void testLoad() throws IOException, URISyntaxException, TrackLoadException { extension.copyAll(); - manager.load(); + manager.load("tracks"); assertEquals(17, manager.getTracks().size()); assertEquals(1, manager.getTrackSets().size()); @@ -73,7 +73,7 @@ void testRandomTracksIncorrectLimit() { void testRandomTracks() throws IOException, URISyntaxException, TrackLoadException { extension.copyAll(); - manager.load(); + manager.load("tracks"); assertEquals(3, manager.getRandomTracks(3, TrackCategory.MODERN).size()); assertEquals(6, manager.getRandomTracks(50, TrackCategory.MODERN).size()); } @@ -83,7 +83,7 @@ void testRandomTracks() throws IOException, URISyntaxException, TrackLoadExcepti */ @Test void testRandomTracksEmpty() throws TrackLoadException { - manager.load(); + manager.load("tracks"); assertEquals(0, manager.getRandomTracks(50, TrackCategory.BASIC).size()); } diff --git a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/VersionTest.java b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/VersionTest.java index c21538bd..1df38f8f 100644 --- a/shared/src/test/java/org/moparforia/shared/tracks/filesystem/VersionTest.java +++ b/shared/src/test/java/org/moparforia/shared/tracks/filesystem/VersionTest.java @@ -20,7 +20,7 @@ void testTrackManagerInvalidVersions() throws IOException, URISyntaxException, T extension.copyAll(); TrackManager manager = new FileSystemTrackManager(extension.getFileSystem()); - manager.load(); + manager.load("tracks"); assertEquals(1, manager.getTracks().size()); } diff --git a/shared/src/test/java/org/moparforia/shared/tracks/parsers/TrackConverterTest.java b/shared/src/test/java/org/moparforia/shared/tracks/parsers/TrackConverterTest.java index cc426933..c1809524 100644 --- a/shared/src/test/java/org/moparforia/shared/tracks/parsers/TrackConverterTest.java +++ b/shared/src/test/java/org/moparforia/shared/tracks/parsers/TrackConverterTest.java @@ -41,7 +41,7 @@ void testConvertTracks() throws IOException, URISyntaxException { TrackConverter.convertTracks(tracks); - statsManager.load(); + statsManager.load("tracks"); for (TrackStats stat : consolidated) { Track track = stat.getTrack();