Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build-jar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ jobs:
java-version: "17"
cache: maven

# For tag builds, stamp the project version from the tag (v1.7 -> 1.7) so the jar's
# Implementation-Version matches the release. Without this the manifest keeps the
# hardcoded pom version and the updater re-downloads the same release forever.
- name: Set release version from tag
if: startsWith(github.ref, 'refs/tags/v')
run: mvn --batch-mode versions:set -DnewVersion="${GITHUB_REF_NAME#v}" -DgenerateBackupPoms=false

- name: Build
run: mvn --batch-mode clean package

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
target/Progressive-Java-Client.jar
/target
25 changes: 23 additions & 2 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if (Test-Path src/main/resources) {
Get-ChildItem -Recurse src/main/java -Filter *.java | ForEach-Object FullName | Set-Content sources.txt
$previousErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = "Continue"
javac -J-Xmx512m --release 17 -encoding UTF-8 -cp "lib/*" -d target/classes '@sources.txt'
javac -J-Xmx1g --release 17 -encoding UTF-8 -cp "lib/*" -d target/classes '@sources.txt'
$javacExitCode = $LASTEXITCODE
$ErrorActionPreference = $previousErrorActionPreference
Remove-Item sources.txt -Force
Expand All @@ -44,18 +44,38 @@ Remove-Item target/classes/META-INF/*.SF -Force -ErrorAction SilentlyContinue
Remove-Item target/classes/META-INF/*.DSA -Force -ErrorAction SilentlyContinue
Remove-Item target/classes/META-INF/*.RSA -Force -ErrorAction SilentlyContinue

$clientVersion = if ($env:CLIENT_VERSION) { $env:CLIENT_VERSION.TrimStart("v") } else { "1.7" }
@"
{
"version": "$clientVersion",
"web_host": "localhost",
"web_port": 80,
"game_port": 43594
}
"@ | Set-Content -Encoding UTF8 target/config.json
@"
Manifest-Version: 1.0
Implementation-Version: $clientVersion
Build-Time: $((Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))

"@ | Set-Content -Encoding ascii target/manifest.mf

# Build the updater jar first, then fold it into the client classes so it ships
# *inside* the client jar. At runtime the client extracts it back beside itself.
jar --create --file target/Progressive-Java-Updater.jar --main-class com.gradwahl.rs254.update.UpdateHelper -C target/classes com/gradwahl/rs254/update
if ($LASTEXITCODE -ne 0) {
throw "updater jar failed with exit code $LASTEXITCODE"
}
Copy-Item target/Progressive-Java-Updater.jar target/classes/Progressive-Java-Updater.jar -Force

jar --create --file target/Progressive-Java-Client.jar --main-class com.gradwahl.rs254.Main --manifest target/manifest.mf -C target/classes .
if ($LASTEXITCODE -ne 0) {
throw "jar failed with exit code $LASTEXITCODE. Close any running client and rebuild."
}
Remove-Item target/manifest.mf

Write-Host "Build complete: target/Progressive-Java-Client.jar"
Write-Host "Build complete: target/Progressive-Java-Updater.jar"

# Wrap the JAR in a single .exe with the custom icon using Launch4j.
$launch4jc = "C:\Program Files (x86)\Launch4j\launch4jc.exe"
Expand All @@ -71,12 +91,13 @@ if (Test-Path $launch4jc) {
<headerType>gui</headerType>
<jar>$jarAbsPath</jar>
<outfile>$exeAbsPath</outfile>
<chdir>.</chdir>
<errTitle>Progressive Java Client</errTitle>
<icon>$icoAbsPath</icon>
<jre>
<path></path>
<minVersion>17</minVersion>
<opt>-Dsun.java2d.noddraw=true --enable-native-access=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED</opt>
<opt>-Xmx1g -Dsun.java2d.noddraw=true -Drs254.logDir=logs -XX:ErrorFile=logs\jvm_crash.log --enable-native-access=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED</opt>
</jre>
<cmdLine>10 0 highmem members 32</cmdLine>
<versionInfo>
Expand Down
24 changes: 22 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fi

find src/main/java -name "*.java" > sources.txt

javac -J-Xmx512m --release 17 -encoding UTF-8 -cp "lib/*" -d target/classes @sources.txt
javac -J-Xmx1g --release 17 -encoding UTF-8 -cp "lib/*" -d target/classes @sources.txt
rm sources.txt

# Fold runtime dependencies and LWJGL natives into the artifact so the JAR can
Expand All @@ -34,7 +34,26 @@ done
rm -f target/classes/META-INF/MANIFEST.MF
rm -f target/classes/META-INF/*.SF target/classes/META-INF/*.DSA target/classes/META-INF/*.RSA

printf 'Manifest-Version: 1.0\n\n' > target/manifest.mf
BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
CLIENT_VERSION="${CLIENT_VERSION:-1.7}"
CLIENT_VERSION="${CLIENT_VERSION#v}"
cat > target/config.json <<EOF
{
"version": "$CLIENT_VERSION",
"web_host": "localhost",
"web_port": 80,
"game_port": 43594
}
EOF
printf 'Manifest-Version: 1.0\nImplementation-Version: %s\nBuild-Time: %s\n\n' "$CLIENT_VERSION" "$BUILD_TIME" > target/manifest.mf

# Build the updater jar first, then fold it into the client classes so it ships
# *inside* the client jar. At runtime the client extracts it back beside itself.
jar --create --file target/Progressive-Java-Updater.jar \
--main-class com.gradwahl.rs254.update.UpdateHelper \
-C target/classes com/gradwahl/rs254/update

cp target/Progressive-Java-Updater.jar target/classes/Progressive-Java-Updater.jar

jar --create --file target/Progressive-Java-Client.jar \
--main-class com.gradwahl.rs254.Main \
Expand All @@ -44,4 +63,5 @@ jar --create --file target/Progressive-Java-Client.jar \
rm target/manifest.mf

echo "Build complete: target/Progressive-Java-Client.jar"
echo "Build complete: target/Progressive-Java-Updater.jar"
echo "Run with: ./run.sh"
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.gradwahl</groupId>
<artifactId>Progressive-Java-Client</artifactId>
<version>0.1.0</version>
<version>1.7</version>
<name>Progressive Java Client</name>

<properties>
Expand Down Expand Up @@ -172,6 +172,10 @@
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.gradwahl.rs254.Main</mainClass>
<manifestEntries>
<Implementation-Version>${project.version}</Implementation-Version>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</transformer>
</transformers>
</configuration>
Expand Down
3 changes: 2 additions & 1 deletion run.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ cd /d "%~dp0"
set "SCRIPT_DIR=%~dp0"
set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
if not exist target\Progressive-Java-Client.jar call build.bat
if not exist target\Progressive-Java-Updater.jar call build.bat

if not exist "%SCRIPT_DIR%\logs" mkdir "%SCRIPT_DIR%\logs"

echo Starting RS2 client (HTTP :80, game :43594)...
java -Dsun.java2d.noddraw=true -Drs254.logDir="%SCRIPT_DIR%\logs" --enable-native-access=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -XX:ErrorFile="%SCRIPT_DIR%\logs\jvm_crash_%%p.log" -jar target\Progressive-Java-Client.jar 10 0 highmem members 32
java -Xmx1g -Dsun.java2d.noddraw=true -Drs254.logDir="%SCRIPT_DIR%\logs" --enable-native-access=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -XX:ErrorFile="%SCRIPT_DIR%\logs\jvm_crash_%%p.log" -jar target\Progressive-Java-Client.jar 10 0 highmem members 32

if %ERRORLEVEL% neq 0 (
echo.
Expand Down
3 changes: 2 additions & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ if [ "$MISSING" -eq 1 ]; then
REBUILD=1
fi

if [ ! -f target/Progressive-Java-Client.jar ] || [ "$REBUILD" -eq 1 ]; then
if [ ! -f target/Progressive-Java-Client.jar ] || [ ! -f target/Progressive-Java-Updater.jar ] || [ "$REBUILD" -eq 1 ]; then
bash build.sh
fi

mkdir -p "$SCRIPT_DIR/logs"

echo "Starting RS2 client (HTTP :80, game :43594)..."
java \
-Xmx1g \
-Drs254.logDir="$SCRIPT_DIR/logs" \
--enable-native-access=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
Expand Down
60 changes: 58 additions & 2 deletions src/main/java/com/gradwahl/rs254/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public record ClientConfig(String host, int httpPort, int gamePort, boolean secure, int revision, String cacheDir, String dbPath) {
public record ClientConfig(String host, int httpPort, int gamePort, boolean secure, int revision,
String cacheDir, String dbPath, String version) {

private static final String CONFIG_FILE = "config.json";

public static ClientConfig load() {
File configFile = resolveConfigFile();
boolean firstRun = !configFile.exists();
String version = currentVersionLabel();

if (firstRun) {
String defaultConfig =
"{\n" +
" \"version\": \"" + escapeJson(version) + "\",\n" +
" \"web_host\": \"localhost\",\n" +
" \"web_port\": 80,\n" +
" \"game_port\": 43594\n" +
Expand All @@ -30,11 +35,33 @@ public static ClientConfig load() {
}
} else {
System.out.println("[Config] Loaded config from: " + configFile.getAbsolutePath());
updateVersionField(configFile, version);
}

return parseFile(configFile);
}

public static String currentVersionLabel() {
try {
String version = ClientConfig.class.getPackage().getImplementationVersion();
if (version != null && !version.isBlank()) {
return version;
}
var manifestUrl = ClientConfig.class.getResource("/META-INF/MANIFEST.MF");
if (manifestUrl != null) {
try (InputStream in = manifestUrl.openStream()) {
Attributes attrs = new Manifest(in).getMainAttributes();
version = attrs.getValue("Implementation-Version");
if (version != null && !version.isBlank()) {
return version;
}
}
}
} catch (Exception ignored) {
}
return "dev";
}

private static File resolveConfigFile() {
// Place config next to the JAR, falling back to the working directory
try {
Expand All @@ -54,10 +81,12 @@ private static ClientConfig parseFile(File file) {
int revision = 254;
String cacheDir = "cache";
String dbPath = "";
String version = currentVersionLabel();

if (file.exists()) {
try {
String json = Files.readString(file.toPath(), StandardCharsets.UTF_8);
version = readString(json, "version", version);
host = readString(json, "web_host", host);
httpPort = readInt(json, "web_port", httpPort);
gamePort = readInt(json, "game_port", gamePort);
Expand All @@ -76,7 +105,30 @@ private static ClientConfig parseFile(File file) {
cacheDir = System.getProperty("rs254.cacheDir", cacheDir);
dbPath = System.getProperty("rs254.dbPath", dbPath);

return new ClientConfig(host, httpPort, gamePort, secure, revision, cacheDir, dbPath);
return new ClientConfig(host, httpPort, gamePort, secure, revision, cacheDir, dbPath, version);
}

private static void updateVersionField(File file, String version) {
try {
String json = Files.readString(file.toPath(), StandardCharsets.UTF_8);
String escaped = escapeJson(version);
String updated;
if (Pattern.compile("\"version\"\\s*:").matcher(json).find()) {
updated = json.replaceFirst("\"version\"\\s*:\\s*\"((?:[^\\\\\"]|\\\\.)*)\"",
"\"version\": \"" + Matcher.quoteReplacement(escaped) + "\"");
} else {
int objectStart = json.indexOf('{');
if (objectStart < 0) return;
updated = json.substring(0, objectStart + 1)
+ "\n \"version\": \"" + escaped + "\","
+ json.substring(objectStart + 1);
}
if (!updated.equals(json)) {
Files.writeString(file.toPath(), updated, StandardCharsets.UTF_8);
}
} catch (IOException e) {
System.err.println("[Config] Warning: could not update version in " + file + ": " + e.getMessage());
}
}

private static String readString(String json, String key, String defaultValue) {
Expand All @@ -96,6 +148,10 @@ private static int readInt(String json, String key, int defaultValue) {
return defaultValue;
}

private static String escapeJson(String value) {
return value.replace("\\", "\\\\").replace("\"", "\\\"");
}

/** @deprecated Use {@link #load()} instead. */
@Deprecated
public static ClientConfig fromSystemProperties() {
Expand Down
Loading
Loading