Skip to content

Commit 9e17a5c

Browse files
committed
fix: Merge conflicts
2 parents 30f445d + 31d31df commit 9e17a5c

3 files changed

Lines changed: 79 additions & 29 deletions

File tree

common/src/main/java/de/rafael/modflared/binary/download/DownloadedCloudflared.java

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@
1616
import net.minecraft.util.Pair;
1717
import org.jetbrains.annotations.Contract;
1818
import org.jetbrains.annotations.NotNull;
19-
import org.jetbrains.annotations.Nullable;
2019
import org.lwjgl.system.Platform;
2120

2221
import java.io.*;
2322
import java.net.URI;
2423
import java.nio.charset.StandardCharsets;
2524
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.nio.file.StandardCopyOption;
27+
import java.nio.file.attribute.PosixFilePermission;
2628
import java.util.Arrays;
29+
import java.util.UUID;
2730
import java.util.concurrent.CompletableFuture;
31+
import java.util.concurrent.TimeUnit;
2832

2933
public class DownloadedCloudflared extends Cloudflared {
3034

@@ -91,7 +95,7 @@ public String[] buildCommand(RunningTunnel.@NotNull Access access) {
9195
return command;
9296
}
9397

94-
private CompletableFuture<Void> downloadAndSaveInfo() {
98+
private @NotNull CompletableFuture<Void> downloadAndSaveInfo() {
9599
return downloadFile().thenAccept(unused -> {
96100
try {
97101
save();
@@ -116,19 +120,25 @@ public CompletableFuture<Pair<Boolean, String>> isUptoDate() {
116120
}
117121

118122
public @NotNull CompletableFuture<Void> downloadFile() {
119-
return GithubAPI.requestFileHash(download.downloadFile()).thenAcceptAsync(fileHash -> {
123+
return GithubAPI.requestFileHash(download.downloadFile()).thenAcceptAsync(expected -> {
120124
try {
121-
for (int i = 0; i < 5; i++) {
125+
for (int i = 0; i < 4; i++) {
122126
Modflared.LOGGER.info("Downloading cloudflared version {} from github. Attempt: {}", version, i + 1);
123-
File file = syncDownloadFile();
127+
var downloadedFile = syncDownloadFile();
128+
Modflared.LOGGER.info("Downloaded file preparing cloudflared binary...");
129+
var file = new File(TunnelManager.DATA_FOLDER, download.fileName());
130+
prepareFile(downloadedFile, file);
124131

125132
// Check if file is corrupt
126-
if(fileHash.compareTo(file)) {
127-
Modflared.LOGGER.info("Preparing cloudflared binary...");
128-
prepareFile(file);
133+
Modflared.LOGGER.info("Checking file integrity");
134+
var provided = GithubAPI.FileHash.computeHash(file);
135+
if(expected.compareTo(provided)) {
129136
Modflared.LOGGER.info("Download finished of cloudflared version {}!", version);
130137
return;
131138
} else {
139+
Modflared.LOGGER.warn("This downloaded file does not match with the file hash provided on GitHub.");
140+
Modflared.LOGGER.warn("Expected {}, Provided: {}", expected.hash(), provided.hash());
141+
132142
file.delete();
133143
}
134144
}
@@ -141,22 +151,8 @@ public CompletableFuture<Pair<Boolean, String>> isUptoDate() {
141151
}, Modflared.EXECUTOR);
142152
}
143153

144-
private void prepareFile(File file) throws IOException, InterruptedException {
145-
switch (Platform.get()) {
146-
case MACOSX:
147-
new ProcessBuilder("tar", "-xzf", file.getName()).directory(file.getParentFile()).start().waitFor();
148-
new ProcessBuilder("mv", "cloudflared", file.getName()).directory(file.getParentFile()).start().waitFor();
149-
//Fallthrough
150-
case LINUX:
151-
new ProcessBuilder("chmod", "+x", file.getName()).directory(file.getParentFile()).start();
152-
break;
153-
default:
154-
break;
155-
}
156-
}
157-
158154
private @NotNull File syncDownloadFile() throws IOException, InterruptedException {
159-
File output = new File(TunnelManager.DATA_FOLDER, download.fileName());
155+
File output = new File(TunnelManager.DATA_FOLDER, UUID.randomUUID().toString());
160156
if(!output.getParentFile().exists()) output.getParentFile().mkdirs();
161157
if(!output.exists()) output.createNewFile();
162158
try (BufferedInputStream in = new BufferedInputStream(URI.create(GITHUB_DOWNLOAD_ENDPOINT + version + "/" + download.downloadFile()).toURL().openStream()); BufferedOutputStream fileOutputStream = new BufferedOutputStream(new FileOutputStream(output))) {
@@ -171,6 +167,56 @@ private void prepareFile(File file) throws IOException, InterruptedException {
171167
return output;
172168
}
173169

170+
private void prepareFile(@NotNull File downloadedFile, File targetFile) throws IOException, InterruptedException {
171+
var platform = Platform.get();
172+
173+
if(platform == Platform.MACOSX) {
174+
var workingDirectory = downloadedFile.getParentFile().toPath();
175+
runCommand(workingDirectory, "tar", "-xzf", downloadedFile.getName());
176+
Files.move(workingDirectory.resolve("cloudflared"), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
177+
} else {
178+
Files.move(downloadedFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
179+
}
180+
181+
if(platform == Platform.LINUX || platform == Platform.MACOSX) {
182+
makeExecutable(targetFile.toPath());
183+
}
184+
185+
downloadedFile.delete();
186+
}
187+
188+
private void runCommand(@NotNull Path workingDirectory, String... command) throws IOException, InterruptedException {
189+
ProcessBuilder processBuilder = new ProcessBuilder(command)
190+
.directory(workingDirectory.toFile())
191+
.redirectErrorStream(true);
192+
Process process = processBuilder.start();
193+
boolean finished = process.waitFor(60, TimeUnit.SECONDS);
194+
if (!finished) {
195+
process.destroyForcibly();
196+
throw new IOException("Command timed out: " + String.join(" ", command));
197+
}
198+
int code = process.exitValue();
199+
if (code != 0) {
200+
throw new IOException("Command failed (exit " + code + "): " + String.join(" ", command));
201+
}
202+
}
203+
204+
private void makeExecutable(@NotNull Path path) throws IOException {
205+
try {
206+
var permissions = Files.getPosixFilePermissions(path);
207+
permissions.add(PosixFilePermission.OWNER_EXECUTE);
208+
permissions.add(PosixFilePermission.GROUP_EXECUTE);
209+
permissions.add(PosixFilePermission.OTHERS_EXECUTE);
210+
Files.setPosixFilePermissions(path, permissions);
211+
} catch (UnsupportedOperationException exception) {
212+
// Fallback (non-POSIX)
213+
var file = path.toFile();
214+
if(!file.setExecutable(true, false)) {
215+
throw new IOException("Failed to set executable bit on " + file.getName());
216+
}
217+
}
218+
}
219+
174220
private void save() throws IOException {
175221
Files.writeString(VERSION_FILE.toPath(), Modflared.GSON.toJson(this), StandardCharsets.UTF_8);
176222
}

common/src/main/java/de/rafael/modflared/github/GithubAPI.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,17 @@ private static JsonObject getJsonFromEndpoint(@NotNull URL url) throws IOExcepti
7676
public record FileHash(String file, String hash) {
7777

7878
public boolean compareTo(File file) throws IOException {
79-
ByteSource byteSource = Files.asByteSource(file);
80-
HashCode hashCode = byteSource.hash(Hashing.sha256());
81-
return compareTo(hashCode.toString());
79+
return compareTo(computeHash(file));
80+
}
81+
82+
public boolean compareTo(@NotNull FileHash hash) {
83+
return Objects.equals(this.hash, hash.hash());
8284
}
8385

84-
public boolean compareTo(String hash) {
85-
return Objects.equals(this.hash, hash);
86+
public static @NotNull FileHash computeHash(File file) throws IOException {
87+
ByteSource byteSource = Files.asByteSource(file);
88+
HashCode hashCode = byteSource.hash(Hashing.sha256());
89+
return new FileHash(file.getName(), hashCode.toString());
8690
}
8791

8892
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ enabled_platforms=fabric,neoforge
1010

1111
# Mod Properties
1212
archives_base_name=modflared
13-
mod_version=1.4.1
13+
mod_version=1.5.0
1414
maven_group=de.rafael
1515
mod_minecraft_version=1.21.8
1616

0 commit comments

Comments
 (0)