gameDir containing dots breaks some file opening methods
Based on 1.11.2 decompiled using MCP 9.35 rc1
The bug
Some file opening methods do not work when Minecraft is launched with a gameDir containing dots.
Affected situations
List might be incomplete
Last updated for 1.11.2
- opening screenshots (net.minecraft.util.ScreenShotHelper.saveScreenshot(File, String, int, int, Framebuffer))
- opening crash reports
- net.minecraft.client.Minecraft.displayCrashReport(CrashReport)
- net.minecraft.server.MinecraftServer.run()
- parts of realms (?) (net.minecraft.realms.Realms.getGameDirectoryPath())
How to reproduce (old Java launcher)
- Create a profile with the following game directory
./game-data
- Start Minecraft with the profile
- Take a screenshot and try to open it by clicking on the message in chat
→ The file is not opened
Additionally something like the following will appear in the Game Output of your launcher:
20:02:05] [Client thread/ERROR]: Couldn't open link: Failed to open file:/LAUNCHER_PATH/./game-data/screenshots/2017-02-04_19.58.40.png. Error message: The system cannot find the file specified.
Code analysis
This happens because the affected methods call the method java.io.File.getAbsolutePath() for the screenshot file path which does not resolve dots. Instead the method java.io.File.getCanonicalPath() could be used.
Environment
OS: Windows 7
Linked Issues
Created Issue:
Cannot open screenshots when Minecraft is launched with gameDir containing dots
The bug
Clicking on screenshot links in chat does not work when Minecraft is launched with a gameDir containing dots.
How to reproduce
- Create a profile with the following game directory
./game-data- Start Minecraft with the profile
- Take a screenshot and try to open it by clicking on the message in chat
→ The file is not openedAdditionally something like the following will appear in the Game Output of your launcher:
20:02:05] [Client thread/ERROR]: Couldn't open link: Failed to open file:/LAUNCHER_PATH/./game-data/screenshots/2017-02-04_19.58.40.png. Error message: The system cannot find the file specified.Code analysis
Based on 1.11.2 decompiled using MCP 9.35 rc1
This happens because the method net.minecraft.util.ScreenShotHelper.saveScreenshot(File, String, int, int, Framebuffer) calls the method java.io.File.getAbsolutePath() for the screenshot file path which does not remove redundant dots. Instead the method java.io.File.getCanonicalPath() could be used.
Cannot open screenshots when Minecraft is launched with gameDir containing dotsgameDir containing dots breaks some file opening methods
The bug
Clicking on screenshot links in chat doesnot work when Minecraft is launched with a gameDir containing dots.
How to reproduce
- Create a profile with the following game directory
./game-data- Start Minecraft with the profile
- Take a screenshot and try to open it by clicking on the message in chat
→ The file is not openedAdditionally something like the following will appear in the Game Output of your launcher:
20:02:05] [Client thread/ERROR]: Couldn't open link: Failed to open file:/LAUNCHER_PATH/./game-data/screenshots/2017-02-04_19.58.40.png. Error message: The system cannot find the file specified.Code analysis
Based on 1.11.2 decompiled using MCP 9.35 rc1
This happens because the method net.minecraft.util.ScreenShotHelper.saveScreenshot(File, String, int, int, Framebuffer) call
sthe method java.io.File.getAbsolutePath() for the screenshot file path which does not remove redundantdots. Instead the method java.io.File.getCanonicalPath() could be used.Based on 1.11.2 decompiled using MCP 9.35 rc1
The bug
Some file opening methods do not work when Minecraft is launched with a gameDir containing dots.
Affected situations
List might be incomplete
Last updated for 1.11.2
- opening screenshots (net.minecraft.util.ScreenShotHelper.saveScreenshot(File, String, int, int, Framebuffer))
- opening crash reports
- net.minecraft.client.Minecraft.displayCrashReport(CrashReport)
- net.minecraft.server.MinecraftServer.run()
- parts of realms (?) (net.minecraft.realms.Realms.getGameDirectoryPath())
How to reproduce
- Create a profile with the following game directory
./game-data- Start Minecraft with the profile
- Take a screenshot and try to open it by clicking on the message in chat
→ The file is not openedAdditionally something like the following will appear in the Game Output of your launcher:
20:02:05] [Client thread/ERROR]: Couldn't open link: Failed to open file:/LAUNCHER_PATH/./game-data/screenshots/2017-02-04_19.58.40.png. Error message: The system cannot find the file specified.Code analysis
This happens because the affected methods call the method java.io.File.getAbsolutePath() for the screenshot file path which does not resolve dots. Instead the method java.io.File.getCanonicalPath() could be used.
OS: Windows 7
Based on 1.11.2 decompiled using MCP 9.35 rc1
The bug
Some file opening methods do not work when Minecraft is launched with a gameDir containing dots.
Affected situations
List might be incomplete
Last updated for 1.11.2
- opening screenshots (net.minecraft.util.ScreenShotHelper.saveScreenshot(File, String, int, int, Framebuffer))
- opening crash reports
- net.minecraft.client.Minecraft.displayCrashReport(CrashReport)
- net.minecraft.server.MinecraftServer.run()
- parts of realms (?) (net.minecraft.realms.Realms.getGameDirectoryPath())
How to reproduce (old Java launcher)
- Create a profile with the following game directory
./game-data- Start Minecraft with the profile
- Take a screenshot and try to open it by clicking on the message in chat
→ The file is not openedAdditionally something like the following will appear in the Game Output of your launcher:
20:02:05] [Client thread/ERROR]: Couldn't open link: Failed to open file:/LAUNCHER_PATH/./game-data/screenshots/2017-02-04_19.58.40.png. Error message: The system cannot find the file specified.Code analysis
This happens because the affected methods call the method java.io.File.getAbsolutePath() for the screenshot file path which does not resolve dots. Instead the method java.io.File.getCanonicalPath() could be used.
is duplicated by
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40 pre-1.
Java automatically adds a dot at the end of the game directory path due to the java.io.File.getAbsolutePath() call which can return an absolute path which is also a canonical path, but also a path which is only absolute since a path can have multiple absolute paths. While this surely isn't the most elegant solution, one can easily get the ClickEvent to work by adding a one liner at the beginning of the net.minecraft.util.ScreenShotHelper.saveScreenshot() method.
try { // This line will check if the game directory path ends with a dot and removes it if it does. String fgamedir = gameDirectory.getAbsolutePath().charAt(gameDirectory.getAbsolutePath().length() -1) == '.' ? gameDirectory.getAbsolutePath().substring(0, gameDirectory.getAbsolutePath().length() - 1) : gameDirectory.getAbsolutePath(); File file1 = new File(fgamedir, "screenshots"); file1.mkdir(); BufferedImage bufferedimage = createScreenshot(width, height, buffer); File file2; if (screenshotName == null) { file2 = getTimestampedPNGFileForDirectory(file1); } else { file2 = new File(file1, screenshotName); } ImageIO.write(bufferedimage, "png", file2); ITextComponent itextcomponent = new TextComponentString(file2.getName()); itextcomponent.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, file2.getAbsolutePath())); itextcomponent.getStyle().setUnderlined(Boolean.valueOf(true)); return new TextComponentTranslation("screenshot.success", new Object[] {itextcomponent}); } catch (Exception exception) { LOGGER.warn("Couldn't save screenshot", (Throwable)exception); return new TextComponentTranslation("screenshot.failure", new Object[] {exception.getMessage()}); }
As I'm currently unsure what exactly causes this problem, it might be worth trying to reproduce this bug on other operating systems.
EDIT: As Marcono1234 has already described here: MC-113208; a way simpler solution would be to use file2.getCanonicalPath() instad of file2.getAbsolutePath().
@[Mod] bemoty it looks like you partwise describe MC-113208. We do not know what exact problem Ricky John David Jenkins has / had and the message in user-63148 comment looks different from the one the problem you are describing likely produces, probably "The system cannot find the file specified." like MC-113208.
It is great that you took the time to do a code analysis though. Are you sure that the case you are describing is really happening?
Marcono1234 So, I just tried to reproduce this bug in different versions and different game directories and for some reason I could only get it to work in my MCP game directory. Every other game directory (.minecraft / even a test folder on my desktop with dots in its name) works just fine. I get the following console output from eclipse using MCP:
[Client thread/ERROR]: Couldn't open link: Failed to open file:/C:/Users/bemoty/Desktop/mcp940-pre1/jars/./screenshots/2017-07-11_23.48.25.png. Error message: The system cannot find the file specified.
While this is indeed a different error message than @user-63148 received when trying to reproduce the bug, the message looks pretty much the same as the one in MC-113208. After carefully examining the code I'm pretty certain that it's the dot in the absolute path causing this to happen since every other manually inserted path seems to work. The problem described here is pretty surely related to MC-113208.
Does anything appear in the log? Does MC-113208 describe your issue?
No it doesn't, I found the log location and the Error message didn't match MC-113208. 2018-02-15-1.log.gz
Are you sure the dot in the gameDir is causing these game functions to break? I just tried to reproduce the bug in game directories with dots at various different places in their names (also ./game-data) and I've not been able to reproduce it a single time.
When does the method call java.io.File.getAbsolutePath() actually return an absolute path which isn't a canonical path? Every canonical path is also an absolute path, but not the other way around.
Yes, I am still able to reproduce this. Your comment sounds like you create folders with a dot in the name (like .minecraft), which work perfectly fine. The problem occurs when you use dots as relative path directories.
Your second sentence explains that, did you possibly switch the words by accident? Anyways, consider for example the following example with home as current directory:
Marcono1234 As I've already mentioned in my comment, I've also tried to reproduce it with dots in relative game directory paths, including "./game-data", but I still can't get it to work like that. The only occasion in which it didn't work for me was when I tried to reproduce it in MCP. Am I doing something wrong? Here's a video of me trying to reproduce the bug with "./test". (I also can't get it to work in 1.12.)
Also thanks for explaining the exact difference between an absolute and a canonical path again, I think I got it now. However, I still can't get my head
around why I can only get this to work inside of MCP.
Maybe it is caused by the new launcher. Can you please check which game directory is set when you try to edit the created profile again. I used the old Java launcher and was able to reproduce this in 1.12.
I just checked the game directory path of the profile I created and it says C:\Users\bemoty\AppData\Roaming\.minecraft\test. Are you able to reproduce it in the new launcher? If not, this might actually be caused by the old launcher or, respectively, by starting the game manually without converting the absolute game directory path to a canonical one.
If this is the case, most users won't even notice this bug since they are using the normal Minecraft launcher which converts the path automatically. For occasions in which the game is started without converting the absolute game directory path to a canonical one before startup (ex. MCP) this should be fixed by replacing the getAbsolutePath() method with getCanonicalPath() though.
Resolved as "Invalid" since the Java launcher is no longer available and it appears this issue (at least for screenshots) cannot be reproduced, even when launching Minecraft from command line with a relative gameDir in 20w07a.