Skip to content

Commit

Permalink
Added support for selecting optional components to install as part of…
Browse files Browse the repository at this point in the history
… an update.

<package version="1.1">
  <component id="base" required="true">
    <title>Base Game</title>
    <description>The base game files.</description>
  </component>
  <component id="eduardo" default="true">
    <title>Picture of Eduardo</title>
    <description>Draws a picture of Eduardo on your screen.</description>
  </component>
  <component id="alice">
    <title>Picture of Alice</title>
    <description>Draws a picture of Alice on your screen.</description>
  </component>
  <filegroup source="http://example.com/update/" dest=".">
    <!-- Eduardo doesn't want to exist with Alice around -->
    <file size="1024" component="eduardo, !alice">eduardo.png</file>
    <file size="1024" component="alice">alice.png</file>
  </filegroup>
</package>
  • Loading branch information
sk89q committed Jun 6, 2013
1 parent 5f46733 commit 008da45
Show file tree
Hide file tree
Showing 9 changed files with 508 additions and 29 deletions.
41 changes: 20 additions & 21 deletions src/main/java/com/sk89q/mclauncher/LaunchTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public class LaunchTask extends Task {
private boolean playOffline = false;
private boolean skipUpdateCheck = false;
private boolean forceUpdate = false;
private boolean forceIncrementalUpdate = false;
private boolean wantUpdate = false;
private boolean notInstalled = false;
private volatile Updater updater;
Expand Down Expand Up @@ -124,6 +125,16 @@ public void setPlayOffline(boolean playOffline) {
public void setForceUpdate(boolean forceUpdate) {
this.forceUpdate = forceUpdate;
}

/**
* Set update force state.
*
* @param forceIncrementalUpdate true to force update
*/
public void setForceIncrementalUpdate(boolean forceIncrementalUpdate) {
this.forceIncrementalUpdate = forceIncrementalUpdate;

}

/**
* Set to show the Java console.
Expand Down Expand Up @@ -554,7 +565,7 @@ public void run() {
}

// Ask the user if s/he wants to update
if (!forceUpdate && updateRequired && !notInstalled) {
if (!forceUpdate && !forceIncrementalUpdate && updateRequired && !notInstalled) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
Expand All @@ -572,7 +583,7 @@ public void run() {
}

// Proceed with the update
if (notInstalled || forceUpdate || (updateRequired && wantUpdate)) {
if (notInstalled || forceUpdate || forceIncrementalUpdate || (updateRequired && wantUpdate)) {
// We have a custom package definition URL that we have to fetch!
if (packageDefUrl != null) {
fireStatusChange("Downloading package definition for update...");
Expand All @@ -593,7 +604,8 @@ public void run() {
throw new IOException("Did not get expected 200 code");
}

update(rootDir, cache, conn.getInputStream(), forceUpdate, username, ticket);
update(rootDir, cache, conn.getInputStream(),
forceUpdate, forceIncrementalUpdate, username, ticket);
} catch (IOException e) {
e.printStackTrace();
throw new ExecutionException("Could not fetch the update package definition file (" +
Expand All @@ -605,7 +617,7 @@ public void run() {
} else {
// For vanilla, we bundle the package
update(rootDir, cache, Launcher.class.getResourceAsStream("/resources/update.xml"),
forceUpdate, username, ticket);
forceUpdate, forceIncrementalUpdate, username, ticket);
}

// Check for cancel
Expand All @@ -630,13 +642,15 @@ public void run() {
* @param rootDir path to the working directory of minecraft
* @param packageStream input stream of the package .xml file
* @param forced true to force re-download
* @param forcedIncremental true to force an incremental update
* @throws ExecutionException thrown on any error
*/
private void update(File rootDir, UpdateCache cache, InputStream packageStream,
boolean forced, String username, String ticket) throws ExecutionException {
boolean forced, boolean forcedIncremental,
String username, String ticket) throws ExecutionException {
fireTitleChange("Updating Minecraft...");

updater = new Updater(packageStream, rootDir, cache);
updater = new Updater(frame, packageStream, rootDir, cache);
updater.setReinstall(forced);
updater.registerParameter("user", username);
updater.registerParameter("ticket", "deprecated"); // Now deprecated
Expand All @@ -653,21 +667,6 @@ private void update(File rootDir, UpdateCache cache, InputStream packageStream,
logger.log(Level.SEVERE, "Update error occurred", t);
throw new ExecutionException("An unknown error occurred.", t);
}

// Remind the user to disable mods
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(getComponent(),
"Your game has been updated. If you encounter problems, " +
"try disabling any mods (if any) that you have installed.",
"Update completed", JOptionPane.INFORMATION_MESSAGE);
}
});
} catch (InterruptedException e) {
} catch (InvocationTargetException e) {
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/sk89q/mclauncher/LauncherFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public class LauncherFrame extends JFrame {
private JTextField passText;
private JCheckBox rememberPass;
private JCheckBox forceUpdateCheck;
private JCheckBox changeComponentsCheck;
private JCheckBox playOfflineCheck;
private JCheckBox showConsoleCheck;
private JCheckBox autoConnectCheck;
Expand Down Expand Up @@ -557,6 +558,9 @@ private JPanel createLoginPanel() {

forceUpdateCheck = new JCheckBox("Force a game update");
forceUpdateCheck.setBorder(null);

changeComponentsCheck = new JCheckBox("Re-select install options (if any)");
changeComponentsCheck.setBorder(null);

playOfflineCheck = new JCheckBox("Play in offline mode");
playOfflineCheck.setBorder(null);
Expand Down Expand Up @@ -590,6 +594,7 @@ public void actionPerformed(ActionEvent e) {
panel.add(rememberPass, checkboxC);
panel.add(autoConnectCheck, checkboxC);
panel.add(forceUpdateCheck, checkboxC);
panel.add(changeComponentsCheck, checkboxC);
panel.add(playOfflineCheck, checkboxC);
panel.add(showConsoleCheck, checkboxC);
panel.add(expandContainer, checkboxC);
Expand All @@ -598,6 +603,7 @@ public void actionPerformed(ActionEvent e) {
jarLabel.setVisible(false);
jarCombo.setVisible(false);
forceUpdateCheck.setVisible(false);
changeComponentsCheck.setVisible(false);
playOfflineCheck.setVisible(false);

userText.addActionListener(new ActionListener() {
Expand Down Expand Up @@ -661,6 +667,7 @@ public void actionPerformed(ActionEvent e) {
jarLabel.setVisible(true);
jarCombo.setVisible(true);
forceUpdateCheck.setVisible(true);
changeComponentsCheck.setVisible(true);
playOfflineCheck.setVisible(allowOfflineName);
// registerAccount.setVisible(true);
}
Expand Down Expand Up @@ -897,6 +904,7 @@ public void launch(String autoConnect, boolean test) {

LaunchTask task = new LaunchTask(this, getWorkspace(), username, password, jar);
task.setForceUpdate(forceUpdateCheck.isSelected());
task.setForceIncrementalUpdate(changeComponentsCheck.isSelected());
task.setPlayOffline(playOfflineCheck.isSelected() || (test && options.getSettings().getBool(Def.FAST_TEST, false)));
task.setShowConsole(showConsoleCheck.isSelected());
if (autoConnect != null) {
Expand Down
148 changes: 148 additions & 0 deletions src/main/java/com/sk89q/mclauncher/SelectComponentsDialog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* SK's Minecraft Launcher
* Copyright (C) 2010, 2011 Albert Pham <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.mclauncher;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;

import com.sk89q.mclauncher.model.Component;
import com.sk89q.mclauncher.model.ComponentTableModel;
import com.sk89q.mclauncher.model.PackageManifest;

public class SelectComponentsDialog extends JDialog {

private static final long serialVersionUID = -8771235345163527656L;

private final PackageManifest manifest;

private JTable table;

public SelectComponentsDialog(JFrame frame, PackageManifest manifest) {
super(frame, "Select Install Options", true);

this.manifest = manifest;

setResizable(true);
buildUI();
pack();
setSize(320, 500);
setLocationRelativeTo(frame);
}

private void buildUI() {
JPanel container = new JPanel();
container.setLayout(new BorderLayout(8, 8));
container.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));

JLabel infoLabel = new JLabel(
"<html>To change these later, select 'Re-select install options' " +
"after clicking 'More Options' on the launcher.");
container.add(infoLabel, BorderLayout.NORTH);

table = new JTable() {
private static final long serialVersionUID = 4897191210730076435L;

@Override
public java.awt.Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
java.awt.Component c = super.prepareRenderer(renderer, row, col);
if (col == 0) {
c.setEnabled(!((Component) (getModel()).getValueAt(row, 1)).isRequired());
}
return c;
}
};

table.setTableHeader(null);
table.setShowGrid(false);
table.setRowHeight(table.getRowHeight() + 2);
table.setIntercellSpacing(new Dimension(0, 0));
table.setFillsViewportHeight(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setModel(new ComponentTableModel(manifest.getComponents()));
table.getColumnModel().getColumn(0).setMaxWidth(30);
JScrollPane tableScroll = new JScrollPane(table);
container.add(tableScroll, BorderLayout.CENTER);

JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout(0, 8));
container.add(bottomPanel, BorderLayout.SOUTH);

JLabel descLabel = new JLabel("<html><b>Description:</b>");
bottomPanel.add(descLabel, BorderLayout.NORTH);

final JTextArea descArea = new JTextArea("Select an option to see its description.") {
private static final long serialVersionUID = 4339941505774335040L;

@Override
public Dimension getPreferredSize() {
return new Dimension((int) super.getPreferredSize().getWidth(), 100);
}
};
descArea.setFont(descLabel.getFont());
descArea.setBackground(descLabel.getBackground());
descArea.setEditable(false);
descArea.setWrapStyleWord(true);
descArea.setLineWrap(true);
JScrollPane descScroll = new JScrollPane(descArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
bottomPanel.add(descScroll, BorderLayout.CENTER);

add(container, BorderLayout.CENTER);

table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
Component component = (Component) (table.getModel()).getValueAt(table.getSelectedRow(), 1);
descArea.setText(component.getDescription());
}
});

JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 5));
JButton installButton = new JButton("Continue...");
buttonsPanel.add(installButton);
bottomPanel.add(buttonsPanel, BorderLayout.SOUTH);

installButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}

}
81 changes: 81 additions & 0 deletions src/main/java/com/sk89q/mclauncher/model/Component.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.sk89q.mclauncher.model;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement(name = "component")
public class Component {

private String id;
private String title;
private String description;
private boolean defaultSelected;
private boolean required;

private transient boolean selected;

@XmlAttribute(name = "id")
public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

@XmlElement
public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

@XmlElement
public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

@XmlAttribute(name = "default")
public boolean isDefaultSelected() {
return defaultSelected;
}

public void setDefaultSelected(boolean defaultSelected) {
this.defaultSelected = defaultSelected;
if (defaultSelected) {
selected = true;
}
}

@XmlAttribute(name = "required")
public boolean isRequired() {
return required;
}

public void setRequired(boolean required) {
this.required = required;
}

@XmlTransient
public boolean isSelected() {
return required || selected;
}

public void setSelected(boolean selected) {
this.selected = selected;
}

@Override
public String toString() {
return getTitle();
}

}
Loading

0 comments on commit 008da45

Please sign in to comment.