Only allow a single program instance to be run.
Creates a ServerSocket instance on a port (default: 49250). Credits to marcostudios for the suggestion. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
6bdb026447
commit
60eaa42997
|
@ -29,7 +29,9 @@ import itdelatrisu.opsu.states.SongMenu;
|
|||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.newdawn.slick.AppGameContainer;
|
||||
import org.newdawn.slick.Color;
|
||||
|
@ -66,6 +68,11 @@ public class Opsu extends StateBasedGame {
|
|||
STATE_GAMEPAUSEMENU = 6,
|
||||
STATE_GAMERANKING = 7;
|
||||
|
||||
/**
|
||||
* Used to restrict the program to a single instance.
|
||||
*/
|
||||
private static ServerSocket SERVER_SOCKET;
|
||||
|
||||
public Opsu(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
@ -82,12 +89,6 @@ public class Opsu extends StateBasedGame {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// set path for lwjgl natives - NOT NEEDED if using JarSplice
|
||||
// System.setProperty("org.lwjgl.librarypath", new File("native").getAbsolutePath());
|
||||
|
||||
// set the resource path
|
||||
ResourceLoader.addResourceLocation(new FileSystemLocation(new File("./res/")));
|
||||
|
||||
// log all errors to a file
|
||||
Log.setVerbose(false);
|
||||
try {
|
||||
|
@ -102,13 +103,29 @@ public class Opsu extends StateBasedGame {
|
|||
}
|
||||
});
|
||||
|
||||
// parse configuration file
|
||||
Options.parseOptions();
|
||||
|
||||
// only allow a single instance
|
||||
try {
|
||||
SERVER_SOCKET = new ServerSocket(Options.getPort());
|
||||
} catch (IOException e) {
|
||||
Log.error(String.format("Another program is already running on port %d.", Options.getPort()), e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// set path for lwjgl natives - NOT NEEDED if using JarSplice
|
||||
// System.setProperty("org.lwjgl.librarypath", new File("native").getAbsolutePath());
|
||||
|
||||
// set the resource path
|
||||
ResourceLoader.addResourceLocation(new FileSystemLocation(new File("./res/")));
|
||||
|
||||
// start the game
|
||||
Opsu osuGame = new Opsu("opsu!");
|
||||
try {
|
||||
AppGameContainer app = new AppGameContainer(osuGame);
|
||||
|
||||
// basic game settings
|
||||
Options.parseOptions();
|
||||
int[] containerSize = Options.getContainerSize();
|
||||
app.setDisplayMode(containerSize[0], containerSize[1], false);
|
||||
String[] icons = { "icon16.png", "icon32.png" };
|
||||
|
@ -147,6 +164,18 @@ public class Opsu extends StateBasedGame {
|
|||
|
||||
Options.saveOptions();
|
||||
((AppGameContainer) this.getContainer()).destroy();
|
||||
closeSocket();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the server socket.
|
||||
*/
|
||||
public static void closeSocket() {
|
||||
try {
|
||||
SERVER_SOCKET.close();
|
||||
} catch (IOException e) {
|
||||
Log.error("Failed to close server socket.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@ public class MainMenuExit extends BasicGameState {
|
|||
|
||||
if (yesButton.contains(x, y)) {
|
||||
Options.saveOptions();
|
||||
Opsu.closeSocket();
|
||||
container.exit();
|
||||
} else if (noButton.contains(x, y))
|
||||
game.enterState(Opsu.STATE_MAINMENU, new EmptyTransition(), new FadeInTransition(Color.black));
|
||||
|
@ -141,6 +142,7 @@ public class MainMenuExit extends BasicGameState {
|
|||
switch (key) {
|
||||
case Input.KEY_1:
|
||||
Options.saveOptions();
|
||||
Opsu.closeSocket();
|
||||
container.exit();
|
||||
break;
|
||||
case Input.KEY_2:
|
||||
|
|
|
@ -225,6 +225,11 @@ public class Options extends BasicGameState {
|
|||
*/
|
||||
private static int screenshotFormatIndex = 0;
|
||||
|
||||
/**
|
||||
* Port binding.
|
||||
*/
|
||||
private static int port = 0;
|
||||
|
||||
/**
|
||||
* Back button (shared by other states).
|
||||
*/
|
||||
|
@ -673,6 +678,19 @@ public class Options extends BasicGameState {
|
|||
*/
|
||||
public static boolean isComboBurstEnabled() { return showComboBursts; }
|
||||
|
||||
/**
|
||||
* Returns the port number to bind to.
|
||||
* @return the port
|
||||
*/
|
||||
public static int getPort() {
|
||||
if (port == 0) {
|
||||
// choose a random port
|
||||
port = 49250;
|
||||
optionsChanged = true; // force file creation
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current beatmap directory.
|
||||
* If invalid, this will attempt to search for the directory,
|
||||
|
@ -761,6 +779,11 @@ public class Options extends BasicGameState {
|
|||
case "ComboBurst":
|
||||
showComboBursts = Boolean.parseBoolean(value);
|
||||
break;
|
||||
case "Port":
|
||||
i = Integer.parseInt(value);
|
||||
if (i > 0 && i <= 65535)
|
||||
port = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -814,6 +837,8 @@ public class Options extends BasicGameState {
|
|||
writer.newLine();
|
||||
writer.write(String.format("ComboBurst = %b", showComboBursts));
|
||||
writer.newLine();
|
||||
writer.write(String.format("Port = %d", port));
|
||||
writer.newLine();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
Log.error(String.format("Failed to write to file '%s'.", OPTIONS_FILE), e);
|
||||
|
|
Loading…
Reference in New Issue
Block a user