Skip to content

Commit

Permalink
fix: change default configuration location & fix cli arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
azurejelly committed Aug 31, 2024
1 parent 6be5c36 commit 5f49b1c
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 59 deletions.
74 changes: 60 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,70 @@
# NuVotifier
# standalone-nuvotifier
Standalone NuVotifier server implementation. From the original README:
> NuVotifier is a secure alternative to using the original Votifier project.
> NuVotifier will work in place of Votifier - any vote listener that supports
> Votifier will also support NuVotifier.
NuVotifier is a secure alternative to using the original Votifier project.
NuVotifier will work in place of Votifier - any vote listener that supports
Votifier will also support NuVotifier.
## Useful resources
- [Setup Guide](https://github.com/NuVotifier/NuVotifier/wiki/Setup-Guide)
- [Troubleshooting Guide](https://github.com/NuVotifier/NuVotifier/wiki/Troubleshooting-Guide)
- [Developer Information](https://github.com/NuVotifier/NuVotifier/wiki/Developer-Documentation)

NuVotifier supports many different platforms using the same universal JAR:
## Running
Grab a compiled binary from [GitHub releases](https://github.com/azujelly/standalone-nuvotifier/releases) and run it from the command line. For example:
```shell
$ curl -O https://github.com/azujelly/standalone-nuvotifier/releases/download/3.0.0-SNAPSHOT/nuvotifier-standalone.jar
$ java -Xms512M -Xmx512M -jar nuvotifier-standalone.jar
```

+ Bukkit / Spigot / Paper >=1.7.10
+ Sponge 7
+ BungeeCord / Waterfall
+ Velocity
You can also use command line arguments to configure some settings:
```shell
$ java -Xms512M -Xmx512M -jar nuvotifier-standalone.jar --bind 0.0.0.0 --port 8195 --config /etc/nuvotifier/
```

NuVotifier also adds forwarding and listener test commands not present in the
original version.
## Using Docker
A Docker image is available at [Docker Hub](https://hub.docker.com/r/azurejelly/standalone-nuvotifier). To pull it, run:
```shell
$ docker pull azurejelly/standalone-nuvotifier:latest
```

[Setup Guide](https://github.com/NuVotifier/NuVotifier/wiki/Setup-Guide)
### Running
Run the image using:
```shell
$ docker run -p 8192:8192 \
-v /etc/nuvotifier:/etc/nuvotifier \
--restart unless-stopped \
--name nuvotifier \
azurejelly/standalone-nuvotifier:latest
```

[Troubleshooting Guide](https://github.com/NuVotifier/NuVotifier/wiki/Troubleshooting-Guide)
This will:
- Expose port 8192 on the host machine;
- Map `/etc/nuvotifier` (host) to `/etc/nuvotifier` (container) using bind mounts;
- Restart the container automatically unless stopped;
- Name the container `nuvotifier`;
- And use the `azurejelly/standalone-nuvotifier:latest` image.

[Developer Information](https://github.com/NuVotifier/NuVotifier/wiki/Developer-Documentation)
Additionally, if you're also running your Minecraft server with Docker, you could create a network for cross-container communication:
```shell
$ docker network create votifierNetwork
$ docker run ... --network votifierNetwork ...
```

Note that you will need to recreate your existing containers to do this.

### Compose
The Docker Compose equivalent of the previous `docker run` command (minus networking stuff) is as follows:
```yaml
services:
forwarder:
container_name: nuvotifier
image: azurejelly/standalone-nuvotifier:latest
restart: unless-stopped
ports:
- 8192:8192
volumes:
- ./config:/etc/nuvotifier
```
# License
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,28 @@
import org.apache.commons.cli.Option;

import java.io.File;
import java.net.InetSocketAddress;

public class CommandArguments {

public static final Option BIND_ADDRESS = Option.builder("b")
public static final Option HOST = Option.builder("h")
.desc("The address NuVotifier should bind to.")
.type(InetSocketAddress.class)
.longOpt("bind")
.hasArg(true)
.type(String.class)
.longOpt("host")
.required(false)
.build();

public static final Option PORT = Option.builder("p")
.desc("The port NuVotifier should bind to.")
.hasArg(true)
.type(int.class)
.longOpt("port")
.required(false)
.build();

public static final Option CONFIGURATION = Option.builder("c")
.desc("Configuration file location. Defaults to /etc/nuvotifier/config.yml or C:\\ProgramData\\nuvotifier\\config.yml under Windows.")
public static final Option CONFIG_FOLDER = Option.builder("c")
.desc("The location where NuVotifier should store configuration files at.")
.hasArg(true)
.required(false)
.type(File.class)
.longOpt("config")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.vexsoftware.nuvotifier.standalone.Main;
import com.vexsoftware.nuvotifier.standalone.config.VotifierConfiguration;
import com.vexsoftware.nuvotifier.standalone.config.options.CommandArguments;
import com.vexsoftware.nuvotifier.standalone.utils.EnvironmentUtil;
import org.apache.commons.cli.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -20,6 +19,8 @@
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class ConfigurationModule extends AbstractModule {
Expand All @@ -31,8 +32,8 @@ public class ConfigurationModule extends AbstractModule {
public Options getOptions() {
Options options = new Options();

options.addOption(CommandArguments.CONFIGURATION);
options.addOption(CommandArguments.BIND_ADDRESS);
options.addOption(CommandArguments.CONFIG_FOLDER);
options.addOption(CommandArguments.HOST);
options.addOption(CommandArguments.PORT);

return options;
Expand All @@ -53,36 +54,37 @@ public ObjectMapper provideYAMLMapper() {
@Provides
@Singleton
@Named("configPath")
public File provideDefaultConfigurationPath() {
if (EnvironmentUtil.isUnix() || EnvironmentUtil.isSolaris() || EnvironmentUtil.isMacOS()) {
return new File("/etc/nuvotifier/");
public File provideConfigurationDirectory(CommandLine cli, Options options) {
if (cli.hasOption(CommandArguments.CONFIG_FOLDER)) {
try {
File file = cli.getParsedOptionValue(CommandArguments.CONFIG_FOLDER);
System.out.println(file != null ? "file is not null" : "file is null");
return cli.getParsedOptionValue(CommandArguments.CONFIG_FOLDER);
} catch (ParseException ex) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(Main.class.getName(), options);
System.exit(1);
return null;
}
}

return new File("C:\\ProgramData\\nuvotifier\\");
Path currentRelativePath = Paths.get(".");
File config = new File(currentRelativePath.toFile(), "config");

if (!config.exists() && !config.mkdirs()) {
logger.error("Failed to create configuration directory at {}", config.getAbsolutePath());
System.exit(1);
return null;
}

return config;
}

@Provides
@Singleton
public VotifierConfiguration provideVotifierConfiguration(
@Named("configPath") File configPath,
CommandLine cli,
Options options,
ObjectMapper mapper
) {
public VotifierConfiguration provideVotifierConfiguration(@Named("configPath") File configPath, ObjectMapper mapper) {
try {
File file = cli.hasOption(CommandArguments.CONFIGURATION)
? cli.getParsedOptionValue(CommandArguments.CONFIGURATION)
: new File(configPath, "config.yml");

if (!configPath.exists()) {
if (!configPath.mkdirs()) {
logger.error("Failed to make default configuration directory at {}", configPath.getAbsolutePath());
System.exit(1);
return null;
}

logger.debug("Made default configuration directory");
}
File file = new File(configPath, "config.yml");

if (!file.exists()) {
InputStream resource = this.getClass().getClassLoader().getResourceAsStream("config.yml");
Expand All @@ -97,11 +99,6 @@ public VotifierConfiguration provideVotifierConfiguration(
}

return mapper.readValue(file, VotifierConfiguration.class);
} catch (ParseException ex) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(Main.class.getName(), options);
System.exit(1);
return null;
} catch (IOException e) {
logger.error("Failed to read or copy defaults to configuration file:", e);
System.exit(1);
Expand All @@ -118,30 +115,34 @@ public CommandLine getCommandLine(Options options, String[] args) {
} catch (ParseException ex) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(Main.class.getName(), options);
System.exit(1);
return null;
}
}

@Singleton
@Provides
@Singleton
@Named("bindAddress")
public String getBindAddress(CommandLine cli, VotifierConfiguration config) {
if (cli.hasOption(CommandArguments.BIND_ADDRESS)) {
return cli.getOptionValue(CommandArguments.BIND_ADDRESS);
if (cli.hasOption(CommandArguments.HOST)) {
return cli.getOptionValue(CommandArguments.HOST);
}

return config.getHost();
}

@Singleton
@Provides
@Singleton
@Named("port")
public int getPort(CommandLine cli, VotifierConfiguration config) {
public int getPort(CommandLine cli, Options options, VotifierConfiguration config) {
if (cli.hasOption(CommandArguments.PORT)) {
try {
return cli.getParsedOptionValue(CommandArguments.PORT);
} catch (ParseException ex) {
logger.error("Could not parse command line arguments", ex);
String str = cli.getOptionValue(CommandArguments.PORT);
return Integer.parseInt(str);
} catch (NumberFormatException ex) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(Main.class.getName(), options);
System.exit(1);
}
}

Expand All @@ -151,6 +152,7 @@ public int getPort(CommandLine cli, VotifierConfiguration config) {
@Singleton
@Provides
public InetSocketAddress getInetSocketAddress(@Named("bindAddress") String address, @Named("port") int port) {
System.out.println(address != null ? "address is not null" : "address is null");
return new InetSocketAddress(address, port);
}
}

0 comments on commit 5f49b1c

Please sign in to comment.