|
21 | 21 | import org.jackhuang.hmcl.auth.AuthInfo; |
22 | 22 | import org.jackhuang.hmcl.launch.DefaultLauncher; |
23 | 23 | import org.jackhuang.hmcl.launch.ProcessListener; |
| 24 | +import org.jackhuang.hmcl.util.NativePatcher; |
24 | 25 | import org.jackhuang.hmcl.util.i18n.LocaleUtils; |
25 | 26 | import org.jackhuang.hmcl.util.io.FileUtils; |
| 27 | +import org.jackhuang.hmcl.util.io.JarUtils; |
| 28 | +import org.jackhuang.hmcl.util.platform.CommandBuilder; |
26 | 29 | import org.jackhuang.hmcl.util.platform.ManagedProcess; |
27 | 30 | import org.jackhuang.hmcl.util.versioning.GameVersionNumber; |
28 | 31 |
|
29 | 32 | import java.io.IOException; |
| 33 | +import java.io.InputStream; |
30 | 34 | import java.nio.file.*; |
31 | 35 | import java.util.*; |
32 | 36 | import java.util.stream.Stream; |
@@ -150,4 +154,60 @@ public void makeLaunchScript(Path scriptFile) throws IOException { |
150 | 154 | generateOptionsTxt(); |
151 | 155 | super.makeLaunchScript(scriptFile); |
152 | 156 | } |
| 157 | + |
| 158 | + @Override |
| 159 | + protected void appendJvmArgs(CommandBuilder result) { |
| 160 | + super.appendJvmArgs(result); |
| 161 | + |
| 162 | + if (config().getAllowAutoAgent() |
| 163 | + && !options.isNoGeneratedJVMArgs() |
| 164 | + && !options.isNoGeneratedOptimizingJVMArgs() |
| 165 | + && NativePatcher.needPatchMemoryUtil(version, options.getJava().getParsedVersion())) { |
| 166 | + LOG.info("Attempting to patch game with lwjgl-unsafe-agent"); |
| 167 | + try { |
| 168 | + result.add("-javaagent:" + extractLwjglUnsafeAgent()); |
| 169 | + } catch (Exception e) { |
| 170 | + LOG.warning("Failed to extract lwjgl-unsafe-agent", e); |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + |
| 175 | + private Path extractLwjglUnsafeAgent() throws IOException { |
| 176 | + String agentVersion = JarUtils.getAttribute("hmcl.lwjgl-unsafe-agent.version", null); |
| 177 | + if (agentVersion == null) { |
| 178 | + throw new IOException("Missing hmcl.lwjgl-unsafe-agent.version attribute"); |
| 179 | + } |
| 180 | + |
| 181 | + Library library = new Library(new Artifact("org.glavo", "lwjgl-unsafe-agent", agentVersion)); |
| 182 | + String fileName = library.getArtifact().getFileName(); |
| 183 | + |
| 184 | + Path agentPath = repository.getLibraryFile(version, library).toAbsolutePath().normalize(); |
| 185 | + if (agentPath.toString().contains("=")) { |
| 186 | + throw new IOException("Invalid library path: " + agentPath); |
| 187 | + } |
| 188 | + |
| 189 | + byte[] bytes; |
| 190 | + try (InputStream input = DefaultLauncher.class.getResourceAsStream("/assets/" + fileName)) { |
| 191 | + if (input == null) { |
| 192 | + throw new IOException("/assets/" + fileName + " not found"); |
| 193 | + } |
| 194 | + |
| 195 | + bytes = input.readAllBytes(); |
| 196 | + } |
| 197 | + |
| 198 | + if (Files.isRegularFile(agentPath)) { |
| 199 | + try { |
| 200 | + if (Files.size(agentPath) == bytes.length) { |
| 201 | + return agentPath; |
| 202 | + } |
| 203 | + } catch (IOException e) { |
| 204 | + LOG.warning("Failed to check size of " + agentPath, e); |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + Files.createDirectories(agentPath.getParent()); |
| 209 | + FileUtils.saveSafely(agentPath, output -> output.write(bytes)); |
| 210 | + return agentPath; |
| 211 | + } |
| 212 | + |
153 | 213 | } |
0 commit comments