Skip to content

Commit

Permalink
Added skin unpacker (.osk), and changed all import dirs to "Import".
Browse files Browse the repository at this point in the history
- Skin packs placed in the "Import" directory will be imported to the root skin directory.
- Consolidated the replay import directory and song pack directory into one directory (since files are distinguished by extension).

Signed-off-by: Jeffrey Han <[email protected]>
  • Loading branch information
itdelatrisu committed Jan 2, 2017
1 parent 8080ff2 commit e9889b7
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/ReplayImport/
/Import/
/Replays/
/Screenshots/
/Skins/
Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,17 @@ The following files and folders will be created by opsu! as needed:
logged to this file, and other warnings not shown are logged as well.
* `Songs/`: The beatmap directory (not used if an osu! installation is detected).
The parser searches all of its subdirectories for .osu files to load.
* `SongPacks/`: The beatmap pack directory. The unpacker extracts all .osz
files within this directory to the beatmap directory.
* `Skins/`: The skins directory. Each skin must be placed in a folder within
this directory. Any game resource (in `res/`) can be skinned by placing a
file with the same name in a skin folder. Skins can be selected in the
options menu.
* `Screenshots/`: The screenshot directory. Screenshots can be taken by
pressing the F12 key.
* `Replays/`: The replay directory. Replays of each completed game are saved
as .osr files, and can be viewed at a later time or shared with others.
* `ReplayImport/`: The replay import directory. The importer moves all .osr
files within this directory to the replay directory and saves the scores in
the scores database. Replays can be imported from osu! as well as opsu!.
* `Import/`: The import directory. All beatmap packs (.osz) and skin
packs (.osk) are unpacked to the proper location. All replays (.osr) are
moved to the replay directory, and their scores saved to the scores database.
* `Screenshots/`: The screenshot directory. Screenshots can be taken by
pressing the F12 key.
* `Natives/`: The native libraries directory.
* `Temp/`: The temporary files directory. Deleted when opsu! exits.

Expand Down
88 changes: 35 additions & 53 deletions src/itdelatrisu/opsu/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,15 @@ public class Options {
/** The beatmap directory. */
private static File beatmapDir;

/** The OSZ archive directory. */
private static File oszDir;
/** The import directory. */
private static File importDir;

/** The screenshot directory (created when needed). */
private static File screenshotDir;

/** The replay directory (created when needed). */
private static File replayDir;

/** The replay import directory. */
private static File replayImportDir;

/** The root skin directory. */
private static File skinRootDir;

Expand Down Expand Up @@ -235,12 +232,12 @@ public enum GameOption {
@Override
public void read(String s) { beatmapDir = new File(s); }
},
OSZ_DIRECTORY ("OSZDirectory") {
IMPORT_DIRECTORY ("ImportDirectory") {
@Override
public String write() { return getOSZDir().getAbsolutePath(); }
public String write() { return getImportDir().getAbsolutePath(); }

@Override
public void read(String s) { oszDir = new File(s); }
public void read(String s) { importDir = new File(s); }
},
SCREENSHOT_DIRECTORY ("ScreenshotDirectory") {
@Override
Expand All @@ -256,13 +253,6 @@ public enum GameOption {
@Override
public void read(String s) { replayDir = new File(s); }
},
REPLAY_IMPORT_DIRECTORY ("ReplayImportDirectory") {
@Override
public String write() { return getReplayImportDir().getAbsolutePath(); }

@Override
public void read(String s) { replayImportDir = new File(s); }
},
SKIN_DIRECTORY ("SkinDirectory") {
@Override
public String write() { return getSkinRootDir().getAbsolutePath(); }
Expand Down Expand Up @@ -369,15 +359,32 @@ public void toggle(GameContainer container) {
}
},
SKIN ("Skin", "Skin", "Restart (Ctrl+Shift+F5) to apply skin changes.") {
private String[] itemList = null;

/** Creates the list of available skins. */
private void createSkinList() {
File[] dirs = SkinLoader.getSkinDirectories(getSkinRootDir());
itemList = new String[dirs.length + 1];
itemList[0] = Skin.DEFAULT_SKIN_NAME;
for (int i = 0; i < dirs.length; i++)
itemList[i + 1] = dirs[i].getName();
}

@Override
public String getValueString() { return skinName; }

@Override
public Object[] getItemList() { return skinDirs; }
public Object[] getItemList() {
if (itemList == null)
createSkinList();
return itemList;
}

@Override
public void selectItem(int index, GameContainer container) {
skinName = skinDirs[index];
if (itemList == null)
createSkinList();
skinName = itemList[index];
UI.sendBarNotification(getDescription());
}

Expand Down Expand Up @@ -880,9 +887,6 @@ public boolean hasFullscreenDisplayMode() {
/** Current screen resolution. */
private static Resolution resolution = Resolution.RES_1024_768;

/** The available skin directories. */
private static String[] skinDirs;

/** The name of the skin. */
private static String skinName = "Default";

Expand Down Expand Up @@ -1302,33 +1306,18 @@ public static File getBeatmapDir() {
}

/**
* Returns the OSZ archive directory.
* If invalid, this will create and return a "SongPacks" directory.
* @return the OSZ archive directory
* Returns the import directory (for beatmaps, skins, and replays).
* If invalid, this will create and return an "Import" directory.
* @return the import directory
*/
public static File getOSZDir() {
if (oszDir != null && oszDir.isDirectory())
return oszDir;

oszDir = new File(DATA_DIR, "SongPacks/");
if (!oszDir.isDirectory() && !oszDir.mkdir())
ErrorHandler.error(String.format("Failed to create song packs directory at '%s'.", oszDir.getAbsolutePath()), null, false);
return oszDir;
}

/**
* Returns the replay import directory.
* If invalid, this will create and return a "ReplayImport" directory.
* @return the replay import directory
*/
public static File getReplayImportDir() {
if (replayImportDir != null && replayImportDir.isDirectory())
return replayImportDir;

replayImportDir = new File(DATA_DIR, "ReplayImport/");
if (!replayImportDir.isDirectory() && !replayImportDir.mkdir())
ErrorHandler.error(String.format("Failed to create replay import directory at '%s'.", replayImportDir.getAbsolutePath()), null, false);
return replayImportDir;
public static File getImportDir() {
if (importDir != null && importDir.isDirectory())
return importDir;

importDir = new File(DATA_DIR, "Import/");
if (!importDir.isDirectory() && !importDir.mkdir())
ErrorHandler.error(String.format("Failed to create import directory at '%s'.", importDir.getAbsolutePath()), null, false);
return importDir;
}

/**
Expand Down Expand Up @@ -1390,13 +1379,6 @@ public static void loadSkin() {
if (skinDir == null) // invalid skin name
skinName = Skin.DEFAULT_SKIN_NAME;

// create available skins list
File[] dirs = SkinLoader.getSkinDirectories(getSkinRootDir());
skinDirs = new String[dirs.length + 1];
skinDirs[0] = Skin.DEFAULT_SKIN_NAME;
for (int i = 0; i < dirs.length; i++)
skinDirs[i + 1] = dirs[i].getName();

// set skin and modify resource locations
ResourceLoader.removeAllResourceLocations();
if (skinDir == null)
Expand Down
18 changes: 18 additions & 0 deletions src/itdelatrisu/opsu/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@

import com.sun.jna.platform.FileUtils;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

/**
* Contains miscellaneous utilities.
*/
Expand Down Expand Up @@ -322,6 +325,21 @@ else if (doReplace)
return cleanName.toString();
}

/**
* Extracts the contents of a ZIP archive to a destination.
* @param file the ZIP archive
* @param dest the destination directory
*/
public static void unzip(File file, File dest) {
try {
ZipFile zipFile = new ZipFile(file);
zipFile.extractAll(dest.getAbsolutePath());
} catch (ZipException e) {
ErrorHandler.error(String.format("Failed to unzip file %s to dest %s.",
file.getAbsolutePath(), dest.getAbsolutePath()), e, false);
}
}

/**
* Deletes a file or directory. If a system trash directory is available,
* the file or directory will be moved there instead.
Expand Down
25 changes: 3 additions & 22 deletions src/itdelatrisu/opsu/beatmap/OszUnpacker.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@

package itdelatrisu.opsu.beatmap;

import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.Utils;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

/**
* Unpacker for OSZ (ZIP) archives.
*/
Expand All @@ -46,8 +43,7 @@ private OszUnpacker() {}
* Invokes the unpacker for each OSZ archive in a root directory.
* @param root the root directory
* @param dest the destination directory
* @return an array containing the new (unpacked) directories, or null
* if no OSZs found
* @return an array containing the new (unpacked) directories
*/
public static File[] unpackAllFiles(File root, File dest) {
List<File> dirs = new ArrayList<File>();
Expand All @@ -74,7 +70,7 @@ public boolean accept(File dir, String name) {
File songDir = new File(dest, dirName);
if (!songDir.isDirectory()) {
songDir.mkdir();
unzip(file, songDir);
Utils.unzip(file, songDir);
file.delete(); // delete the OSZ when finished
dirs.add(songDir);
}
Expand All @@ -87,21 +83,6 @@ public boolean accept(File dir, String name) {
return dirs.toArray(new File[dirs.size()]);
}

/**
* Extracts the contents of a ZIP archive to a destination.
* @param file the ZIP archive
* @param dest the destination directory
*/
private static void unzip(File file, File dest) {
try {
ZipFile zipFile = new ZipFile(file);
zipFile.extractAll(dest.getAbsolutePath());
} catch (ZipException e) {
ErrorHandler.error(String.format("Failed to unzip file %s to dest %s.",
file.getAbsolutePath(), dest.getAbsolutePath()), e, false);
}
}

/**
* Returns the name of the current file being unpacked, or null if none.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/itdelatrisu/opsu/downloads/DownloadNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public void createDownload(DownloadServer server) {
String url = server.getDownloadURL(beatmapSetID);
if (url == null)
return;
String path = String.format("%s%c%d", Options.getOSZDir(), File.separatorChar, beatmapSetID);
String path = String.format("%s%c%d", Options.getImportDir(), File.separatorChar, beatmapSetID);
String rename = String.format("%d %s - %s.osz", beatmapSetID, artist, title);
Download download = new Download(url, path, rename);
download.setListener(new DownloadListener() {
Expand Down
4 changes: 2 additions & 2 deletions src/itdelatrisu/opsu/replay/ReplayImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*/
public class ReplayImporter {
/** The subdirectory (within the replay import directory) to move replays that could not be imported. */
private static final String FAILED_IMPORT_DIR = "failed";
private static final String FAILED_IMPORT_DIR = "InvalidReplays";

/** The index of the current file being imported. */
private static int fileIndex = -1;
Expand Down Expand Up @@ -114,7 +114,7 @@ public boolean accept(File dir, String name) {
* @param file the file to move
*/
private static void moveToFailedDirectory(File file) {
File dir = new File(Options.getReplayImportDir(), FAILED_IMPORT_DIR);
File dir = new File(Options.getImportDir(), FAILED_IMPORT_DIR);
dir.mkdir();
File moveToFile = new File(dir, file.getName());
try {
Expand Down
Loading

0 comments on commit e9889b7

Please sign in to comment.