private void init(ResourceEntry targetEntry) { songEntry = targetEntry; songId = -1L; Song2daBitmap songBitmap = new Song2daBitmap(StreamUtils.getByteBuffer(4), 0, 4); List<RefEntry> resList = songBitmap.getResourceList(); for (final RefEntry refEntry : resList) { ResourceEntry entry = refEntry.getResourceEntry(); if (entry != null && entry.equals(targetEntry)) { songId = refEntry.getValue(); break; } } if (songId >= 0) { if (Profile.getGame() != Profile.Game.PST) { scriptActions.add(Pattern.compile("StartMusic\\(" + Long.toString(songId) + ",.+\\)")); IdsMap map = null; if (ResourceFactory.resourceExists("SONGLIST.IDS")) { map = IdsMapCache.get("SONGLIST.IDS"); } else if (Profile.getGame() == Profile.Game.IWD2) { map = IdsMapCache.get("MUSIC.IDS"); } if (map != null && map.getMap().containsKey(Long.valueOf(songId))) { String musicId = map.getMap().get(Long.valueOf(songId)).getString(); scriptActions.add(Pattern.compile("SetMusic\\(.+?," + Long.toString(songId) + "\\)")); if (musicId != null && !musicId.isEmpty()) { scriptActions.add(Pattern.compile("SetMusic\\(.+?," + musicId + "\\)")); } } } } }
// Returns the actual physical file of the given resource entry or null. private static Path getCurrentFile(ResourceEntry entry) { if (entry instanceof FileResourceEntry || (entry instanceof BIFFResourceEntry && entry.hasOverride())) { return entry.getActualPath(); } else { return null; } }
@Override public void show(Component invoker, int x, int y) { super.show(invoker, x, y); mi_rename.setEnabled(tree.getLastSelectedPathComponent() instanceof FileResourceEntry); if (tree.getLastSelectedPathComponent() instanceof ResourceEntry) { ResourceEntry entry = (ResourceEntry) tree.getLastSelectedPathComponent(); mi_delete.setEnabled( entry != null && entry.hasOverride() || entry instanceof FileResourceEntry); mi_restore.setEnabled(isBackupAvailable(entry)); } else { mi_delete.setEnabled(false); mi_restore.setEnabled(false); } }
/** * Returns whether a backup exists in the same folder as the specified resource entry or a biffed * file has been overriden. */ static boolean isBackupAvailable(ResourceEntry entry) { if (entry != null) { return (getBackupFile(entry) != null || (entry instanceof BIFFResourceEntry && entry.hasOverride())); } return false; }
private void searchStruct(ResourceEntry entry, AbstractStruct struct) { List<StructEntry> list = struct.getFlatList(); for (final StructEntry e : list) { if (e instanceof Song2daBitmap) { int v = ((Song2daBitmap) e).getValue(); if (v == songId) { addHit(entry, String.format("%s (%d)", songEntry.getResourceName(), songId), e); } } } }
// Returns the backup file of the specified resource entry if available or null. // A backup file is either a *.bak file or a biffed file which has been overridden. private static Path getBackupFile(ResourceEntry entry) { Path file = getCurrentFile(entry); if (entry instanceof FileResourceEntry || (entry instanceof BIFFResourceEntry && entry.hasOverride())) { if (file != null) { Path bakFile = file.getParent().resolve(file.getFileName().toString() + ".bak"); if (Files.isRegularFile(bakFile)) { return bakFile; } } } else if (entry instanceof BIFFResourceEntry) { return file; } return null; }
/** * Attempts to restore the specified resource entry if it's backed up by an associated "*.bak" * file. */ static void restoreResource(ResourceEntry entry) { if (entry != null) { final String[] options = {"Restore", "Cancel"}; final String msgBackup = "Are you sure you want to restore " + entry + " with a previous version?"; final String msgBiffed = "Are you sure you want to restore the biffed version of " + entry + "?"; Path bakFile = getBackupFile(entry); boolean isBackedUp = (bakFile != null) && (bakFile.getFileName().toString().toLowerCase(Locale.ENGLISH).endsWith(".bak")); if (JOptionPane.showOptionDialog( NearInfinity.getInstance(), isBackedUp ? msgBackup : msgBiffed, "Restore backup", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]) == JOptionPane.YES_OPTION) { NearInfinity.getInstance().removeViewable(); if (bakFile != null && (bakFile.getFileName().toString().toLowerCase(Locale.ENGLISH).endsWith(".bak"))) { // .bak available -> restore .bak version Path curFile = getCurrentFile(entry); Path tmpFile = getTempFile(curFile); if (curFile != null && Files.isRegularFile(curFile) && bakFile != null && Files.isRegularFile(bakFile)) { try { Files.move(curFile, tmpFile); try { Files.move(bakFile, curFile); try { Files.delete(tmpFile); } catch (IOException e) { e.printStackTrace(); } JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Backup has been restored successfully.", "Restore backup", JOptionPane.INFORMATION_MESSAGE); return; } catch (IOException e) { // Worst possible scenario: failed restore operation can't restore original resource String path = tmpFile.getParent().toString(); String tmpName = tmpFile.getFileName().toString(); String curName = curFile.getFileName().toString(); JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Error while restoring resource.\n" + "Near Infinity is unable to recover from the restore operation.\n" + String.format( "Please manually rename the file \"%1$s\" into \"%2$s\", located in \n + \"%3$s\"", tmpName, curName, path), "Critical Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); return; } } catch (IOException e) { e.printStackTrace(); } } JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Error while restoring resource.\nRestore operation has been cancelled.", "Error", JOptionPane.ERROR_MESSAGE); } else if (entry instanceof BIFFResourceEntry && entry.hasOverride()) { // Biffed and no .bak available -> delete overridden copy try { ((BIFFResourceEntry) entry).deleteOverride(); JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Backup has been restored successfully.", "Restore backup", JOptionPane.INFORMATION_MESSAGE); } catch (IOException e) { JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Error removing file \"" + entry + "\" from override folder!", "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } } } }
/** Attempts to delete the specified resource if it exists as a file in the game path. */ static void deleteResource(ResourceEntry entry) { if (entry instanceof FileResourceEntry) { String options[] = {"Delete", "Cancel"}; if (JOptionPane.showOptionDialog( NearInfinity.getInstance(), "Are you sure you want to delete " + entry + '?', "Delete file", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]) != 0) return; NearInfinity.getInstance().removeViewable(); ResourceFactory.getResources().removeResourceEntry(entry); Path bakFile = getBackupFile(entry); if (bakFile != null) { try { Files.delete(bakFile); } catch (IOException e) { e.printStackTrace(); } } try { ((FileResourceEntry) entry).deleteFile(); } catch (IOException e) { JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Error deleting file \"" + entry.getResourceName() + "\"!", "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } else if (entry instanceof BIFFResourceEntry) { String options[] = {"Delete", "Cancel"}; if (JOptionPane.showOptionDialog( NearInfinity.getInstance(), "Are you sure you want to delete the " + "override file " + entry + '?', "Delete file", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]) != 0) return; NearInfinity.getInstance().removeViewable(); Path bakFile = getBackupFile(entry); if (bakFile != null) { try { Files.delete(bakFile); } catch (IOException e) { e.printStackTrace(); } } try { ((BIFFResourceEntry) entry).deleteOverride(); } catch (IOException e) { JOptionPane.showMessageDialog( NearInfinity.getInstance(), "Error deleting file \"" + entry.getResourceName() + "\"!", "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } }