Blocker and Critical level bugfixes throughout the project (#4648)

* fixed https://sonarcloud.io/project/issues?id=org.xmage%3Amage-root&issues=AWIlv32RgrzAwlaaQ7rP&open=AWIlv32RgrzAwlaaQ7rP

* ensure closing of scanner if it was opened

* Refactored method in EmpyrialArchAngel to not always return same value.

* Refactored method in FalkenrathAristocrat to not always return same value.

* Refactored method in GilderBairn to not always return the same value.

* fixed left open resources, ensured quiet closing of the streams

* Refactored method in IceCave to not always return same value.

* Refactored method in KjeldoranRoyalGuard to not always return same value.

* Refactored method in LegionsInitiative to not always return same value.

* Refactored method in NaturesWill to not always return same value.

* added quiet closing method in new streamutils class, used to clean up the connectdialog

* Fix small typo

* added quiet closing to saveobjectutil

* closed resources in savegame method of gamecontroller

* properly close resources in loadGame method of GameReplay class

* further proper resource closing in ServerMessagesUtil

* fixed unclosed resources in copy method in mage framework Copier

* closed unclosed resources in copyCompressed method in Copier

* ensure closing of filewriter in manasymbols

* ensure proper closing of Stream in arcane UI

* ensure closing of datagram socket in arcane Util

* ensure resource closing in deckimport from clipboard

* ensure closing of plugin classloader

* ensured closing of zipinputstream resource

* ensure closing of fileoutputstream in ScryfallSymbolsSource

* ensure closing resources after finishing/canceling download of pictures

* remove commented code

* move locks to try block to ensure unlocking along all execution paths

* remove dangerous instance of double-checked locking

* removed dangerous instance of double checked locking in settingsmanager

* Removed dangerous instance of double-checked locking in ThemePluginImpl

* close resource which did not happen certainly

* close another stream

* ensure closing of inputstream
This commit is contained in:
ArcadeMode 2018-03-22 14:13:13 +01:00 committed by Jeff Wadsworth
parent ec77cecbf6
commit 5ac975c52e
31 changed files with 288 additions and 276 deletions

View file

@ -67,6 +67,10 @@ public class ManaPieChart extends JComponent {
for (int i = 0; i < slices.length; i++) {
total += slices[i].value;
}
if (total == 0.0D) {
return; //there are no slices or no slices with a value > 0, stop here
}
double curValue = 0.0D;
int startAngle = 0;

View file

@ -1,5 +1,7 @@
package mage.client.deckeditor;
import mage.util.StreamUtils;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
@ -39,15 +41,16 @@ public class DeckImportFromClipboardDialog extends JDialog {
}
private void onOK() {
BufferedWriter bw = null;
try {
File temp = File.createTempFile("cbimportdeck", ".txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
bw = new BufferedWriter(new FileWriter(temp));
bw.write(txtDeckList.getText());
bw.close();
tmpPath = temp.getPath();
} catch (IOException e) {
e.printStackTrace();
} finally {
StreamUtils.closeQuietly(bw);
}
dispose();

View file

@ -43,6 +43,7 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.Writer;
import java.io.Closeable;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketException;
@ -73,6 +74,7 @@ import mage.client.util.Config;
import mage.client.util.gui.countryBox.CountryItemEditor;
import mage.client.util.sets.ConstructedFormats;
import mage.remote.Connection;
import mage.utils.StreamUtils;
import org.apache.log4j.Logger;
/**
@ -565,6 +567,7 @@ public class ConnectDialog extends MageDialog {
private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
BufferedReader in = null;
Writer output = null;
try {
String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt");
if (serverUrl.contains("xmage.info/files/")) {
@ -618,7 +621,7 @@ public class ConnectDialog extends MageDialog {
}
List<String> servers = new ArrayList<>();
if (in != null) {
Writer output = null;
if (!URLNotFound) {
// write serverlist to be able to read if URL is not available
File file = new File("serverlist.txt");
@ -637,10 +640,6 @@ public class ConnectDialog extends MageDialog {
}
}
if (output != null) {
output.close();
}
in.close();
}
if (servers.isEmpty()) {
JOptionPane.showMessageDialog(null, "Couldn't find any server.");
@ -668,15 +667,12 @@ public class ConnectDialog extends MageDialog {
} catch (Exception ex) {
logger.error(ex, ex);
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
StreamUtils.closeQuietly(in);
StreamUtils.closeQuietly(output);
}
}//GEN-LAST:event_jButton1ActionPerformed
private void jProxySettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jProxySettingsButtonActionPerformed
PreferencesDialog.main(new String[]{PreferencesDialog.OPEN_CONNECTION_TAB});
}//GEN-LAST:event_jProxySettingsButtonActionPerformed

View file

@ -45,16 +45,12 @@ public class ArrowBuilder {
* Get the panel where all arrows are being drawn.
* @return
*/
public JPanel getArrowsManagerPanel() {
public synchronized JPanel getArrowsManagerPanel() {
if (arrowsManagerPanel == null) {
synchronized (ArrowBuilder.class) {
if (arrowsManagerPanel == null) {
arrowsManagerPanel = new JPanel();
arrowsManagerPanel.setVisible(true);
arrowsManagerPanel.setOpaque(false);
arrowsManagerPanel.setLayout(null);
}
}
arrowsManagerPanel = new JPanel();
arrowsManagerPanel.setVisible(true);
arrowsManagerPanel.setOpaque(false);
arrowsManagerPanel.setLayout(null);
}
return arrowsManagerPanel;
}

View file

@ -1,5 +1,7 @@
package mage.client.util.object;
import mage.utils.StreamUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@ -61,10 +63,9 @@ public final class SaveObjectUtil {
oos.writeObject(object);
oos.close();
} catch (FileNotFoundException e) {
return;
} catch (IOException io) {
return;
} catch (Exception e) {
} finally {
StreamUtils.closeQuietly(oos);
}
}
}

View file

@ -41,6 +41,7 @@ import mage.client.constants.Constants.ResourceSymbolSize;
import mage.client.util.GUISizeHelper;
import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
import mage.utils.StreamUtils;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
@ -249,10 +250,15 @@ public final class ManaSymbols {
+ "color-rendering: optimizeQuality;"
+ "image-rendering: optimizeQuality;"
+ "}";
File cssFile = File.createTempFile("batik-default-override-", ".css");
FileWriter w = new FileWriter(cssFile);
w.write(css);
w.close();
FileWriter w = null;
try {
w = new FileWriter(cssFile);
w.write(css);
} finally {
StreamUtils.closeQuietly(w);
}
TranscodingHints transcoderHints = new TranscodingHints();
@ -284,7 +290,6 @@ public final class ManaSymbols {
try {
TranscoderInput input = new TranscoderInput(new FileInputStream(svgFile));
ImageTranscoder t = new ImageTranscoder() {
@Override

View file

@ -1,5 +1,7 @@
package org.mage.card.arcane;
import mage.utils.StreamUtils;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
@ -72,8 +74,8 @@ public final class UI {
}
public static ImageIcon getImageIcon (String path) {
InputStream stream = null;
try {
InputStream stream;
stream = UI.class.getResourceAsStream(path);
if (stream == null && new File(path).exists()) {
stream = new FileInputStream(path);
@ -86,6 +88,8 @@ public final class UI {
return new ImageIcon(data);
} catch (IOException ex) {
throw new RuntimeException("Error reading image: " + path);
} finally {
StreamUtils.closeQuietly(stream);
}
}

View file

@ -37,9 +37,13 @@ public final class Util {
}
public static void broadcast(byte[] data, int port) throws IOException {
DatagramSocket socket = new DatagramSocket();
broadcast(socket, data, port, NetworkInterface.getNetworkInterfaces());
socket.close();
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
broadcast(socket, data, port, NetworkInterface.getNetworkInterfaces());
} finally {
socket.close();
}
}
private static void broadcast(DatagramSocket socket, byte[] data, int port, Enumeration<NetworkInterface> ifaces)

View file

@ -9,6 +9,7 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mage.util.StreamUtils;
import org.mage.plugins.card.dl.DownloadJob;
import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG;
@ -106,20 +107,21 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
if (destFile.exists() && (destFile.length() > 0)){
continue;
}
FileOutputStream stream = null;
try {
// base64 transform
String data64 = foundedData.get(searchCode);
Base64.Decoder dec = Base64.getDecoder();
byte[] fileData = dec.decode(data64);
FileOutputStream stream = new FileOutputStream(destFile);
stream = new FileOutputStream(destFile);
stream.write(fileData);
stream.close();
LOGGER.info("New svg symbol downloaded: " + needCode);
} catch (Exception e) {
LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage());
} finally {
StreamUtils.closeQuietly(stream);
}
}
}

View file

@ -24,6 +24,7 @@ import mage.client.MageFrame;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.sets.ConstructedFormats;
import mage.remote.Connection;
import mage.util.StreamUtils;
import net.java.truevfs.access.TFile;
import net.java.truevfs.access.TFileOutputStream;
import net.java.truevfs.access.TVFS;
@ -745,34 +746,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
}
}
/*
if(!destFile.getParentFile().exists()){
destFile.getParentFile().mkdirs();
}
*/
/*
// WTF start?! TODO: wtf
File existingFile = new File(imagePath.replaceFirst("\\w{3}.zip", ""));
if (existingFile.exists()) {
try {
new TFile(existingFile).cp_rp(outputFile);
} catch (IOException e) {
logger.error("Error while copying file " + card.getName(), e);
}
synchronized (sync) {
update(cardIndex + 1, count);
}
existingFile.delete();
File parent = existingFile.getParentFile();
if (parent != null && parent.isDirectory() && parent.list().length == 0) {
parent.delete();
}
return;
}
// WTF end?!
*/
// START to download
cardImageSource.doPause(url.getPath());
URLConnection httpConn = url.openConnection(p);
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
@ -782,18 +755,18 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
if (responseCode == 200) {
// download OK
// save data to temp
BufferedOutputStream out;
try (BufferedInputStream in = new BufferedInputStream(httpConn.getInputStream())) {
out = new BufferedOutputStream(new TFileOutputStream(fileTempImage));
OutputStream out = null;
OutputStream tfileout = null;
InputStream in = null;
try {
in = new BufferedInputStream(httpConn.getInputStream());
tfileout = new TFileOutputStream(fileTempImage);
out = new BufferedOutputStream(tfileout);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
// user cancelled
if (cancel) {
in.close();
out.flush();
out.close();
// stop download, save current state and exit
TFile archive = destFile.getTopLevelArchive();
///* not need to unmout/close - it's auto action
@ -804,8 +777,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} catch (Exception e) {
logger.error("Can't close archive file: " + e.getMessage(), e);
}
}//*/
}
try {
TFile.rm(fileTempImage);
} catch (Exception e) {
@ -816,9 +788,12 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
out.write(buf, 0, len);
}
}
// TODO: remove to finnaly section?
out.flush();
out.close();
finally {
StreamUtils.closeQuietly(in);
StreamUtils.closeQuietly(out);
StreamUtils.closeQuietly(tfileout);
}
// TODO: add two faces card correction? (WTF)
// SAVE final data
@ -847,81 +822,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
}
}
/*
// Logger.getLogger(this.getClass()).info(url.toString());
boolean useTempFile = false;
int responseCode = 0;
URLConnection httpConn = null;
if (temporaryFile != null && temporaryFile.length() > 100) {
useTempFile = true;
} else {
cardImageSource.doPause(url.getPath());
httpConn = url.openConnection(p);
httpConn.connect();
responseCode = ((HttpURLConnection) httpConn).getResponseCode();
}
if (responseCode == 200 || useTempFile) {
if (!useTempFile) {
BufferedOutputStream out;
try (BufferedInputStream in = new BufferedInputStream(httpConn.getInputStream())) {
//try (BufferedInputStream in = new BufferedInputStream(url.openConnection(p).getInputStream())) {
out = new BufferedOutputStream(new TFileOutputStream(temporaryFile));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
// user cancelled
if (cancel) {
in.close();
out.flush();
out.close();
temporaryFile.delete();
return;
}
out.write(buf, 0, len);
}
}
out.flush();
out.close();
}
// TODO: WTF?! start
if (card != null && card.isTwoFacedCard()) {
BufferedImage image = ImageIO.read(temporaryFile);
if (image.getHeight() == 470) {
BufferedImage renderedImage = new BufferedImage(265, 370, BufferedImage.TYPE_INT_RGB);
renderedImage.getGraphics();
Graphics2D graphics2D = renderedImage.createGraphics();
if (card.isTwoFacedCard() && card.isSecondSide()) {
graphics2D.drawImage(image, 0, 0, 265, 370, 313, 62, 578, 432, null);
} else {
graphics2D.drawImage(image, 0, 0, 265, 370, 41, 62, 306, 432, null);
}
graphics2D.dispose();
writeImageToFile(renderedImage, outputFile);
} else {
outputFile.getParentFile().mkdirs();
new TFile(temporaryFile).cp_rp(outputFile);
}
//temporaryFile.delete();
} else {
outputFile.getParentFile().mkdirs();
new TFile(temporaryFile).cp_rp(outputFile);
}
// WTF?! end
} else {
if (card != null && !useSpecifiedPaths) {
logger.warn("Image download for " + card.getName()
+ (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "")
+ '(' + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString());
}
if (logger.isDebugEnabled()) { // Shows the returned html from the request to the web server
logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
}
}
*/
} catch (AccessDeniedException e) {
logger.error("Can't access to files: " + card.getName() + "(" + card.getSet() + "). Try rebooting your system to remove the file lock.");
} catch (Exception e) {
@ -933,26 +833,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
update(cardIndex + 1, count);
}
}
// private void writeImageToFile(BufferedImage image, TFile file) throws IOException {
// Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
//
// ImageWriter writer = (ImageWriter) iter.next();
// ImageWriteParam iwp = writer.getDefaultWriteParam();
// iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
// iwp.setCompressionQuality(0.96f);
//
// File tempFile = new File(getImagesDir() + File.separator + image.hashCode() + file.getName());
// FileImageOutputStream output = new FileImageOutputStream(tempFile);
// writer.setOutput(output);
// IIOImage image2 = new IIOImage(image, null, null);
// writer.write(null, image2, iwp);
// writer.dispose();
// output.close();
//
// new TFile(tempFile).cp_rp(file);
// tempFile.delete();
// }
}
private void update(int card, int count) {

View file

@ -12,13 +12,9 @@ public class SettingsManager {
private static SettingsManager settingsManager = null;
public static SettingsManager getIntance() {
public static synchronized SettingsManager getIntance() {
if (settingsManager == null) {
synchronized (SettingsManager.class) {
if (settingsManager == null) {
settingsManager = new SettingsManager();
}
}
settingsManager = new SettingsManager();
}
return settingsManager;
}

View file

@ -150,47 +150,43 @@ public class ThemePluginImpl implements ThemePlugin {
return bgPanel;
}
private ImagePanel createImagePanelInstance() {
private synchronized ImagePanel createImagePanelInstance() {
if (background == null) {
synchronized (ThemePluginImpl.class) {
if (background == null) {
String filename = "/background.png";
try {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
} else {
String path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE, "");
if (path != null && !path.isEmpty()) {
try {
File f = new File(path);
if (f != null) {
background = ImageIO.read(f);
}
} catch (Exception e) {
background = null;
}
}
}
if (background == null) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
}
if (background == null) {
String filename = "/background.png";
try {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
background = ImageIO.read(is);
} else {
String path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE, "");
if (path != null && !path.isEmpty()) {
try {
File f = new File(path);
if (f != null) {
background = ImageIO.read(f);
}
} catch (Exception e) {
background = null;
}
}
}
if (background == null) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
}
if (background == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
}
return new ImagePanel(background, ImagePanelStyle.SCALED);
}

View file

@ -0,0 +1,30 @@
package mage.utils;
import java.io.Closeable;
public final class StreamUtils {
/***
* Quietly closes the closable, ignoring nulls and exceptions
* @param c - the closable to be closed
*/
public static void closeQuietly(Closeable c) {
if (c != null) {
try {
c.close();
}
catch (Exception e) {
}
}
}
public static void closeQuietly(AutoCloseable ac) {
if (ac != null) {
try {
ac.close();
}
catch (Exception e) {
}
}
}
}

View file

@ -957,10 +957,11 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
}
protected final void getSuggestedActions() {
Scanner scanner = null;
try {
File file = new File(FILE_WITH_INSTRUCTIONS);
if (file.exists()) {
Scanner scanner = new Scanner(file);
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("cast:")
@ -976,6 +977,10 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
} catch (Exception e) {
// swallow
e.printStackTrace();
} finally {
if(scanner != null) {
scanner.close();
}
}
}

View file

@ -90,8 +90,8 @@ public class ChatSession {
String userName = clients.get(userId);
if (reason != DisconnectReason.LostConnection) { // for lost connection the user will be reconnected or session expire so no removeUserFromAllTablesAndChat of chat yet
final Lock w = lock.writeLock();
w.lock();
try {
w.lock();
clients.remove(userId);
} finally {
w.unlock();

View file

@ -29,6 +29,7 @@
package mage.server;
import mage.server.util.PluginClassLoader;
import mage.util.StreamUtils;
import java.io.File;
import java.io.IOException;
@ -54,10 +55,12 @@ public final class ExtensionPackageLoader {
String entryPoint = entryPointReader.nextLine().trim();
entryPointReader.close();
PluginClassLoader classLoader = new PluginClassLoader();
for(File f : packagesDirectory.listFiles()) classLoader.addURL(f.toURI().toURL());
PluginClassLoader classLoader = null;
try {
classLoader = new PluginClassLoader();
for(File f : packagesDirectory.listFiles()) {
classLoader.addURL(f.toURI().toURL());
}
return (ExtensionPackage) Class.forName(entryPoint, false, classLoader).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
@ -65,6 +68,8 @@ public final class ExtensionPackageLoader {
throw new RuntimeException("Entry point class not found!", e);
} catch (ClassCastException e) {
throw new RuntimeException("Entry point not an instance of ExtensionPackage.", e);
} finally {
StreamUtils.closeQuietly(classLoader);
}
}
}

View file

@ -231,8 +231,8 @@ public enum UserManager {
}
logger.debug("Users to remove " + toRemove.size());
final Lock w = lock.readLock();
w.lock();
try {
w.lock();
for (User user : toRemove) {
users.remove(user.getId());
}

View file

@ -64,6 +64,7 @@ import mage.server.util.ConfigSettings;
import mage.server.util.Splitter;
import mage.server.util.SystemUtil;
import mage.server.util.ThreadExecutor;
import mage.utils.StreamUtils;
import mage.utils.timer.PriorityTimer;
import mage.view.*;
import mage.view.ChatMessage.MessageColor;
@ -902,17 +903,23 @@ public class GameController implements GameCallback {
}
public boolean saveGame() {
OutputStream file = null;
ObjectOutput output = null;
OutputStream buffer = null;
try {
OutputStream file = new FileOutputStream("saved/" + game.getId().toString() + ".game");
OutputStream buffer = new BufferedOutputStream(file);
try (ObjectOutput output = new ObjectOutputStream(new GZIPOutputStream(buffer))) {
output.writeObject(game);
output.writeObject(game.getGameStates());
}
file = new FileOutputStream("saved/" + game.getId().toString() + ".game");
buffer = new BufferedOutputStream(file);
output = new ObjectOutputStream(new GZIPOutputStream(buffer));
output.writeObject(game);
output.writeObject(game.getGameStates());
logger.debug("Saved game:" + game.getId());
return true;
} catch (IOException ex) {
logger.fatal("Cannot save game.", ex);
} finally {
StreamUtils.closeQuietly(file);
StreamUtils.closeQuietly(output);
StreamUtils.closeQuietly(buffer);
}
return false;
}

View file

@ -40,6 +40,7 @@ import mage.game.GameState;
import mage.game.GameStates;
import mage.server.Main;
import mage.util.CopierObjectInputStream;
import mage.utils.StreamUtils;
import org.apache.log4j.Logger;
@ -84,21 +85,31 @@ public class GameReplay {
}
private Game loadGame(UUID gameId) {
InputStream file = null;
InputStream buffer = null;
InputStream gzip = null;
ObjectInput input = null;
try{
InputStream file = new FileInputStream("saved/" + gameId.toString() + ".game");
InputStream buffer = new BufferedInputStream(file);
try (ObjectInput input = new CopierObjectInputStream(Main.classLoader, new GZIPInputStream(buffer))) {
Game loadGame = (Game) input.readObject();
GameStates states = (GameStates) input.readObject();
loadGame.loadGameStates(states);
return loadGame;
}
file = new FileInputStream("saved/" + gameId.toString() + ".game");
buffer = new BufferedInputStream(file);
gzip = new GZIPInputStream(buffer);
input = new CopierObjectInputStream(Main.classLoader, gzip);
Game loadGame = (Game) input.readObject();
GameStates states = (GameStates) input.readObject();
loadGame.loadGameStates(states);
return loadGame;
}
catch(ClassNotFoundException ex) {
logger.fatal("Cannot load game. Class not found.", ex);
}
catch(IOException ex) {
logger.fatal("Cannot load game:" + gameId, ex);
} finally {
StreamUtils.closeQuietly(file);
StreamUtils.closeQuietly(buffer);
StreamUtils.closeQuietly(input);
StreamUtils.closeQuietly(gzip);
}
return null;
}

View file

@ -27,6 +27,7 @@
*/
package mage.server.util;
import mage.utils.StreamUtils;
import org.apache.log4j.Logger;
import java.io.File;
@ -49,7 +50,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* @author nantuko
*/
public enum ServerMessagesUtil {
instance;
instance;
private static final Logger log = Logger.getLogger(ServerMessagesUtil.class);
private static final String SERVER_MSG_TXT_FILE = "server.msg.txt";
private ScheduledExecutorService updateExecutor;
@ -147,13 +148,22 @@ instance;
log.warn("Couldn't find server.msg");
return null;
}
Scanner scanner = new Scanner(is);
Scanner scanner = null;
List<String> newMessages = new ArrayList<>();
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (!message.trim().isEmpty()) {
newMessages.add(message.trim());
try {
scanner = new Scanner(is);
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (!message.trim().isEmpty()) {
newMessages.add(message.trim());
}
}
} catch(Exception e) {
log.error(e,e);
} finally {
StreamUtils.closeQuietly(scanner);
StreamUtils.closeQuietly(is);
}
return newMessages;
}

View file

@ -91,7 +91,6 @@ class EmpyrialArchangelEffect extends ReplacementEffectImpl {
Permanent p = game.getPermanent(source.getSourceId());
if (p != null) {
p.damage(damageEvent.getAmount(), event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable());
return true;
}
return true;
}

View file

@ -105,7 +105,7 @@ class FalkenrathAristocratEffect extends OneShotEffect {
Permanent sourceCreature = game.getPermanent(source.getSourceId());
if (sacrificedCreature.hasSubtype(SubType.HUMAN, game) && sourceCreature != null) {
sourceCreature.addCounters(CounterType.P1P1.createInstance(), source, game);
return true;
break;
}
}
}

View file

@ -95,12 +95,11 @@ class GilderBairnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(source.getFirstTarget());
if (target == null) {
return false;
}
for (Counter counter : target.getCounters(game).values()) {
Counter newCounter = new Counter(counter.getName(), counter.getCount());
target.addCounters(newCounter, source, game);
if (target != null) {
for (Counter counter : target.getCounters(game).values()) {
Counter newCounter = new Counter(counter.getName(), counter.getCount());
target.addCounters(newCounter, source, game);
}
}
return false;
}

View file

@ -102,7 +102,7 @@ class IceCaveEffect extends OneShotEffect {
if (cost.pay(source, game, source.getSourceId(), playerId, false, null)) {
game.informPlayers(player.getLogName() + " pays" + cost.getText() + " to counter " + spell.getIdName() + '.');
game.getStack().counter(spell.getId(), source.getSourceId(), game);
return true;
break;
}
}
}

View file

@ -99,7 +99,6 @@ class KjeldoranRoyalGuardEffect extends ReplacementEffectImpl {
Permanent p = game.getPermanent(source.getSourceId());
if (p != null) {
p.damage(damageEvent.getAmount(), event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable());
return true;
}
return true;
}

View file

@ -129,7 +129,6 @@ class LegionsInitiativeExileEffect extends OneShotEffect {
//create delayed triggered ability
AtTheBeginOfCombatDelayedTriggeredAbility delayedAbility = new AtTheBeginOfCombatDelayedTriggeredAbility(new LegionsInitiativeReturnFromExileEffect());
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
return true;
}

View file

@ -84,19 +84,16 @@ class NaturesWillEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> damagedPlayers = (HashSet<UUID>) this.getValue("damagedPlayers");
if (damagedPlayers == null) {
return false;
}
List<Permanent> lands = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source.getSourceId(), game);
for (Permanent land : lands) {
if (damagedPlayers.contains(land.getControllerId())) {
land.tap(game);
} else if (land.getControllerId().equals(source.getControllerId())) {
land.untap(game);
if (damagedPlayers != null) {
List<Permanent> lands = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source.getSourceId(), game);
for (Permanent land : lands) {
if (damagedPlayers.contains(land.getControllerId())) {
land.tap(game);
} else if (land.getControllerId().equals(source.getControllerId())) {
land.untap(game);
}
}
}
return false;
}
}

View file

@ -4,7 +4,7 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
import java.io.Closeable;
/**
* Helper for file operations.
*
@ -84,15 +84,17 @@ public final class FileHelper {
*/
public static void downloadFile(String filename, HttpURLConnection urlConnection) {
System.out.println("Downloading " + filename);
InputStream in = null;
FileOutputStream out = null;
try {
InputStream in = urlConnection.getInputStream();
in = urlConnection.getInputStream();
File f = new File(filename);
if (!f.exists() && f.getParentFile() != null) {
f.getParentFile().mkdirs();
System.out.println("Directories have been created: " + f.getParentFile().getPath());
}
FileOutputStream out = new FileOutputStream(filename);
out = new FileOutputStream(filename);
byte[] buf = new byte[4 * 1024];
int bytesRead;
@ -103,6 +105,19 @@ public final class FileHelper {
System.out.println("File has been updated: " + filename);
} catch (IOException e) {
System.out.println("i/o exception - " + e.getMessage());
} finally {
closeQuietly(in);
closeQuietly(out);
}
}
public static void closeQuietly(Closeable s) {
if(s != null) {
try {
s.close();
} catch (Exception e) {
System.out.println("i/o exception - " + e.getMessage());
}
}
}
}

View file

@ -2,6 +2,7 @@ package mage.verify;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import mage.util.StreamUtils;
import java.io.File;
import java.io.FileInputStream;
@ -94,9 +95,16 @@ public final class MtgJson {
}
stream = new FileInputStream(file);
}
ZipInputStream zipInputStream = new ZipInputStream(stream);
zipInputStream.getNextEntry();
return new ObjectMapper().readValue(zipInputStream, ref);
ZipInputStream zipInputStream = null;
try {
zipInputStream = new ZipInputStream(stream);
zipInputStream.getNextEntry();
return new ObjectMapper().readValue(zipInputStream, ref);
} finally {
StreamUtils.closeQuietly(zipInputStream);
StreamUtils.closeQuietly(stream);
}
}
public static Map<String, JsonSet> sets() {

View file

@ -50,36 +50,44 @@ public class Copier<T> {
public T copy(T obj) {
T copy = null;
FastByteArrayOutputStream fbos = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
try {
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
ObjectOutputStream out= new ObjectOutputStream(fbos);
fbos = new FastByteArrayOutputStream();
out = new ObjectOutputStream(fbos);
// Write the object out to a byte array
out.writeObject(obj);
out.flush();
out.close();
// Retrieve an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new CopierObjectInputStream(loader, fbos.getInputStream());
in = new CopierObjectInputStream(loader, fbos.getInputStream());
copy = (T) in.readObject();
}
catch(IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
StreamUtils.closeQuietly(fbos);
StreamUtils.closeQuietly(out);
StreamUtils.closeQuietly(in);
}
return copy;
}
public byte[] copyCompressed(T obj) {
FastByteArrayOutputStream fbos = null;
ObjectOutputStream out = null;
try {
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
ObjectOutputStream out= new ObjectOutputStream(new GZIPOutputStream(fbos));
fbos = new FastByteArrayOutputStream();
out = new ObjectOutputStream(new GZIPOutputStream(fbos));
// Write the object out to a byte array
out.writeObject(obj);
out.flush();
out.close();
byte[] copy = new byte[fbos.getSize()];
System.arraycopy(fbos.getByteArray(), 0, copy, 0, fbos.getSize());
@ -87,6 +95,9 @@ public class Copier<T> {
}
catch(IOException e) {
e.printStackTrace();
} finally {
StreamUtils.closeQuietly(fbos);
StreamUtils.closeQuietly(out);
}
return null;
}

View file

@ -0,0 +1,30 @@
package mage.util;
import java.io.Closeable;
public final class StreamUtils {
/***
* Quietly closes the closable, ignoring nulls and exceptions
* @param c - the closable to be closed
*/
public static void closeQuietly(Closeable c) {
if (c != null) {
try {
c.close();
}
catch (Exception e) {
}
}
}
public static void closeQuietly(AutoCloseable ac) {
if (ac != null) {
try {
ac.close();
}
catch (Exception e) {
}
}
}
}