Merge pull request #5 from magefree/master

Merge upstream into master
This commit is contained in:
chrvanorle 2018-03-29 15:52:07 +02:00 committed by GitHub
commit 45724e8bf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 177 additions and 42 deletions

View file

@ -104,6 +104,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final String LITE_MODE_ARG = "-lite";
private static final String GRAY_MODE_ARG = "-gray";
private static final String FILL_SCREEN_ARG = "-fullscreen";
private static final String SKIP_DONE_SYMBOLS = "-skipDoneSymbols";
private static final String NOT_CONNECTED_TEXT = "<not connected>";
private static MageFrame instance;
@ -121,6 +122,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
//TODO: make gray theme, implement theme selector in preferences dialog
private static boolean grayMode = false;
private static boolean fullscreenMode = false;
private static boolean skipSmallSymbolGenerationForExisting = false;
private static final Map<UUID, ChatPanelBasic> CHATS = new HashMap<>();
private static final Map<UUID, GamePanel> GAMES = new HashMap<>();
@ -152,6 +154,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
public static boolean isGray() {
return grayMode;
}
public static boolean isSkipSmallSymbolGenerationForExisting() {
return skipSmallSymbolGenerationForExisting;
}
@Override
public MageVersion getVersion() {
@ -1191,6 +1197,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (arg.startsWith(FILL_SCREEN_ARG)) {
fullscreenMode = true;
}
if (arg.startsWith(SKIP_DONE_SYMBOLS)) {
skipSmallSymbolGenerationForExisting = true;
}
}
if (!liteMode) {
final SplashScreen splash = SplashScreen.getSplashScreen();

View file

@ -60,6 +60,7 @@ import mage.client.util.ButtonColumn;
import mage.client.util.GUISizeHelper;
import mage.client.util.IgnoreList;
import mage.client.util.MageTableRowSorter;
import mage.client.util.URLHandler;
import mage.client.util.gui.GuiDisplayUtil;
import mage.client.util.gui.TableUtil;
import mage.constants.*;
@ -579,7 +580,7 @@ public class TablesPanel extends javax.swing.JPanel {
this.jPanelBottom.setVisible(false);
} else {
this.jPanelBottom.setVisible(true);
this.jLabelFooterText.setText(serverMessages.get(0));
URLHandler.handleMessage(serverMessages.get(0), this.jLabelFooterText);
this.jButtonFooterNext.setVisible(serverMessages.size() > 1);
}
}
@ -1283,7 +1284,9 @@ public class TablesPanel extends javax.swing.JPanel {
if (currentMessage >= messages.size()) {
currentMessage = 0;
}
this.jLabelFooterText.setText(messages.get(currentMessage));
URLHandler.RemoveMouseAdapter(jLabelFooterText);
URLHandler.handleMessage(messages.get(currentMessage), this.jLabelFooterText);
}
}
}//GEN-LAST:event_jButtonFooterNextActionPerformed

View file

@ -0,0 +1,117 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.util;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JLabel;
/**
*
* @author Dahny
*/
public class URLHandler {
private static MouseAdapter currentMouseAdapter;
/**
* This method makes a URL in a message click-able and converts the message
* into HTML.
*
* @param message: The selected message
* @param label: The message of the day label
*/
public static void handleMessage(String message, JLabel label) {
String url = detectURL(message);
if (!url.equals("")) {
label.addMouseListener(createMouseAdapter(url));
}
label.setText(convertToHTML(message));
}
public static void RemoveMouseAdapter(JLabel label) {
label.removeMouseListener(currentMouseAdapter);
currentMouseAdapter = null;
}
private static MouseAdapter createMouseAdapter(String url) {
currentMouseAdapter = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 0) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
try {
URI uri = new URI(url);
desktop.browse(uri);
} catch (IOException | URISyntaxException ex) {
// do nothing
}
}
}
}
};
return currentMouseAdapter;
}
public static String convertToHTML(String input) {
String s = input;
String output = "<html>";
// separate the input by spaces
String[] parts = s.split("\\s+");
for (String item : parts) {
try {
URL url = new URL(item);
// The item is already a valid URL
output = output + "<a href=\"" + url + "\">" + url + "</a> ";
} catch (MalformedURLException e) {
//The item might still be a URL
if (item.startsWith("www.")) {
output = output + "<a href=\"" + item + "\">" + item + "</a> ";
} else {
output = output + item + " ";
}
}
}
output = output + "</html>";
return output;
}
public static String detectURL(String input) {
String s = input;
String output = "";
// separate the input by spaces
String[] parts = s.split("\\s+");
for (String item : parts) {
try {
URL url = new URL(item);
// The item is already a valid URL
output = url.toString();
} catch (MalformedURLException e) {
//The item might still be a URL
if (item.startsWith("www.")) {
output = "http://" + item;
}
}
}
return output;
}
}

View file

@ -31,10 +31,14 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import javax.swing.*;
import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame;
import mage.client.constants.Constants;
import mage.client.constants.Constants.ResourceSetSize;
import mage.client.constants.Constants.ResourceSymbolSize;
@ -57,7 +61,7 @@ public final class ManaSymbols {
private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class);
private static final Map<Integer, Map<String, BufferedImage>> manaImages = new HashMap<>();
private static final Map<String, Map<String, Image>> setImages = new HashMap<>();
private static final Map<String, Map<String, Image>> setImages = new ConcurrentHashMap<>();
private static final HashSet<String> onlyMythics = new HashSet<>();
private static final HashSet<String> withoutSymbols = new HashSet<>();
@ -77,7 +81,7 @@ public final class ManaSymbols {
}
private static final Map<String, Dimension> setImagesExist = new HashMap<>();
private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
private static String cachedPath;
private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9",
"B", "BG", "BR", "BP", "2B",
"G", "GU", "GW", "GP", "2G",
@ -167,37 +171,39 @@ public final class ManaSymbols {
} catch (Exception e) {
}
}
// generate small size
try {
File file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM));
if (!file.exists()) {
file.mkdirs();
}
String pathRoot = getResourceSetsPath(ResourceSetSize.SMALL) + set;
for (String code : codes) {
file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM) + set + '-' + code + ".png");
if (file.exists()) {
continue;
}
file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM) + set + '-' + code + ".jpg");
Image image = UI.getImageIcon(file.getAbsolutePath()).getImage();
try {
int width = image.getWidth(null);
int height = image.getHeight(null);
if (height > 0) {
int dx = 0;
if (set.equals("M10") || set.equals("M11") || set.equals("M12")) {
dx = 6;
}
Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width));
BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
File newFile = new File(getResourceSetsPath(ResourceSetSize.SMALL) + set + '-' + code + ".png");
ImageIO.write(resized, "png", newFile);
}
} catch (Exception e) {
File newFile = new File(pathRoot + '-' + code + ".png");
if(!(MageFrame.isSkipSmallSymbolGenerationForExisting() && newFile.exists())){// skip if option enabled and file already exists
file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM) + set + '-' + code + ".png");
if (file.exists()) {
file.delete();
continue;
}
file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM) + set + '-' + code + ".jpg");
Image image = UI.getImageIcon(file.getAbsolutePath()).getImage();
try {
int width = image.getWidth(null);
int height = image.getHeight(null);
if (height > 0) {
int dx = 0;
if (set.equals("M10") || set.equals("M11") || set.equals("M12")) {
dx = 6;
}
Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width));
BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
ImageIO.write(resized, "png", newFile);
}
} catch (Exception e) {
if (file.exists()) {
file.delete();
}
}
}
}
@ -205,7 +211,6 @@ public final class ManaSymbols {
} catch (Exception e) {
}
}
// mark loaded images
// TODO: delete that code, images draw-show must dynamicly
File file;
@ -226,7 +231,6 @@ public final class ManaSymbols {
}
public static BufferedImage loadSVG(File svgFile, int resizeToWidth, int resizeToHeight, boolean useShadow) throws IOException {
// debug: disable shadow gen, need to test it
useShadow = false;
@ -424,17 +428,17 @@ public final class ManaSymbols {
}
private static boolean loadSymbolImages(int size) {
// load all symbols to cash
// load all symbols to cache
// priority: SVG -> GIF
// gif remain for backward compatibility
boolean fileErrors = false;
HashMap<String, BufferedImage> sizedSymbols = new HashMap<>();
for (String symbol : symbols) {
//boolean fileErrors = false;
AtomicBoolean fileErrors = new AtomicBoolean(false);
Map<String, BufferedImage> sizedSymbols = new ConcurrentHashMap<>();
IntStream.range(0, symbols.length).parallel().forEach(i-> {
String symbol = symbols[i];
BufferedImage image = null;
File file = null;
File file;
// svg
file = getSymbolFileNameAsSVG(symbol);
@ -456,13 +460,13 @@ public final class ManaSymbols {
if (image != null) {
sizedSymbols.put(symbol, image);
} else {
fileErrors = true;
fileErrors.set(true);
LOGGER.warn("SVG or GIF symbol can't be load: " + symbol);
}
}
});
manaImages.put(size, sizedSymbols);
return !fileErrors;
return !fileErrors.get();
}
private static void renameSymbols(String path) {

View file

@ -1,5 +1,7 @@
package org.mage.card.arcane;
import mage.util.StreamUtils;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
@ -42,7 +44,7 @@ public final class Util {
socket = new DatagramSocket();
broadcast(socket, data, port, NetworkInterface.getNetworkInterfaces());
} finally {
socket.close();
StreamUtils.closeQuietly(socket);
}
}

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

@ -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());
}