Skip to content

Commit

Permalink
[FileCommands] Fix crash when tasfile folder doesn't exist (#222)
Browse files Browse the repository at this point in the history
- [FileCommands] Properly create temp folders on initialise
- [PlaybackSerialiser] Switch to paths
- [Tests] Switch to paths, fix some race conditions...
  • Loading branch information
ScribbleTAS authored Dec 18, 2024
2 parents 15c324f + 7daec20 commit 4bac6f5
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,33 @@ protected AbstractDataFile(Path file, String name, String comment) {
this.comment = comment;
this.properties = new Properties();

createDirectory(file);
try {
createDirectory(file.getParent());
} catch (IOException e) {
MCTCommon.LOGGER.catching(e);
}
}

/**
* Creates the directory for the file if it doesn't exist
* @param file The file to create the directory for
* @param directory The file to create the directory for
*/
protected void createDirectory(Path file) {
try {
Files.createDirectories(file.getParent());
} catch (IOException e) {
MCTCommon.LOGGER.catching(e);
public static void createDirectory(Path directory) throws IOException {
/*
* Test if the directory is a file,
* but named like the target directory.
*
* For example, naming a file "tasfiles" and
* putting it in the saves folder will succeed the "Files.exists" check,
* but fail everywhere, where a directory is required...
*
* If this is the case, delete the file and create a directory instead.
*/
if (Files.exists(directory) && !Files.isDirectory(directory)) {
Files.delete(directory);
}

Files.createDirectories(directory);
}

public void load() {
Expand Down
43 changes: 27 additions & 16 deletions src/main/java/com/minecrafttas/tasmod/TASmodClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -18,6 +17,7 @@
import com.minecrafttas.mctcommon.events.EventClient.EventOpenGui;
import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide;
import com.minecrafttas.mctcommon.events.EventListenerRegistry;
import com.minecrafttas.mctcommon.file.AbstractDataFile;
import com.minecrafttas.mctcommon.networking.Client;
import com.minecrafttas.mctcommon.networking.PacketHandlerRegistry;
import com.minecrafttas.mctcommon.networking.Server;
Expand Down Expand Up @@ -60,9 +60,9 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even

public static TickSyncClient ticksyncClient;

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

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

public static InfoHud hud;

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

public static void createTASDir() {
File tasDir = new File(tasdirectory);
if (!tasDir.exists()) {
tasDir.mkdir();
public static void createTASfileDir() {
try {
AbstractDataFile.createDirectory(tasfiledirectory);
} catch (IOException e) {
TASmod.LOGGER.catching(e);
}
}

public static void createSavestatesDir() {
File savestateDir = new File(savestatedirectory);
if (!savestateDir.exists()) {
savestateDir.mkdir();
try {
AbstractDataFile.createDirectory(savestatedirectory);
} catch (IOException e) {
TASmod.LOGGER.catching(e);
}
}

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

LanguageManager.registerMod("tasmod");

createFolders();

registerConfigValues();

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

// Create them here so they are created after the folders have been created, since they depend on the tasfiles folder
desyncMonitorFileCommandExtension = new DesyncMonitorFileCommandExtension();
optionsFileCommandExtension = new OptionsFileCommandExtension();
labelFileCommandExtension = new LabelFileCommandExtension();

registerEventListeners();

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

}

private void createFolders() {
createTASfileDir();
createSavestatesDir();
}

private void registerNetworkPacketHandlers() {
// Register packet handlers
LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client");
Expand Down Expand Up @@ -185,9 +199,6 @@ public void onClientInit(Minecraft mc) {
registerPlaybackMetadata(mc);
registerSerialiserFlavors(mc);
registerFileCommands();

createTASDir();
createSavestatesDir();
}

boolean waszero;
Expand Down Expand Up @@ -308,9 +319,9 @@ private void registerSerialiserFlavors(Minecraft mc) {
TASmodAPIRegistry.SERIALISER_FLAVOR.register(betaFlavor);
}

public static DesyncMonitorFileCommandExtension desyncMonitorFileCommandExtension = new DesyncMonitorFileCommandExtension();
public static OptionsFileCommandExtension optionsFileCommandExtension = new OptionsFileCommandExtension();
public static LabelFileCommandExtension labelFileCommandExtension = new LabelFileCommandExtension();
public static DesyncMonitorFileCommandExtension desyncMonitorFileCommandExtension;
public static OptionsFileCommandExtension optionsFileCommandExtension;
public static LabelFileCommandExtension labelFileCommandExtension;

private void registerFileCommands() {
TASmodAPIRegistry.PLAYBACK_FILE_COMMAND.register(desyncMonitorFileCommandExtension);
Expand Down
28 changes: 13 additions & 15 deletions src/main/java/com/minecrafttas/tasmod/commands/CommandFolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import static com.minecrafttas.tasmod.TASmod.LOGGER;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -30,13 +30,13 @@ public String getName() {
@Override
public String getUsage(ICommandSender sender) {
return "/folder <type>";
}
}

@Override
public int getRequiredPermissionLevel() {
return 0;
}

@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
if (args.length == 1) {
Expand Down Expand Up @@ -66,26 +66,24 @@ public List<String> getTabCompletions(MinecraftServer server, ICommandSender sen
}

public static void openTASFolder() {
File file = new File(TASmodClient.tasdirectory);
Path file = TASmodClient.tasfiledirectory;
try {
if (!file.exists())
file.mkdir();
Desktop.getDesktop().open(file);
TASmodClient.createTASfileDir();
Desktop.getDesktop().open(file.toFile());
} catch (IOException e) {
LOGGER.error("Something went wrong while opening ", file.getPath());
e.printStackTrace();
LOGGER.error("Something went wrong while opening ", file);
LOGGER.catching(e);
}
}

public static void openSavestates() {
File file = new File(TASmodClient.savestatedirectory);
Path file = TASmodClient.savestatedirectory;
try {
if (!file.exists())
file.mkdir();
Desktop.getDesktop().open(file);
TASmodClient.createSavestatesDir();
Desktop.getDesktop().open(file.toFile());
} catch (IOException e) {
LOGGER.error("Something went wrong while opening ", file.getPath());
e.printStackTrace();
LOGGER.error("Something went wrong while opening ", file);
LOGGER.catching(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
import java.io.IOException;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.Display;

import com.dselent.bigarraylist.BigArrayList;
Expand All @@ -28,6 +31,7 @@
import com.minecrafttas.mctcommon.networking.exception.WrongSideException;
import com.minecrafttas.mctcommon.networking.interfaces.ClientPacketHandler;
import com.minecrafttas.mctcommon.networking.interfaces.PacketID;
import com.minecrafttas.tasmod.TASmod;
import com.minecrafttas.tasmod.TASmodClient;
import com.minecrafttas.tasmod.events.EventClient.EventClientTickPost;
import com.minecrafttas.tasmod.events.EventPlaybackClient;
Expand Down Expand Up @@ -80,6 +84,8 @@
*/
public class PlaybackControllerClient implements ClientPacketHandler, EventClientInit, EventVirtualInput.EventVirtualKeyboardTick, EventVirtualInput.EventVirtualMouseTick, EventVirtualInput.EventVirtualCameraAngleTick, EventClientTickPost {

private Logger logger = TASmod.LOGGER;

/**
* The current state of the controller.
*/
Expand All @@ -101,19 +107,32 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventClien

private VirtualCameraAngle camera = new VirtualCameraAngle();

public final File directory = new File(Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles");
/**
* The directory where to store the tasfiles
*/
public final Path tasFileDirectory;
/**
* The file ending of the TASfiles
*/
public final Path fileEnding = Paths.get(".mctas");

/**
* The place where all inputs get stored
*/
private BigArrayList<TickContainer> inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
private BigArrayList<TickContainer> inputs;

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

// =====================================================================================================

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

public PlaybackControllerClient() {
tasFileDirectory = TASmodClient.tasfiledirectory;

inputs = new BigArrayList<TickContainer>(tasFileDirectory.resolve("temp").toAbsolutePath().toString());
}

/**
* Sets the current {@link TASstate}
*
Expand All @@ -127,7 +146,7 @@ public void setTASState(TASstate stateIn) {
try {
TASmodClient.client.send(new TASmodBufferBuilder(PLAYBACK_STATE).writeTASState(stateIn));
} catch (Exception e) {
e.printStackTrace();
logger.catching(e);
}
}

Expand Down Expand Up @@ -478,7 +497,7 @@ public void setInputs(BigArrayList<TickContainer> inputs, long index) {
} catch (IOException e) {
e.printStackTrace();
}
this.inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
this.inputs = new BigArrayList<TickContainer>(tasFileDirectory + File.separator + "temp");
SerialiserFlavorBase.addAll(this.inputs, inputs);
setIndex(index);
}
Expand Down Expand Up @@ -522,7 +541,7 @@ public void clear() {
} catch (IOException e) {
e.printStackTrace();
}
inputs = new BigArrayList<TickContainer>(directory + File.separator + "temp");
inputs = new BigArrayList<TickContainer>(tasFileDirectory + File.separator + "temp");
index = 0;
}

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

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

try {
TASmodClient.controller.setInputs(PlaybackSerialiser.loadFromFile(new File(directory, name + ".mctas"), flavor));
TASmodClient.controller.setInputs(PlaybackSerialiser.loadFromFile(tasFileDirectory.resolve(name + fileEnding), flavor));
} catch (PlaybackLoadException e) {
if (mc.world != null) {
TextComponentString textComponent = new TextComponentString(e.getMessage());
Expand Down
Loading

0 comments on commit 4bac6f5

Please sign in to comment.