forked from External/mage
commit
45724e8bf9
7 changed files with 177 additions and 42 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
117
Mage.Client/src/main/java/mage/client/util/URLHandler.java
Normal file
117
Mage.Client/src/main/java/mage/client/util/URLHandler.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue