mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 08:56:15 +00:00
Merge pull request #2690 from wschaeferB/2518-AnalyzeDataAsap
2518 analyze data asap
This commit is contained in:
commit
bca5a67aeb
@ -20,17 +20,30 @@ package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* The final panel of the add image wizard. It displays a progress bar and
|
||||
@ -42,21 +55,35 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript
|
||||
*/
|
||||
class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
|
||||
|
||||
private boolean readyToIngest = false;
|
||||
// task that will clean up the created database file if the wizard is cancelled before it finishes
|
||||
private AddImageAction.CleanupTask cleanupTask;
|
||||
|
||||
private final AddImageAction addImageAction;
|
||||
|
||||
private DataSourceProcessor dsProcessor = null;
|
||||
private boolean cancelled;
|
||||
/**
|
||||
* flag to indicate that the image adding process is finished and this panel
|
||||
* is completed(valid)
|
||||
*/
|
||||
private boolean imgAdded = false;
|
||||
private boolean ingested = false;
|
||||
/**
|
||||
* The visual component that displays this panel. If you need to access the
|
||||
* component from this class, just use getComponent().
|
||||
*/
|
||||
private AddImageWizardAddingProgressVisual component;
|
||||
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
|
||||
|
||||
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
|
||||
private final DSPProgressMonitorImpl dspProgressMonitorImpl = new DSPProgressMonitorImpl();
|
||||
private IngestJobSettings ingestJobSettings;
|
||||
|
||||
public DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
|
||||
AddImageWizardAddingProgressPanel(AddImageAction action) {
|
||||
this.addImageAction = action;
|
||||
}
|
||||
|
||||
DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
|
||||
return dspProgressMonitorImpl;
|
||||
}
|
||||
|
||||
@ -209,12 +236,24 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
|
||||
*/
|
||||
@Override
|
||||
public void readSettings(WizardDescriptor settings) {
|
||||
// Start ingest if it hasn't already been started
|
||||
startIngest();
|
||||
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
|
||||
if (imgAdded) {
|
||||
getComponent().setStateFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void resetReadyToIngest() {
|
||||
this.readyToIngest = false;
|
||||
}
|
||||
|
||||
void setIngestJobSettings(IngestJobSettings ingestSettings) {
|
||||
showWarnings(ingestSettings);
|
||||
this.readyToIngest = true;
|
||||
this.ingestJobSettings = ingestSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* this doesn't appear to store anything? plus, there are no settings in
|
||||
* this panel -jm
|
||||
@ -240,4 +279,136 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
|
||||
getComponent().showErrors(errorString, critical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start ingest after verifying we have a new image, we are ready to ingest,
|
||||
* and we haven't already ingested.
|
||||
*/
|
||||
private void startIngest() {
|
||||
if (!newContents.isEmpty() && readyToIngest && !ingested) {
|
||||
ingested = true;
|
||||
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings);
|
||||
setStateFinished();
|
||||
}
|
||||
}
|
||||
|
||||
private static void showWarnings(IngestJobSettings ingestJobSettings) {
|
||||
List<String> warnings = ingestJobSettings.getWarnings();
|
||||
if (warnings.isEmpty() == false) {
|
||||
StringBuilder warningMessage = new StringBuilder();
|
||||
for (String warning : warnings) {
|
||||
warningMessage.append(warning).append("\n");
|
||||
}
|
||||
JOptionPane.showMessageDialog(null, warningMessage.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Data source processing by kicking off the selected
|
||||
* DataSourceProcessor
|
||||
*/
|
||||
void startDataSourceProcessing(DataSourceProcessor dsp) {
|
||||
if (dsProcessor == null) { //this can only be run once
|
||||
final UUID dataSourceId = UUID.randomUUID();
|
||||
newContents.clear();
|
||||
cleanupTask = null;
|
||||
readyToIngest = false;
|
||||
dsProcessor = dsp;
|
||||
|
||||
// Add a cleanup task to interrupt the background process if the
|
||||
// wizard exits while the background process is running.
|
||||
cleanupTask = addImageAction.new CleanupTask() {
|
||||
@Override
|
||||
void cleanup() throws Exception {
|
||||
cancelDataSourceProcessing(dataSourceId);
|
||||
cancelled = true;
|
||||
}
|
||||
};
|
||||
|
||||
cleanupTask.enable();
|
||||
|
||||
new Thread(() -> {
|
||||
Case.getCurrentCase().notifyAddingDataSource(dataSourceId);
|
||||
}).start();
|
||||
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
|
||||
@Override
|
||||
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||
dataSourceProcessorDone(dataSourceId, result, errList, contents);
|
||||
}
|
||||
};
|
||||
|
||||
setStateStarted();
|
||||
|
||||
// Kick off the DSProcessor
|
||||
dsProcessor.run(getDSPProgressMonitorImpl(), cbObj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancels the data source processing - in case the users presses 'Cancel'
|
||||
*/
|
||||
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
||||
dsProcessor.cancel();
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for the data source processor. Invoked by the DSP on the EDT
|
||||
* thread, when it finishes processing the data source.
|
||||
*/
|
||||
private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||
// disable the cleanup task
|
||||
cleanupTask.disable();
|
||||
|
||||
// Get attention for the process finish
|
||||
// this caused a crash on OS X
|
||||
if (PlatformUtil.isWindowsOS() == true) {
|
||||
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
|
||||
}
|
||||
AddImageWizardAddingProgressVisual panel = getComponent();
|
||||
if (panel != null) {
|
||||
Window w = SwingUtilities.getWindowAncestor(panel);
|
||||
if (w != null) {
|
||||
w.toFront();
|
||||
}
|
||||
}
|
||||
// Tell the panel we're done
|
||||
setStateFinished();
|
||||
|
||||
//check the result and display to user
|
||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
|
||||
getComponent().setProgressBarTextAndColor(
|
||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
|
||||
} else {
|
||||
getComponent().setProgressBarTextAndColor(
|
||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
|
||||
}
|
||||
|
||||
//if errors, display them on the progress panel
|
||||
boolean critErr = false;
|
||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
|
||||
critErr = true;
|
||||
}
|
||||
for (String err : errList) {
|
||||
// TBD: there probably should be an error level for each error
|
||||
addErrors(err, critErr);
|
||||
}
|
||||
|
||||
//notify the UI of the new content added to the case
|
||||
new Thread(() -> {
|
||||
if (!contents.isEmpty()) {
|
||||
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
|
||||
} else {
|
||||
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
||||
}
|
||||
}).start();
|
||||
|
||||
if (!cancelled) {
|
||||
newContents.clear();
|
||||
newContents.addAll(contents);
|
||||
setStateStarted();
|
||||
startIngest();
|
||||
} else {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
|
||||
// paths to any set hash lookup databases (can be null)
|
||||
|
||||
AddImageWizardDataSourceSettingsPanel() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,7 +183,7 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
component.setDspSelection((String)settings.getProperty("SelectedDsp")); //NON-NLS magic string used SelectDataSourceProcessorPanel
|
||||
component.setDspSelection((String) settings.getProperty("SelectedDsp")); //NON-NLS magic string used SelectDataSourceProcessorPanel
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,28 +19,17 @@
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestProfileSelectionWizardPanel;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
|
||||
|
||||
@ -60,24 +49,10 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
|
||||
*/
|
||||
private Component component = null;
|
||||
private String lastProfileUsed = AddImageWizardIngestConfigPanel.class.getCanonicalName();
|
||||
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
|
||||
private boolean ingested = false;
|
||||
private boolean readyToIngest = false;
|
||||
// task that will clean up the created database file if the wizard is cancelled before it finishes
|
||||
private AddImageAction.CleanupTask cleanupTask;
|
||||
|
||||
private final AddImageAction addImageAction;
|
||||
|
||||
private final AddImageWizardAddingProgressPanel progressPanel;
|
||||
private final AddImageWizardDataSourceSettingsPanel dataSourcePanel;
|
||||
|
||||
private DataSourceProcessor dsProcessor;
|
||||
private boolean cancelled;
|
||||
|
||||
AddImageWizardIngestConfigPanel(AddImageWizardDataSourceSettingsPanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
||||
this.addImageAction = action;
|
||||
AddImageWizardIngestConfigPanel(AddImageWizardAddingProgressPanel proPanel) {
|
||||
this.progressPanel = proPanel;
|
||||
this.dataSourcePanel = dsPanel;
|
||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
|
||||
showWarnings(ingestJobSettings);
|
||||
//When this panel is viewed by the user it will always be displaying the
|
||||
@ -170,12 +145,6 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
|
||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text"));
|
||||
cancel.setEnabled(false);
|
||||
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, cancel});
|
||||
cleanupTask = null;
|
||||
readyToIngest = false;
|
||||
newContents.clear();
|
||||
// Start processing the data source by handing it off to the selected DSP,
|
||||
// so it gets going in the background while the user is still picking the Ingest modules
|
||||
startDataSourceProcessing();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,11 +160,7 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
|
||||
public void storeSettings(WizardDescriptor settings) {
|
||||
IngestJobSettings ingestJobSettings = ingestJobSettingsPanel.getSettings();
|
||||
ingestJobSettings.save();
|
||||
showWarnings(ingestJobSettings);
|
||||
|
||||
// Start ingest if it hasn't already been started
|
||||
readyToIngest = true;
|
||||
startIngest();
|
||||
progressPanel.setIngestJobSettings(ingestJobSettings); //prepare ingest for being started
|
||||
}
|
||||
|
||||
private static void showWarnings(IngestJobSettings ingestJobSettings) {
|
||||
@ -222,132 +187,7 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
|
||||
}
|
||||
//Because this panel kicks off ingest during the wizard we need to
|
||||
//swap out the ingestJobSettings for the ones of the chosen profile before
|
||||
//we start processing
|
||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(lastProfileUsed);
|
||||
ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
|
||||
showWarnings(ingestJobSettings);
|
||||
component = new AddImageWizardIngestConfigVisual(this.ingestJobSettingsPanel);
|
||||
readyToIngest = true;
|
||||
startDataSourceProcessing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start ingest after verifying we have a new image, we are ready to ingest,
|
||||
* and we haven't already ingested.
|
||||
*/
|
||||
private void startIngest() {
|
||||
if (!newContents.isEmpty() && readyToIngest && !ingested) {
|
||||
ingested = true;
|
||||
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettingsPanel.getSettings());
|
||||
progressPanel.setStateFinished();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Data source processing by kicking off the selected
|
||||
* DataSourceProcessor
|
||||
*/
|
||||
private void startDataSourceProcessing() {
|
||||
final UUID dataSourceId = UUID.randomUUID();
|
||||
|
||||
// Add a cleanup task to interrupt the background process if the
|
||||
// wizard exits while the background process is running.
|
||||
cleanupTask = addImageAction.new CleanupTask() {
|
||||
@Override
|
||||
void cleanup() throws Exception {
|
||||
cancelDataSourceProcessing(dataSourceId);
|
||||
cancelled = true;
|
||||
}
|
||||
};
|
||||
|
||||
cleanupTask.enable();
|
||||
|
||||
// get the selected DSProcessor
|
||||
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
|
||||
|
||||
new Thread(() -> {
|
||||
Case.getCurrentCase().notifyAddingDataSource(dataSourceId);
|
||||
}).start();
|
||||
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
|
||||
@Override
|
||||
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||
dataSourceProcessorDone(dataSourceId, result, errList, contents);
|
||||
}
|
||||
};
|
||||
|
||||
progressPanel.setStateStarted();
|
||||
|
||||
// Kick off the DSProcessor
|
||||
dsProcessor.run(progressPanel.getDSPProgressMonitorImpl(), cbObj);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancels the data source processing - in case the users presses 'Cancel'
|
||||
*/
|
||||
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
||||
dsProcessor.cancel();
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for the data source processor. Invoked by the DSP on the EDT
|
||||
* thread, when it finishes processing the data source.
|
||||
*/
|
||||
private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||
// disable the cleanup task
|
||||
cleanupTask.disable();
|
||||
|
||||
// Get attention for the process finish
|
||||
// this caused a crash on OS X
|
||||
if (PlatformUtil.isWindowsOS() == true) {
|
||||
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
|
||||
}
|
||||
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
|
||||
if (panel != null) {
|
||||
Window w = SwingUtilities.getWindowAncestor(panel);
|
||||
if (w != null) {
|
||||
w.toFront();
|
||||
}
|
||||
}
|
||||
// Tell the panel we're done
|
||||
progressPanel.setStateFinished();
|
||||
|
||||
//check the result and display to user
|
||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
|
||||
progressPanel.getComponent().setProgressBarTextAndColor(
|
||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
|
||||
} else {
|
||||
progressPanel.getComponent().setProgressBarTextAndColor(
|
||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
|
||||
}
|
||||
|
||||
//if errors, display them on the progress panel
|
||||
boolean critErr = false;
|
||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
|
||||
critErr = true;
|
||||
}
|
||||
for (String err : errList) {
|
||||
// TBD: there probably should be an error level for each error
|
||||
progressPanel.addErrors(err, critErr);
|
||||
}
|
||||
|
||||
//notify the UI of the new content added to the case
|
||||
new Thread(() -> {
|
||||
if (!contents.isEmpty()) {
|
||||
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
|
||||
} else {
|
||||
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
||||
}
|
||||
}).start();
|
||||
|
||||
if (!cancelled) {
|
||||
newContents.clear();
|
||||
newContents.addAll(contents);
|
||||
progressPanel.setStateStarted();
|
||||
startIngest();
|
||||
} else {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
progressPanel.setIngestJobSettings(ingestJobSettings); //prepare ingest for being started
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +56,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
||||
panels = new ArrayList<>();
|
||||
AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel();
|
||||
panels.add(dspSelection);
|
||||
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
|
||||
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action);
|
||||
|
||||
AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel();
|
||||
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel);
|
||||
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel);
|
||||
panels.add(dsPanel);
|
||||
List<IngestProfiles.IngestProfile> profiles = IngestProfiles.getIngestProfiles();
|
||||
if (!profiles.isEmpty()) {
|
||||
@ -174,7 +174,13 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
// Start processing the data source by handing it off to the selected DSP,
|
||||
// so it gets going in the background while the user is still picking the Ingest modules
|
||||
// This will occur when the next button is clicked on the panel where you have chosen your data to process
|
||||
if (index == dsPanelIndex) {
|
||||
((AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex)).
|
||||
startDataSourceProcessing(((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent().getCurrentDSProcessor());
|
||||
}
|
||||
boolean panelEnablesSkipping = current().panelEnablesSkipping();
|
||||
boolean skipNextPanel = current().skipNextPanel();
|
||||
index++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user