Skip to content

Commit 4bac6f5

Browse files
authored
[FileCommands] Fix crash when tasfile folder doesn't exist (#222)
- [FileCommands] Properly create temp folders on initialise - [PlaybackSerialiser] Switch to paths - [Tests] Switch to paths, fix some race conditions...
2 parents 15c324f + 7daec20 commit 4bac6f5

File tree

14 files changed

+298
-196
lines changed

14 files changed

+298
-196
lines changed

src/main/java/com/minecrafttas/mctcommon/file/AbstractDataFile.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,33 @@ protected AbstractDataFile(Path file, String name, String comment) {
5555
this.comment = comment;
5656
this.properties = new Properties();
5757

58-
createDirectory(file);
58+
try {
59+
createDirectory(file.getParent());
60+
} catch (IOException e) {
61+
MCTCommon.LOGGER.catching(e);
62+
}
5963
}
6064

6165
/**
6266
* Creates the directory for the file if it doesn't exist
63-
* @param file The file to create the directory for
67+
* @param directory The file to create the directory for
6468
*/
65-
protected void createDirectory(Path file) {
66-
try {
67-
Files.createDirectories(file.getParent());
68-
} catch (IOException e) {
69-
MCTCommon.LOGGER.catching(e);
69+
public static void createDirectory(Path directory) throws IOException {
70+
/*
71+
* Test if the directory is a file,
72+
* but named like the target directory.
73+
*
74+
* For example, naming a file "tasfiles" and
75+
* putting it in the saves folder will succeed the "Files.exists" check,
76+
* but fail everywhere, where a directory is required...
77+
*
78+
* If this is the case, delete the file and create a directory instead.
79+
*/
80+
if (Files.exists(directory) && !Files.isDirectory(directory)) {
81+
Files.delete(directory);
7082
}
83+
84+
Files.createDirectories(directory);
7185
}
7286

7387
public void load() {

src/main/java/com/minecrafttas/tasmod/TASmodClient.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import static com.minecrafttas.tasmod.TASmod.LOGGER;
44

5-
import java.io.File;
65
import java.io.IOException;
76
import java.nio.file.Files;
87
import java.nio.file.Path;
@@ -18,6 +17,7 @@
1817
import com.minecrafttas.mctcommon.events.EventClient.EventOpenGui;
1918
import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide;
2019
import com.minecrafttas.mctcommon.events.EventListenerRegistry;
20+
import com.minecrafttas.mctcommon.file.AbstractDataFile;
2121
import com.minecrafttas.mctcommon.networking.Client;
2222
import com.minecrafttas.mctcommon.networking.PacketHandlerRegistry;
2323
import com.minecrafttas.mctcommon.networking.Server;
@@ -60,9 +60,9 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even
6060

6161
public static TickSyncClient ticksyncClient;
6262

63-
public static final String tasdirectory = Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles";
63+
public final static Path tasfiledirectory = Minecraft.getMinecraft().mcDataDir.toPath().resolve("saves").resolve("tasfiles");
6464

65-
public static final String savestatedirectory = Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "savestates";
65+
public final static Path savestatedirectory = Minecraft.getMinecraft().mcDataDir.toPath().resolve("saves").resolve("savestates");
6666

6767
public static InfoHud hud;
6868

@@ -95,17 +95,19 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even
9595
*/
9696
public static PlaybackControllerClient controller = new PlaybackControllerClient();
9797

98-
public static void createTASDir() {
99-
File tasDir = new File(tasdirectory);
100-
if (!tasDir.exists()) {
101-
tasDir.mkdir();
98+
public static void createTASfileDir() {
99+
try {
100+
AbstractDataFile.createDirectory(tasfiledirectory);
101+
} catch (IOException e) {
102+
TASmod.LOGGER.catching(e);
102103
}
103104
}
104105

105106
public static void createSavestatesDir() {
106-
File savestateDir = new File(savestatedirectory);
107-
if (!savestateDir.exists()) {
108-
savestateDir.mkdir();
107+
try {
108+
AbstractDataFile.createDirectory(savestatedirectory);
109+
} catch (IOException e) {
110+
TASmod.LOGGER.catching(e);
109111
}
110112
}
111113

@@ -114,6 +116,8 @@ public void onInitializeClient() {
114116

115117
LanguageManager.registerMod("tasmod");
116118

119+
createFolders();
120+
117121
registerConfigValues();
118122

119123
loadConfig(Minecraft.getMinecraft());
@@ -131,6 +135,11 @@ public void onInitializeClient() {
131135
// Initialize keybind manager
132136
keybindManager = new KeybindManager(VirtualKeybindings::isKeyDownExceptTextfield);
133137

138+
// Create them here so they are created after the folders have been created, since they depend on the tasfiles folder
139+
desyncMonitorFileCommandExtension = new DesyncMonitorFileCommandExtension();
140+
optionsFileCommandExtension = new OptionsFileCommandExtension();
141+
labelFileCommandExtension = new LabelFileCommandExtension();
142+
134143
registerEventListeners();
135144

136145
registerNetworkPacketHandlers();
@@ -144,6 +153,11 @@ public void onInitializeClient() {
144153

145154
}
146155

156+
private void createFolders() {
157+
createTASfileDir();
158+
createSavestatesDir();
159+
}
160+
147161
private void registerNetworkPacketHandlers() {
148162
// Register packet handlers
149163
LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client");
@@ -185,9 +199,6 @@ public void onClientInit(Minecraft mc) {
185199
registerPlaybackMetadata(mc);
186200
registerSerialiserFlavors(mc);
187201
registerFileCommands();
188-
189-
createTASDir();
190-
createSavestatesDir();
191202
}
192203

193204
boolean waszero;
@@ -308,9 +319,9 @@ private void registerSerialiserFlavors(Minecraft mc) {
308319
TASmodAPIRegistry.SERIALISER_FLAVOR.register(betaFlavor);
309320
}
310321

311-
public static DesyncMonitorFileCommandExtension desyncMonitorFileCommandExtension = new DesyncMonitorFileCommandExtension();
312-
public static OptionsFileCommandExtension optionsFileCommandExtension = new OptionsFileCommandExtension();
313-
public static LabelFileCommandExtension labelFileCommandExtension = new LabelFileCommandExtension();
322+
public static DesyncMonitorFileCommandExtension desyncMonitorFileCommandExtension;
323+
public static OptionsFileCommandExtension optionsFileCommandExtension;
324+
public static LabelFileCommandExtension labelFileCommandExtension;
314325

315326
private void registerFileCommands() {
316327
TASmodAPIRegistry.PLAYBACK_FILE_COMMAND.register(desyncMonitorFileCommandExtension);

src/main/java/com/minecrafttas/tasmod/commands/CommandFolder.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import static com.minecrafttas.tasmod.TASmod.LOGGER;
44

55
import java.awt.Desktop;
6-
import java.io.File;
76
import java.io.IOException;
7+
import java.nio.file.Path;
88
import java.util.ArrayList;
99
import java.util.List;
1010

@@ -30,13 +30,13 @@ public String getName() {
3030
@Override
3131
public String getUsage(ICommandSender sender) {
3232
return "/folder <type>";
33-
}
33+
}
3434

3535
@Override
3636
public int getRequiredPermissionLevel() {
3737
return 0;
3838
}
39-
39+
4040
@Override
4141
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
4242
if (args.length == 1) {
@@ -66,26 +66,24 @@ public List<String> getTabCompletions(MinecraftServer server, ICommandSender sen
6666
}
6767

6868
public static void openTASFolder() {
69-
File file = new File(TASmodClient.tasdirectory);
69+
Path file = TASmodClient.tasfiledirectory;
7070
try {
71-
if (!file.exists())
72-
file.mkdir();
73-
Desktop.getDesktop().open(file);
71+
TASmodClient.createTASfileDir();
72+
Desktop.getDesktop().open(file.toFile());
7473
} catch (IOException e) {
75-
LOGGER.error("Something went wrong while opening ", file.getPath());
76-
e.printStackTrace();
74+
LOGGER.error("Something went wrong while opening ", file);
75+
LOGGER.catching(e);
7776
}
7877
}
7978

8079
public static void openSavestates() {
81-
File file = new File(TASmodClient.savestatedirectory);
80+
Path file = TASmodClient.savestatedirectory;
8281
try {
83-
if (!file.exists())
84-
file.mkdir();
85-
Desktop.getDesktop().open(file);
82+
TASmodClient.createSavestatesDir();
83+
Desktop.getDesktop().open(file.toFile());
8684
} catch (IOException e) {
87-
LOGGER.error("Something went wrong while opening ", file.getPath());
88-
e.printStackTrace();
85+
LOGGER.error("Something went wrong while opening ", file);
86+
LOGGER.catching(e);
8987
}
9088
}
9189
}

src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
import java.io.IOException;
1515
import java.io.Serializable;
1616
import java.nio.ByteBuffer;
17+
import java.nio.file.Path;
18+
import java.nio.file.Paths;
1719
import java.util.ArrayList;
1820
import java.util.List;
1921

22+
import org.apache.logging.log4j.Logger;
2023
import org.lwjgl.opengl.Display;
2124

2225
import com.dselent.bigarraylist.BigArrayList;
@@ -28,6 +31,7 @@
2831
import com.minecrafttas.mctcommon.networking.exception.WrongSideException;
2932
import com.minecrafttas.mctcommon.networking.interfaces.ClientPacketHandler;
3033
import com.minecrafttas.mctcommon.networking.interfaces.PacketID;
34+
import com.minecrafttas.tasmod.TASmod;
3135
import com.minecrafttas.tasmod.TASmodClient;
3236
import com.minecrafttas.tasmod.events.EventClient.EventClientTickPost;
3337
import com.minecrafttas.tasmod.events.EventPlaybackClient;
@@ -80,6 +84,8 @@
8084
*/
8185
public class PlaybackControllerClient implements ClientPacketHandler, EventClientInit, EventVirtualInput.EventVirtualKeyboardTick, EventVirtualInput.EventVirtualMouseTick, EventVirtualInput.EventVirtualCameraAngleTick, EventClientTickPost {
8286

87+
private Logger logger = TASmod.LOGGER;
88+
8389
/**
8490
* The current state of the controller.
8591
*/
@@ -101,19 +107,32 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventClien
101107

102108
private VirtualCameraAngle camera = new VirtualCameraAngle();
103109

104-
public final File directory = new File(Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles");
110+
/**
111+
* The directory where to store the tasfiles
112+
*/
113+
public final Path tasFileDirectory;
114+
/**
115+
* The file ending of the TASfiles
116+
*/
117+
public final Path fileEnding = Paths.get(".mctas");
105118

106119
/**
107120
* The place where all inputs get stored
108121
*/
109-
private BigArrayList<TickContainer> inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
122+
private BigArrayList<TickContainer> inputs;
110123

111124
// private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); // TODO Replace with Metadata extension
112125

113126
// =====================================================================================================
114127

115128
private Integer playUntil = null; // TODO Replace with event
116129

130+
public PlaybackControllerClient() {
131+
tasFileDirectory = TASmodClient.tasfiledirectory;
132+
133+
inputs = new BigArrayList<TickContainer>(tasFileDirectory.resolve("temp").toAbsolutePath().toString());
134+
}
135+
117136
/**
118137
* Sets the current {@link TASstate}
119138
*
@@ -127,7 +146,7 @@ public void setTASState(TASstate stateIn) {
127146
try {
128147
TASmodClient.client.send(new TASmodBufferBuilder(PLAYBACK_STATE).writeTASState(stateIn));
129148
} catch (Exception e) {
130-
e.printStackTrace();
149+
logger.catching(e);
131150
}
132151
}
133152

@@ -478,7 +497,7 @@ public void setInputs(BigArrayList<TickContainer> inputs, long index) {
478497
} catch (IOException e) {
479498
e.printStackTrace();
480499
}
481-
this.inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
500+
this.inputs = new BigArrayList<TickContainer>(tasFileDirectory + File.separator + "temp");
482501
SerialiserFlavorBase.addAll(this.inputs, inputs);
483502
setIndex(index);
484503
}
@@ -522,7 +541,7 @@ public void clear() {
522541
} catch (IOException e) {
523542
e.printStackTrace();
524543
}
525-
inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
544+
inputs = new BigArrayList<TickContainer>(tasFileDirectory + File.separator + "temp");
526545
index = 0;
527546
}
528547

@@ -778,7 +797,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws
778797
flavor = TASmodBufferBuilder.readString(buf);
779798

780799
try {
781-
PlaybackSerialiser.saveToFile(new File(directory, name + ".mctas"), this, flavor);
800+
PlaybackSerialiser.saveToFile(tasFileDirectory.resolve(name + fileEnding), this, flavor);
782801
} catch (PlaybackSaveException e) {
783802
if (mc.world != null)
784803
mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.RED + e.getMessage()));
@@ -804,7 +823,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws
804823
flavor = TASmodBufferBuilder.readString(buf);
805824

806825
try {
807-
TASmodClient.controller.setInputs(PlaybackSerialiser.loadFromFile(new File(directory, name + ".mctas"), flavor));
826+
TASmodClient.controller.setInputs(PlaybackSerialiser.loadFromFile(tasFileDirectory.resolve(name + fileEnding), flavor));
808827
} catch (PlaybackLoadException e) {
809828
if (mc.world != null) {
810829
TextComponentString textComponent = new TextComponentString(e.getMessage());

0 commit comments

Comments
 (0)