Skip to content

Commit

Permalink
Server: Add CLI option to specify where to look for tracks
Browse files Browse the repository at this point in the history
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`)
  • Loading branch information
StenAL authored and root committed Oct 14, 2023
1 parent 0de067d commit aabe7b3
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 44 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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`
Expand Down
14 changes: 11 additions & 3 deletions server/src/main/java/org/moparforia/server/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Launcher implements Callable<Integer> {

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"},
Expand All @@ -33,6 +34,13 @@ public class Launcher implements Callable<Integer> {
)
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)
Expand All @@ -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);
}
}
8 changes: 5 additions & 3 deletions server/src/main/java/org/moparforia/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class Server implements Runnable {

private String host;
private int port;
private String tracksDirectory;

private HashMap<LobbyType, Lobby> lobbies = new HashMap<LobbyType, Lobby>();
//private ArrayList<LobbyRef> lobbies = new ArrayList<LobbyRef>();
Expand All @@ -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));
}
Expand Down Expand Up @@ -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();
Expand Down
31 changes: 18 additions & 13 deletions server/src/test/java/org/moparforia/server/LauncherCLITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Track, TrackStats> loadStats() throws IOException {
public Map<Track, TrackStats> loadStats(String tracksDirectory) throws IOException {
List<TrackStats> 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<Path> directoryStream = Files.newDirectoryStream(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -70,11 +70,11 @@ public static String convertTrack(Track track) {
"T " + track.getMap());
}

private List<Track> loadTracks() throws IOException {
private List<Track> loadTracks(String tracksDirectory) throws IOException {
List<Track> 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<Path> directoryStream = Files.newDirectoryStream(tracksPath,
Expand All @@ -90,11 +90,11 @@ private List<Track> loadTracks() throws IOException {
return tracks;
}

private List<TrackSet> loadTrackSets() throws IOException {
private List<TrackSet> loadTrackSets(String tracksDirectory) throws IOException {
List<TrackSet> 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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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());

Expand All @@ -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());
}
Expand All @@ -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());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit aabe7b3

Please sign in to comment.