mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Add Net Decks support
This commit is contained in:
@@ -27,6 +27,7 @@ import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.FDeckViewer;
|
||||
import forge.deck.FSideboardDialog;
|
||||
import forge.download.GuiDownloadService;
|
||||
import forge.error.BugReportDialog;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameEntityView;
|
||||
@@ -40,12 +41,14 @@ import forge.player.PlayerControllerHuman;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.screens.quest.QuestMenu;
|
||||
import forge.screens.settings.GuiDownloader;
|
||||
import forge.sound.AudioClip;
|
||||
import forge.sound.AudioMusic;
|
||||
import forge.sound.IAudioClip;
|
||||
import forge.sound.IAudioMusic;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.GuiChoose;
|
||||
import forge.util.Callback;
|
||||
import forge.util.FCollectionView;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.MessageUtil;
|
||||
@@ -291,6 +294,11 @@ public class GuiMobile implements IGuiBase {
|
||||
return defaultFile; //TODO: Show dialog
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(GuiDownloadService service, Callback<Boolean> callback) {
|
||||
new GuiDownloader(service, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyToClipboard(String text) {
|
||||
Forge.getClipboard().setContents(text);
|
||||
|
||||
@@ -1,29 +1,19 @@
|
||||
package forge.assets;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.badlogic.gdx.Application.ApplicationType;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Forge;
|
||||
import forge.download.GuiDownloadZipService;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.screens.SplashScreen;
|
||||
import forge.toolbox.FProgressBar;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
@@ -52,9 +42,10 @@ public class AssetsDownloader {
|
||||
message += " If so, you may want to connect to wifi first. The download is around 6.5MB.";
|
||||
}
|
||||
if (SOptionPane.showConfirmDialog(message, "New Version Available", "Update Now", "Update Later")) {
|
||||
String apkFile = downloadFile("update", "forge-android-" + version + "-signed-aligned.apk",
|
||||
"http://cardforge.org/android/releases/forge/forge-gui-android/" + version + "/",
|
||||
Forge.getDeviceAdapter().getDownloadsDir(), splashScreen.getProgressBar());
|
||||
String filename = "forge-android-" + version + "-signed-aligned.apk";
|
||||
String apkFile = new GuiDownloadZipService("", "update",
|
||||
"http://cardforge.org/android/releases/forge/forge-gui-android/" + version + "/" + filename,
|
||||
Forge.getDeviceAdapter().getDownloadsDir(), null, splashScreen.getProgressBar()).download(filename);
|
||||
if (apkFile != null) {
|
||||
Forge.getDeviceAdapter().openFile(apkFile);
|
||||
Forge.exit(true);
|
||||
@@ -136,7 +127,9 @@ public class AssetsDownloader {
|
||||
return;
|
||||
}
|
||||
|
||||
downloadAssets(splashScreen.getProgressBar());
|
||||
new GuiDownloadZipService("", "resource files",
|
||||
"http://cardforge.org/android/releases/forge/forge-gui-android/" + Forge.CURRENT_VERSION + "/" + "assets.zip",
|
||||
ForgeConstants.ASSETS_DIR, ForgeConstants.RES_DIR, splashScreen.getProgressBar()).downloadAndUnzip();
|
||||
|
||||
FSkinFont.deleteCachedFiles(); //delete cached font files in case any skin's .ttf file changed
|
||||
|
||||
@@ -153,103 +146,4 @@ public class AssetsDownloader {
|
||||
//so they don't need to be re-downloaded until you upgrade again
|
||||
FileUtil.writeFile(versionFile, Forge.CURRENT_VERSION);
|
||||
}
|
||||
|
||||
private static String downloadFile(final String desc, final String filename, final String sourceFolder, final String destFolder, final FProgressBar progressBar) {
|
||||
progressBar.reset();
|
||||
progressBar.setPercentMode(true);
|
||||
progressBar.setDescription("Downloading " + desc);
|
||||
|
||||
try {
|
||||
URL url = new URL(sourceFolder + filename);
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.connect();
|
||||
|
||||
long contentLength = conn.getContentLength();
|
||||
progressBar.setMaximum(100);
|
||||
|
||||
// input stream to read file - with 8k buffer
|
||||
InputStream input = new BufferedInputStream(url.openStream(), 8192);
|
||||
|
||||
// output stream to write file
|
||||
String destFile = destFolder + filename;
|
||||
OutputStream output = new FileOutputStream(destFile);
|
||||
|
||||
int count;
|
||||
long total = 0;
|
||||
byte data[] = new byte[1024];
|
||||
|
||||
while ((count = input.read(data)) != -1) {
|
||||
total += count;
|
||||
progressBar.setValue((int)(100 * total / contentLength));
|
||||
output.write(data, 0, count);
|
||||
}
|
||||
|
||||
output.flush();
|
||||
output.close();
|
||||
input.close();
|
||||
return destFile;
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
Log.error("Downloading " + desc, "Error downloading " + desc, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void downloadAssets(final FProgressBar progressBar) {
|
||||
String assetsFile = downloadFile("resource files", "assets.zip",
|
||||
"http://cardforge.org/android/releases/forge/forge-gui-android/" + Forge.CURRENT_VERSION + "/",
|
||||
ForgeConstants.ASSETS_DIR, progressBar);
|
||||
if (assetsFile == null) { return; }
|
||||
|
||||
//if assets.zip downloaded successfully, unzip into destination folder
|
||||
try {
|
||||
File resDir = new File(ForgeConstants.RES_DIR);
|
||||
if (resDir.exists()) {
|
||||
//attempt to delete previous res directory if to be rebuilt
|
||||
progressBar.reset();
|
||||
progressBar.setDescription("Deleting old resource files...");
|
||||
FileUtil.deleteDirectory(resDir);
|
||||
}
|
||||
|
||||
ZipFile zipFile = new ZipFile(assetsFile);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
|
||||
progressBar.reset();
|
||||
progressBar.setPercentMode(true);
|
||||
progressBar.setDescription("Unzipping resource files");
|
||||
progressBar.setMaximum(zipFile.size());
|
||||
|
||||
int count = 0;
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry)entries.nextElement();
|
||||
|
||||
String path = ForgeConstants.ASSETS_DIR + entry.getName();
|
||||
if (entry.isDirectory()) {
|
||||
new File(path).mkdir();
|
||||
progressBar.setValue(++count);
|
||||
continue;
|
||||
}
|
||||
copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(path)));
|
||||
progressBar.setValue(++count);
|
||||
}
|
||||
|
||||
zipFile.close();
|
||||
new File(assetsFile).delete();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void copyInputStream(InputStream in, OutputStream out) throws IOException{
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
|
||||
while((len = in.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public class FDeckChooser extends FScreen {
|
||||
private DeckType selectedDeckType;
|
||||
private boolean needRefreshOnActivate;
|
||||
private Callback<Deck> callback;
|
||||
private NetDeckCategory netDeckCategory;
|
||||
private boolean refreshingDeckType;
|
||||
|
||||
private final DeckManager lstDecks;
|
||||
private final FButton btnNewDeck = new FButton("New Deck");
|
||||
@@ -261,6 +263,12 @@ public class FDeckChooser extends FScreen {
|
||||
cmbDeckTypes.addItem(DeckType.COLOR_DECK);
|
||||
cmbDeckTypes.addItem(DeckType.THEME_DECK);
|
||||
cmbDeckTypes.addItem(DeckType.RANDOM_DECK);
|
||||
cmbDeckTypes.addItem(DeckType.NET_DECK);
|
||||
break;
|
||||
case Commander:
|
||||
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
|
||||
cmbDeckTypes.addItem(DeckType.RANDOM_DECK);
|
||||
cmbDeckTypes.addItem(DeckType.NET_DECK);
|
||||
break;
|
||||
default:
|
||||
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
|
||||
@@ -271,7 +279,32 @@ public class FDeckChooser extends FScreen {
|
||||
restoreSavedState();
|
||||
cmbDeckTypes.setChangedHandler(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
public void handleEvent(final FEvent e) {
|
||||
if (cmbDeckTypes.getSelectedItem() == DeckType.NET_DECK && !refreshingDeckType) {
|
||||
FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks
|
||||
@Override
|
||||
public void run() {
|
||||
final NetDeckCategory category = NetDeckCategory.selectAndLoad(lstDecks.getGameType());
|
||||
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (category == null) {
|
||||
cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels
|
||||
if (selectedDeckType == DeckType.NET_DECK && netDeckCategory != null) {
|
||||
cmbDeckTypes.setText(netDeckCategory.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
netDeckCategory = category;
|
||||
refreshDecksList(DeckType.NET_DECK, true, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
refreshDecksList(cmbDeckTypes.getSelectedItem(), false, e);
|
||||
}
|
||||
});
|
||||
@@ -493,6 +526,32 @@ public class FDeckChooser extends FScreen {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateNetDecks() {
|
||||
if (netDeckCategory != null) {
|
||||
cmbDeckTypes.setText(netDeckCategory.toString());
|
||||
}
|
||||
lstDecks.setSelectionSupport(1, 1);
|
||||
|
||||
lstDecks.setPool(DeckProxy.getNetDecks(netDeckCategory));
|
||||
lstDecks.setup(ItemManagerConfig.NET_DECKS);
|
||||
|
||||
btnNewDeck.setText("New Deck");
|
||||
btnNewDeck.setWidth(btnEditDeck.getWidth());
|
||||
btnEditDeck.setVisible(true);
|
||||
|
||||
btnViewDeck.setVisible(true);
|
||||
btnRandom.setText("Random Deck");
|
||||
btnRandom.setWidth(btnNewDeck.getWidth());
|
||||
btnRandom.setLeft(getWidth() - PADDING - btnRandom.getWidth());
|
||||
btnRandom.setCommand(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
DeckgenUtil.randomSelect(lstDecks);
|
||||
accept();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Deck getDeck() {
|
||||
DeckProxy proxy = lstDecks.getSelectedItem();
|
||||
if (proxy == null) { return null; }
|
||||
@@ -530,7 +589,9 @@ public class FDeckChooser extends FScreen {
|
||||
selectedDeckType = deckType;
|
||||
|
||||
if (e == null) {
|
||||
refreshingDeckType = true;
|
||||
cmbDeckTypes.setSelectedItem(deckType);
|
||||
refreshingDeckType = false;
|
||||
}
|
||||
if (deckType == null) { return; }
|
||||
|
||||
@@ -553,6 +614,9 @@ public class FDeckChooser extends FScreen {
|
||||
case RANDOM_DECK:
|
||||
updateRandom();
|
||||
break;
|
||||
case NET_DECK:
|
||||
updateNetDecks();
|
||||
break;
|
||||
}
|
||||
|
||||
if (e != null) { //set default list selection if from combo box change event
|
||||
@@ -577,8 +641,15 @@ public class FDeckChooser extends FScreen {
|
||||
}
|
||||
|
||||
private String getState() {
|
||||
String deckType = cmbDeckTypes.getSelectedItem().name();
|
||||
StringBuilder state = new StringBuilder(deckType);
|
||||
StringBuilder state = new StringBuilder();
|
||||
if (cmbDeckTypes.getSelectedItem() == null || cmbDeckTypes.getSelectedItem() == DeckType.NET_DECK) {
|
||||
//handle special case of net decks
|
||||
if (netDeckCategory == null) { return ""; }
|
||||
state.append(NetDeckCategory.PREFIX + netDeckCategory.getName());
|
||||
}
|
||||
else {
|
||||
state.append(cmbDeckTypes.getSelectedItem().name());
|
||||
}
|
||||
state.append(";");
|
||||
joinSelectedDecks(state, SELECTED_DECK_DELIMITER);
|
||||
return state.toString();
|
||||
@@ -600,25 +671,20 @@ public class FDeckChooser extends FScreen {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a clean name from the state that can be used for labels. */
|
||||
public final String getStateForLabel() {
|
||||
String deckType = cmbDeckTypes.getSelectedItem().toString();
|
||||
StringBuilder state = new StringBuilder(deckType);
|
||||
state.append(": ");
|
||||
joinSelectedDecks(state, ", ");
|
||||
return state.toString();
|
||||
}
|
||||
|
||||
private void restoreSavedState() {
|
||||
DeckType oldDeckType = selectedDeckType;
|
||||
if (stateSetting == null) {
|
||||
//if can't restore saved state, just refresh deck list
|
||||
refreshDecksList(selectedDeckType, true, null);
|
||||
refreshDecksList(oldDeckType, true, null);
|
||||
return;
|
||||
}
|
||||
|
||||
String savedState = prefs.getPref(stateSetting);
|
||||
refreshDecksList(getDeckTypeFromSavedState(savedState), true, null);
|
||||
lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState));
|
||||
if (!lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState))) {
|
||||
//if can't select old decks, just refresh deck list
|
||||
refreshDecksList(oldDeckType, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
private DeckType getDeckTypeFromSavedState(String savedState) {
|
||||
@@ -627,7 +693,12 @@ public class FDeckChooser extends FScreen {
|
||||
return selectedDeckType;
|
||||
}
|
||||
else {
|
||||
return DeckType.valueOf(savedState.split(";")[0]);
|
||||
String deckType = savedState.split(";")[0];
|
||||
if (deckType.startsWith(NetDeckCategory.PREFIX)) {
|
||||
netDeckCategory = NetDeckCategory.selectAndLoad(lstDecks.getGameType(), deckType.substring(NetDeckCategory.PREFIX.length()));
|
||||
return DeckType.NET_DECK;
|
||||
}
|
||||
return DeckType.valueOf(deckType);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
|
||||
@@ -24,9 +24,11 @@ import com.badlogic.gdx.Gdx;
|
||||
import forge.UiCommand;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.download.GuiDownloadService;
|
||||
import forge.download.GuiDownloadZipService;
|
||||
import forge.toolbox.*;
|
||||
import forge.toolbox.FEvent.FEventHandler;
|
||||
import forge.toolbox.FRadioButton.RadioButtonGroup;
|
||||
import forge.util.Callback;
|
||||
|
||||
public class GuiDownloader extends FDialog {
|
||||
public static final Proxy.Type[] TYPES = Proxy.Type.values();
|
||||
@@ -44,16 +46,25 @@ public class GuiDownloader extends FDialog {
|
||||
private final UiCommand cmdClose = new UiCommand() {
|
||||
@Override
|
||||
public void run() {
|
||||
Gdx.graphics.setContinuousRendering(false);
|
||||
service.setCancel(true);
|
||||
hide();
|
||||
if (callback != null) {
|
||||
callback.run(btnStart.getText() == "OK"); //determine result based on whether download finished
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final GuiDownloadService service;
|
||||
private final Callback<Boolean> callback;
|
||||
|
||||
public GuiDownloader(GuiDownloadService service0) {
|
||||
this(service0, null);
|
||||
}
|
||||
public GuiDownloader(GuiDownloadService service0, Callback<Boolean> callback0) {
|
||||
super(service0.getTitle());
|
||||
service = service0;
|
||||
callback = callback0;
|
||||
|
||||
txtAddress.setGhostText("Proxy Address");
|
||||
txtPort.setGhostText("Proxy Port");
|
||||
@@ -85,7 +96,9 @@ public class GuiDownloader extends FDialog {
|
||||
service.initialize(txtAddress, txtPort, progressBar, btnStart, cmdClose, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Gdx.graphics.setContinuousRendering(false);
|
||||
if (!(service instanceof GuiDownloadZipService)) { //retain continuous rendering for zip service
|
||||
Gdx.graphics.setContinuousRendering(false);
|
||||
}
|
||||
progressBar.setShowProgressTrail(false);
|
||||
}
|
||||
}, null);
|
||||
|
||||
@@ -174,10 +174,15 @@ public class FComboBox<T> extends FTextField implements IComboBox<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getRightPadding() {
|
||||
protected float getLeftPadding() {
|
||||
if (getAlignment() == HAlignment.CENTER) {
|
||||
return super.getRightPadding();
|
||||
return getRightPadding(); //match right padding if center aligned
|
||||
}
|
||||
return super.getLeftPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getRightPadding() {
|
||||
return getDivotWidth() + 2 * PADDING;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ public class FEvent {
|
||||
CHANGE,
|
||||
ACTIVATE,
|
||||
SAVE,
|
||||
DELETE
|
||||
DELETE,
|
||||
CLOSE
|
||||
}
|
||||
|
||||
private FDisplayObject source;
|
||||
|
||||
Reference in New Issue
Block a user