Assisted - 用户端 端消耗更多带宽和内存。
diff --git a/pom.xml b/pom.xml
index 3e3da40c..3fe1e4f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
https://github.com/retgal/dayon
mpo.dayon
dayon
- 14.0.2
+ 15.0.0
cross platform remote desktop solution
@@ -658,7 +658,7 @@
1.8.3
../dist/
- assisted.command
+ Assisted.command
./dayon_assisted.sh
@@ -718,7 +718,7 @@
1.8.3
../dist/
- assistant.command
+ Assistant.command
./dayon_assistant.sh
diff --git a/resources/dayon.sh b/resources/dayon.sh
index db18bccc..3edce22e 100755
--- a/resources/dayon.sh
+++ b/resources/dayon.sh
@@ -20,7 +20,7 @@ elif [ ! -f /etc/alternatives/java ]; then
else
JAVA=$(ls -l /etc/alternatives/java | awk -F'> ' '{print $2}')
fi
-JAVA_OPTS="-Xmx256M"
+JAVA_OPTS="-Xmx512M"
case "$@" in
*log=console*)
LOG=
diff --git a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java b/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java
index ce315205..4699f4ae 100644
--- a/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java
+++ b/src/main/java/mpo/dayon/assistant/decompressor/DeCompressorEngine.java
@@ -103,7 +103,7 @@ protected void execute() throws IOException {
cache = configuration.useCache() ? new RegularTileCache(configuration.getCacheMaxSize(), configuration.getCachePurgeSize())
: new NullTileCache();
- Log.info("De-Compressor engine has been reconfigured [tile:" + message.getId() + "] " + configuration);
+ Log.info("De-Compressor engine has been reconfigured [tile:" + message.getId() + "]" + configuration);
}
cache.clearHits();
diff --git a/src/main/java/mpo/dayon/assistant/gui/Assistant.java b/src/main/java/mpo/dayon/assistant/gui/Assistant.java
index 31efb4b0..a0d87f77 100644
--- a/src/main/java/mpo/dayon/assistant/gui/Assistant.java
+++ b/src/main/java/mpo/dayon/assistant/gui/Assistant.java
@@ -22,6 +22,7 @@
import mpo.dayon.common.squeeze.CompressionMethod;
import mpo.dayon.common.network.FileUtilities;
import mpo.dayon.common.utils.Language;
+import mpo.dayon.common.version.Version;
import javax.swing.*;
import java.awt.*;
@@ -46,10 +47,11 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
-import static java.lang.Math.abs;
+import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.lang.Math.*;
import static java.lang.String.format;
import static java.lang.String.valueOf;
-import static java.lang.Thread.sleep;
import static javax.swing.SwingConstants.HORIZONTAL;
import static mpo.dayon.common.babylon.Babylon.translate;
import static mpo.dayon.common.gui.common.ImageUtilities.getOrCreateIcon;
@@ -87,6 +89,8 @@ public class Assistant implements ClipboardOwner {
private final Object prevBufferLOCK = new Object();
+ private final Object upnpEnabledLOCK = new Object();
+
private byte[] prevBuffer = null;
private int prevWidth = -1;
@@ -169,18 +173,6 @@ private void createCounters() {
counters = new ArrayList<>(Arrays.asList(receivedBitCounter, receivedTileCounter, skippedTileCounter, mergedTileCounter, captureCompressionCounter));
}
- public boolean isUpnpEnabled() {
- while (upnpEnabled == null) {
- try {
- sleep(10L);
- } catch (InterruptedException e) {
- Log.warn("Swallowed", e);
- Thread.currentThread().interrupt();
- }
- }
- return upnpEnabled;
- }
-
public NetworkAssistantEngine getNetworkEngine() {
return networkEngine;
}
@@ -369,13 +361,13 @@ public void actionPerformed(ActionEvent ev) {
JFrame captureFrame = (JFrame) SwingUtilities.getRoot((Component) ev.getSource());
final JPanel pane = new JPanel();
- pane.setLayout(new GridLayout(2, 2, 10, 10));
+ pane.setLayout(new GridLayout(3, 2, 10, 10));
final JLabel tickLbl = new JLabel(translate("tick"));
tickLbl.setToolTipText(translate("tick.tooltip"));
final JSlider tickMillisSlider = new JSlider(HORIZONTAL, 50, 1000, captureEngineConfiguration.getCaptureTick());
final Properties tickLabelTable = new Properties(3);
- JLabel actualTick = new JLabel(format("%dms", tickMillisSlider.getValue()));
+ JLabel actualTick = new JLabel(format(" %dms ", tickMillisSlider.getValue()));
tickLabelTable.put(50, new JLabel(translate("min")));
tickLabelTable.put(550, actualTick);
tickLabelTable.put(1000, new JLabel(translate("max")));
@@ -389,43 +381,54 @@ public void actionPerformed(ActionEvent ev) {
final JLabel grayLevelsLbl = new JLabel(translate("grays"));
final JSlider grayLevelsSlider = new JSlider(HORIZONTAL, 0, 6, 6 - captureEngineConfiguration.getCaptureQuantization().ordinal());
final Properties grayLabelTable = new Properties(3);
- JLabel actualLevels = new JLabel(format("%d", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
- grayLabelTable.put(0, new JLabel(translate("min")));
- grayLabelTable.put(3, actualLevels);
+ JLabel actualLevels = new JLabel(format(" %d ", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
+ if (!networkConfiguration.isMonochromePeer()) {
+ grayLabelTable.put(0, new JLabel(translate("min")));
+ grayLabelTable.put(3, actualLevels);
+ } else {
+ grayLabelTable.put(3, new JLabel(translate("min")));
+ grayLevelsSlider.setMinimum(3);
+ }
grayLabelTable.put(6, new JLabel(translate("max")));
grayLevelsSlider.setLabelTable(grayLabelTable);
grayLevelsSlider.setMajorTickSpacing(1);
grayLevelsSlider.setPaintTicks(true);
grayLevelsSlider.setPaintLabels(true);
grayLevelsSlider.setSnapToTicks(true);
- pane.add(grayLevelsLbl);
- pane.add(grayLevelsSlider);
+ pane.add(grayLevelsLbl).setEnabled(!captureEngineConfiguration.isCaptureColors());
+ pane.add(grayLevelsSlider).setEnabled(!captureEngineConfiguration.isCaptureColors());
+
+ final JLabel colorsLbl = new JLabel(translate("colors"));
+ final JCheckBox colorsCb = new JCheckBox();
+ colorsCb.setSelected(captureEngineConfiguration.isCaptureColors());
+ pane.add(colorsLbl).setEnabled(!networkConfiguration.isMonochromePeer());
+ pane.add(colorsCb).setEnabled(!networkConfiguration.isMonochromePeer());
tickMillisSlider.addChangeListener(e -> {
actualTick.setText(tickMillisSlider.getValue() < 1000 ? format("%dms", tickMillisSlider.getValue()) : "1s");
if (!tickMillisSlider.getValueIsAdjusting()) {
sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(),
- toGrayLevel(grayLevelsSlider.getValue())));
+ toGrayLevel(grayLevelsSlider.getValue()), captureEngineConfiguration.isCaptureColors()));
}
});
grayLevelsSlider.addChangeListener(e -> {
actualLevels.setText(format("%d", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
- if (!grayLevelsSlider.getValueIsAdjusting()) {
+ if (!grayLevelsSlider.getValueIsAdjusting() && !captureEngineConfiguration.isCaptureColors()) {
sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(),
- toGrayLevel(grayLevelsSlider.getValue())));
+ toGrayLevel(grayLevelsSlider.getValue()), false));
}
});
+ colorsCb.addActionListener(e -> {
+ grayLevelsLbl.setEnabled(!colorsCb.isSelected());
+ grayLevelsSlider.setEnabled(!colorsCb.isSelected());
+ });
final boolean ok = DialogFactory.showOkCancel(captureFrame, translate("capture"), pane, true, null);
if (ok) {
final CaptureEngineConfiguration newCaptureEngineConfiguration = new CaptureEngineConfiguration(tickMillisSlider.getValue(),
- toGrayLevel(grayLevelsSlider.getValue()));
- if (!newCaptureEngineConfiguration.equals(captureEngineConfiguration)) {
- captureEngineConfiguration = newCaptureEngineConfiguration;
- captureEngineConfiguration.persist();
- sendCaptureConfiguration(captureEngineConfiguration);
- }
+ toGrayLevel(grayLevelsSlider.getValue()), colorsCb.isSelected());
+ updateCaptureConfiguration(newCaptureEngineConfiguration);
}
}
};
@@ -434,6 +437,14 @@ public void actionPerformed(ActionEvent ev) {
return configure;
}
+ private void updateCaptureConfiguration(CaptureEngineConfiguration newCaptureEngineConfiguration) {
+ if (!newCaptureEngineConfiguration.equals(captureEngineConfiguration)) {
+ captureEngineConfiguration = newCaptureEngineConfiguration;
+ captureEngineConfiguration.persist();
+ sendCaptureConfiguration(captureEngineConfiguration);
+ }
+ }
+
private Gray8Bits toGrayLevel(int value) {
switch (value) {
case 6:
@@ -742,12 +753,29 @@ protected void done() {
}
}
+ public boolean isUpnpEnabled() {
+ synchronized (upnpEnabledLOCK) {
+ while (upnpEnabled == null) {
+ try {
+ upnpEnabledLOCK.wait();
+ } catch (InterruptedException e) {
+ Log.warn("Swallowed", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ return upnpEnabled;
+ }
+ }
+
private void initUpnp() {
- CompletableFuture.supplyAsync(UPnP::isUPnPAvailable).thenApply(enabled -> {
- Log.info(format("UPnP is %s", enabled.booleanValue() ? "enabled" : "disabled"));
- upnpEnabled = enabled;
- return enabled;
- });
+ synchronized (upnpEnabledLOCK) {
+ CompletableFuture.supplyAsync(UPnP::isUPnPAvailable).thenApply(enabled -> {
+ Log.info(format("UPnP is %s", enabled.booleanValue() ? "enabled" : "disabled"));
+ upnpEnabled = enabled;
+ return enabled;
+ });
+ upnpEnabledLOCK.notifyAll();
+ }
}
private class MyDeCompressorEngineListener implements DeCompressorEngineListener {
@@ -788,7 +816,7 @@ private BufferedImage scaleImage(BufferedImage image, int width, int height) {
AffineTransform scaleTransform = AffineTransform.getScaleInstance(frame.getxFactor(), frame.getyFactor());
try {
AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR);
- return bilinearScaleOp.filter(image, new BufferedImage(abs(width), abs(height), image.getType()));
+ return bilinearScaleOp.filter(image, new BufferedImage(abs(width), abs(height), image.getType() == 0 ? TYPE_INT_ARGB_PRE : TYPE_BYTE_GRAY));
} catch (ImagingOpException e) {
Log.error(e.getMessage());
return image;
@@ -828,11 +856,20 @@ public boolean onAccepted(Socket connection) {
* Should not block as called from the network receiving thread (!)
*/
@Override
- public void onConnected(Socket connection, char osId, String inputLocale) {
+ public void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion) {
+ assureCompatibility(peerMajorVersion);
sendCaptureConfiguration(captureEngineConfiguration);
sendCompressorConfiguration(compressorEngineConfiguration);
frame.resetCanvas();
- frame.onSessionStarted(osId, inputLocale);
+ frame.onSessionStarted(osId, inputLocale, peerMajorVersion);
+ }
+
+ private void assureCompatibility(int peerMajorVersion) {
+ if (!Version.isColoredVersion(peerMajorVersion) && (captureEngineConfiguration.isCaptureColors() || captureEngineConfiguration.getCaptureQuantization().getLevels() < Gray8Bits.X_32.getLevels())) {
+ Log.warn(format("Pre color v%d.x.x peer detected: CaptureEngineConfiguration adjusted to %s", peerMajorVersion, Gray8Bits.X_128));
+ captureEngineConfiguration = new CaptureEngineConfiguration(captureEngineConfiguration.getCaptureTick(), Gray8Bits.X_128, false);
+ captureEngineConfiguration.persist();
+ }
}
@Override
@@ -881,17 +918,20 @@ public void onResizeScreen(int width, int height) {
@Override
public void onDisconnecting() {
frame.onDisconnecting();
+ networkConfiguration.setMonochromePeer(false);
}
@Override
public void onTerminating() {
Log.info("Session got terminated by peer");
frame.onTerminating();
+ networkConfiguration.setMonochromePeer(false);
}
@Override
public void onIOError(IOException error) {
frame.onIOError(error);
+ networkConfiguration.setMonochromePeer(false);
}
}
diff --git a/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java b/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java
index daf71f65..06a23acc 100644
--- a/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java
+++ b/src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java
@@ -9,6 +9,7 @@
import mpo.dayon.common.log.Log;
import mpo.dayon.common.monitoring.counter.Counter;
import mpo.dayon.common.utils.Language;
+import mpo.dayon.common.version.Version;
import javax.swing.*;
import java.awt.*;
@@ -481,7 +482,7 @@ void onClipboardReceived() {
toggleTransferControls(true);
}
- void onSessionStarted(char osId, String inputLocale) {
+ void onSessionStarted(char osId, String inputLocale, int assistedMajorVersion) {
this.osId = osId;
if (osId == 'm') {
windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.CMD));
@@ -490,6 +491,10 @@ void onSessionStarted(char osId, String inputLocale) {
windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.WIN));
windowsKeyToggleButton.setToolTipText(translate("send.winKey"));
}
+ if (Version.isOutdatedVersion(Version.get().getMajor(), assistedMajorVersion)) {
+ String infoMessage = format("%s%n%s", translate("outdated.msg1"), translate("outdated.msg2"));
+ JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE);
+ }
if (!inputLocale.isEmpty() && !inputLocale.equals(InputContext.getInstance().getLocale().toString())) {
String infoMessage = format("%s%n%s%n%s", translate("keyboardlayout.msg1", inputLocale), translate("keyboardlayout.msg2"), translate("keyboardlayout.msg3"));
JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE);
diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java
index 7980c448..e04084ca 100644
--- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java
+++ b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngine.java
@@ -26,6 +26,7 @@
import static java.lang.String.format;
import static mpo.dayon.common.utils.SystemUtilities.safeClose;
+import static mpo.dayon.common.version.Version.isColoredVersion;
import static mpo.dayon.common.version.Version.isCompatibleVersion;
public class NetworkAssistantEngine extends NetworkEngine implements ReConfigurable {
@@ -289,6 +290,7 @@ private NetworkHelloMessage introduce(ObjectInputStream in) throws IOException {
Log.error(format("Incompatible assisted version: %d.%d", hello.getMajor(), hello.getMinor()));
throw new IOException("version.wrong");
}
+ configuration.setMonochromePeer(!isColoredVersion(hello.getMajor()));
return hello;
}
@@ -297,7 +299,7 @@ private NetworkHelloMessage introduce(ObjectInputStream in) throws IOException {
*/
public void sendCaptureConfiguration(CaptureEngineConfiguration configuration) {
if (sender != null) {
- sender.sendCaptureConfiguration(configuration);
+ sender.sendCaptureConfiguration(configuration, this.configuration.isMonochromePeer());
}
}
@@ -359,7 +361,7 @@ private boolean fireOnAccepted(Socket connection) {
}
private void fireOnConnected(Socket connection, NetworkHelloMessage hello) {
- listeners.getListeners().forEach(listener -> listener.onConnected(connection, hello.getOsId(), hello.getInputLocale()));
+ listeners.getListeners().forEach(listener -> listener.onConnected(connection, hello.getOsId(), hello.getInputLocale(), hello.getMajor()));
}
private void fireOnByteReceived(int count) {
diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java
index 871db0b1..ca47fe91 100644
--- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java
+++ b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineConfiguration.java
@@ -18,6 +18,8 @@ public class NetworkAssistantEngineConfiguration extends Configuration {
private final String tokenServerUrl;
+ private boolean monochromePeer = false;
+
/**
* Default : takes its values from the current preferences.
*/
@@ -39,6 +41,14 @@ public String getTokenServerUrl() {
return tokenServerUrl;
}
+ public boolean isMonochromePeer() {
+ return monochromePeer;
+ }
+
+ public void setMonochromePeer(boolean monochromePeer) {
+ this.monochromePeer = monochromePeer;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java
index f131aedd..21e6af80 100644
--- a/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java
+++ b/src/main/java/mpo/dayon/assistant/network/NetworkAssistantEngineListener.java
@@ -21,7 +21,7 @@ public interface NetworkAssistantEngineListener extends Listener {
/**
* Should not block as called from the network receiving thread (!)
*/
- void onConnected(Socket connection, char osId, String inputLocale);
+ void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion);
/**
* Should not block as called from the network receiving thread (!)
diff --git a/src/main/java/mpo/dayon/assisted/capture/CaptureEngine.java b/src/main/java/mpo/dayon/assisted/capture/CaptureEngine.java
index 34078a0b..5f50fef6 100644
--- a/src/main/java/mpo/dayon/assisted/capture/CaptureEngine.java
+++ b/src/main/java/mpo/dayon/assisted/capture/CaptureEngine.java
@@ -96,6 +96,7 @@ public void stop() {
private void mainLoop() throws InterruptedException {
Gray8Bits quantization = null;
+ boolean captureColors = false;
int tick = -1;
long start = -1L;
int captureId = 0;
@@ -108,6 +109,7 @@ private void mainLoop() throws InterruptedException {
if (reconfigured) {
// assuming everything has changed (!)
quantization = configuration.getCaptureQuantization();
+ captureColors = configuration.isCaptureColors();
tick = configuration.getCaptureTick();
start = System.currentTimeMillis();
captureCount = 0;
@@ -123,7 +125,7 @@ private void mainLoop() throws InterruptedException {
}
++captureCount;
++captureId;
- final byte[] pixels = captureFactory.captureGray(quantization);
+ final byte[] pixels = captureColors ? captureFactory.captureScreen(null) : captureFactory.captureScreen(quantization);
if (pixels == null) {
// testing purpose (!)
@@ -177,8 +179,8 @@ private void updatePreviousCapture(Capture capture) {
}
private CaptureTile[] computeDirtyTiles(byte[] capture) {
- final int x = (captureDimension.width + TILE_DIMENSION.width -1) / TILE_DIMENSION.width;
- final int y = (captureDimension.height + TILE_DIMENSION.height -1) / TILE_DIMENSION.height;
+ final int x = (captureDimension.width + TILE_DIMENSION.width - 1) / TILE_DIMENSION.width;
+ final int y = (captureDimension.height + TILE_DIMENSION.height - 1) / TILE_DIMENSION.height;
final int length = x * y;
// change in screen resolution?
if (length != previousCapture.length) {
@@ -188,13 +190,13 @@ private CaptureTile[] computeDirtyTiles(byte[] capture) {
CaptureTile[] dirty = new CaptureTile[length];
byte[] tileData;
boolean hasDirty = false;
+ int pixelSize = configuration.isCaptureColors() ? 4 : 1;
int tileId = 0;
for (int ty = 0; ty < captureDimension.height; ty += TILE_DIMENSION.height) {
final int th = min(captureDimension.height - ty, TILE_DIMENSION.height);
for (int tx = 0; tx < captureDimension.width; tx += TILE_DIMENSION.width) {
- final int tw = min(captureDimension.width - tx, TILE_DIMENSION.width);
- final int offset = ty * captureDimension.width + tx;
- tileData = createTile(capture, captureDimension.width, offset, tw, th);
+ final int tw = Math.min(captureDimension.width - tx, TILE_DIMENSION.width);
+ tileData = createTile(capture, captureDimension.width, tw, th, tx, ty, pixelSize);
final long cs = CaptureTile.computeChecksum(tileData, 0, tileData.length);
if (cs != previousCapture[tileId]) {
dirty[tileId] = new CaptureTile(cs, new Position(tx, ty), tw, th, tileData);
@@ -207,19 +209,19 @@ private CaptureTile[] computeDirtyTiles(byte[] capture) {
}
/**
- * Screen-rectangle buffer to tile-rectangle buffer.
+ * Screen-rectangle buffer to tile-rectangle buffer. Use pixelSize 4 for colored and 1 for gray pixels.
*/
- private static byte[] createTile(byte[] capture, int width, int srcPos, int tw, int th) {
- final int capacity = tw * th;
+ private static byte[] createTile(byte[] capture, int width, int tw, int th, int tx, int ty, int pixelSize) {
+ final int capacity = tw * th * pixelSize;
final byte[] tile = new byte[capacity];
final int maxSrcPos = capture.length;
- final int maxDestPos = capacity - tw + 1;
+ final int maxDestPos = capacity - tw * pixelSize + 1;
+ int srcPos = ty * width * pixelSize + tx * pixelSize;
int destPos = 0;
-
while (destPos < maxDestPos && srcPos < maxSrcPos) {
- System.arraycopy(capture, srcPos, tile, destPos, tw);
- srcPos += width;
- destPos += tw;
+ System.arraycopy(capture, srcPos, tile, destPos, tw * pixelSize);
+ srcPos += width * pixelSize;
+ destPos += tw * pixelSize;
}
return tile;
}
diff --git a/src/main/java/mpo/dayon/assisted/capture/CaptureFactory.java b/src/main/java/mpo/dayon/assisted/capture/CaptureFactory.java
index 8335e60b..4c784764 100644
--- a/src/main/java/mpo/dayon/assisted/capture/CaptureFactory.java
+++ b/src/main/java/mpo/dayon/assisted/capture/CaptureFactory.java
@@ -8,6 +8,6 @@ public interface CaptureFactory {
Dimension getDimension();
- byte[] captureGray(Gray8Bits quantization);
+ byte[] captureScreen(Gray8Bits quantization);
}
diff --git a/src/main/java/mpo/dayon/assisted/capture/RobotCaptureFactory.java b/src/main/java/mpo/dayon/assisted/capture/RobotCaptureFactory.java
index d1b2eb51..03347eea 100644
--- a/src/main/java/mpo/dayon/assisted/capture/RobotCaptureFactory.java
+++ b/src/main/java/mpo/dayon/assisted/capture/RobotCaptureFactory.java
@@ -19,7 +19,7 @@ public Dimension getDimension() {
}
@Override
- public byte[] captureGray(Gray8Bits quantization) {
- return ScreenUtilities.captureGray(quantization);
+ public byte[] captureScreen(Gray8Bits quantization) {
+ return quantization == null ? ScreenUtilities.captureColors() : ScreenUtilities.captureGray(quantization);
}
}
diff --git a/src/main/java/mpo/dayon/assisted/utils/ScreenUtilities.java b/src/main/java/mpo/dayon/assisted/utils/ScreenUtilities.java
index 01ba451b..cad96c03 100644
--- a/src/main/java/mpo/dayon/assisted/utils/ScreenUtilities.java
+++ b/src/main/java/mpo/dayon/assisted/utils/ScreenUtilities.java
@@ -3,6 +3,7 @@
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
+import java.nio.ByteBuffer;
import mpo.dayon.common.capture.Gray8Bits;
@@ -74,12 +75,19 @@ public static byte[] captureGray(Gray8Bits quantization) {
return rgbToGray8(quantization, captureRGB(sharedScreenSize));
}
+ public static byte[] captureColors() {
+ final int[] ints = captureRGB(sharedScreenSize);
+ ByteBuffer bb = ByteBuffer.allocate(4 * ints.length);
+ bb.asIntBuffer().put(ints);
+ return bb.array();
+ }
+
private static int[] captureRGB(Rectangle bounds) {
BufferedImage image = ROBOT.createScreenCapture(bounds);
final int imageHeight = min(image.getHeight(), bounds.height);
final int imageWidth = min(image.getWidth(), bounds.width);
int[] pixels = new int[imageHeight * imageWidth];
- return image.getRGB(0,0, imageWidth, imageHeight, pixels, 0, imageWidth);
+ return image.getRGB(0, 0, imageWidth, imageHeight, pixels, 0, imageWidth);
}
public static byte[] captureGray(Rectangle bounds, Gray8Bits quantization) {
diff --git a/src/main/java/mpo/dayon/common/buffer/MemByteBuffer.java b/src/main/java/mpo/dayon/common/buffer/MemByteBuffer.java
index 76c05733..7c5fd11b 100644
--- a/src/main/java/mpo/dayon/common/buffer/MemByteBuffer.java
+++ b/src/main/java/mpo/dayon/common/buffer/MemByteBuffer.java
@@ -10,7 +10,6 @@ public class MemByteBuffer extends OutputStream {
private static final int DEFAULT_INITIAL_CAPACITY = 32;
private byte[] buffer;
-
private int count;
public MemByteBuffer() {
@@ -26,8 +25,8 @@ private MemByteBuffer(int capacity) {
* the newly created buffer is adopting that byte array (!)
*/
public MemByteBuffer(byte[] data) {
- buffer = data.clone();
count = data.length;
+ buffer = Arrays.copyOf(data, count);
}
public int size() {
@@ -35,7 +34,7 @@ public int size() {
}
public byte[] getInternal() {
- return buffer.clone();
+ return Arrays.copyOf(buffer, count);
}
public int mark() {
@@ -53,8 +52,8 @@ private void resetToMark(int mark) {
* b
. The 24 high-order bits of b
are ignored.
*/
@Override
- public void write(int val) {
- increaseBuffer(count + 1);
+ public void write(int val) {
+ ensureCapacity(count + 1);
buffer[count++] = (byte) val;
}
@@ -62,25 +61,24 @@ public void write(int val) {
* @see #write(int)
*/
private void write(int val1, int val2) {
- increaseBuffer(count + 2);
+ ensureCapacity(count + 2);
buffer[count++] = (byte) val1;
buffer[count++] = (byte) val2;
}
@Override
- public void write(byte[] buffer) {
+ public void write(byte[] buffer) {
write(buffer, 0, buffer.length);
}
@Override
- public void write(byte[] buffer, int off, int len) {
+ public void write(byte[] buffer, int off, int len) {
if (len == 0) {
return;
}
- final int newCount = count + len;
- increaseBuffer(newCount);
+ ensureCapacity(count + len);
System.arraycopy(buffer, off, this.buffer, count, len);
- count = newCount;
+ count += len;
}
/**
@@ -107,22 +105,20 @@ public void writeLenAsShort(int mark) {
}
public void fill(int len, int val) {
- final int newCount = count + len;
- increaseBuffer(newCount);
- Arrays.fill(buffer, count, newCount, (byte) val);
- count = newCount;
+ ensureCapacity(count + len);
+ Arrays.fill(buffer, count, count + len, (byte) val);
+ count += len;
}
public void arraycopy(byte[] in, int start, int len) {
- final int newCount = count + len;
- increaseBuffer(newCount);
+ ensureCapacity(count + len);
System.arraycopy(in, start, buffer, count, len);
- count = newCount;
+ count += len;
}
- private void increaseBuffer(int newCount) {
+ private void ensureCapacity(int newCount) {
if (newCount > buffer.length) {
buffer = Arrays.copyOf(buffer, Math.max(buffer.length << 1, newCount));
}
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/mpo/dayon/common/capture/Capture.java b/src/main/java/mpo/dayon/common/capture/Capture.java
index 956fd787..2eca2d96 100644
--- a/src/main/java/mpo/dayon/common/capture/Capture.java
+++ b/src/main/java/mpo/dayon/common/capture/Capture.java
@@ -10,13 +10,14 @@
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.AbstractMap;
-import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import mpo.dayon.common.buffer.MemByteBuffer;
import mpo.dayon.common.log.Log;
+import static java.util.Arrays.stream;
+
public class Capture {
private final int id;
@@ -91,7 +92,7 @@ public double computeCompressionRatio(int compressed) {
* number of gray levels.
*/
private int computeInitialByteCount() {
- return Arrays.stream(dirty).filter(Objects::nonNull).mapToInt(tile -> tile.getCapture().size()).sum();
+ return stream(dirty).filter(Objects::nonNull).mapToInt(tile -> tile.getCapture().size()).sum();
}
public int getWidth() {
@@ -111,7 +112,7 @@ public int getTHeight() {
}
public int getDirtyTileCount() {
- return (int) Arrays.stream(dirty).filter(Objects::nonNull).count();
+ return (int) stream(dirty).filter(Objects::nonNull).count();
}
public CaptureTile[] getDirtyTiles() {
@@ -128,7 +129,7 @@ public void mergeDirtyTiles(Capture[] olders) {
}
skipped.addAndGet(xskipped);
merged.set(1 + xmerged);
- Log.warn(String.format("Merged [id:%d] [count:%d] [skipped:%d][merged:%d]", id, olders.length, skipped.get(), merged.get()));
+ Log.warn(String.format("Merged [id:%d][count:%d][skipped:%d][merged:%d]", id, olders.length, skipped.get(), merged.get()));
}
/**
@@ -161,20 +162,29 @@ private void doMergeDirtyTiles(Capture older) {
* Tile-rectangle buffer to screen-rectangle buffer.
*/
public AbstractMap.SimpleEntry createBufferedImage(byte[] prevBuffer, int prevWidth, int prevHeight) {
+ final boolean isGray = stream(dirty)
+ .anyMatch(tile -> tile != null && tile.getCapture().size() == tile.getWidth() * tile.getHeight());
+ return isGray ? createBufferedMonochromeImage(prevBuffer, prevWidth, prevHeight) : createBufferedColorImage(prevBuffer, prevWidth, prevHeight);
+ }
+
+ /**
+ * Tile-rectangle buffer to screen-rectangle buffer. (monochromatic, 1 byte per pixel)
+ */
+ private AbstractMap.SimpleEntry createBufferedMonochromeImage(byte[] prevBuffer, int prevWidth, int prevHeight) {
final int capWidth = captureDimension.width;
final int capHeight = captureDimension.height;
- final byte[] buffer = (prevBuffer != null && capWidth == prevWidth && capHeight == prevHeight) ? prevBuffer : new byte[capWidth * capHeight];
- Arrays.stream(dirty)
+ final byte[] buffer = (prevBuffer != null && capWidth == prevWidth && capHeight == prevHeight && prevBuffer.length == capWidth * capHeight) ? prevBuffer : new byte[capWidth * capHeight];
+ stream(dirty)
.parallel()
.filter(Objects::nonNull)
.forEach(tile -> {
final MemByteBuffer src = tile.getCapture();
- final int srcSize = src.size();
- final int tw = tile.getWidth();
- int destPos = tile.getY() * captureDimension.width + tile.getX();
- for (int srcPos = 0; srcPos < srcSize; srcPos += tw) {
- System.arraycopy(src.getInternal(), srcPos, buffer, destPos, tw);
- destPos += captureDimension.width;
+ final int tileWidth = tile.getWidth();
+ final int srcSize = tileWidth * tile.getHeight();
+ int destPos = tile.getY() * capWidth + tile.getX();
+ for (int srcPos = 0; srcPos < srcSize; srcPos += tileWidth) {
+ System.arraycopy(src.getInternal(), srcPos, buffer, destPos, tileWidth);
+ destPos += capWidth;
}
});
@@ -183,4 +193,32 @@ public AbstractMap.SimpleEntry createBufferedImage(byte[]
final ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] { 8 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
return new AbstractMap.SimpleEntry<>(new BufferedImage(cm, raster, false, null), buffer);
}
+
+ /**
+ * Tile-rectangle buffer to screen-rectangle buffer. (color, 4 bytes per pixel)
+ */
+ private AbstractMap.SimpleEntry createBufferedColorImage(byte[] prevBuffer, int prevWidth, int prevHeight) {
+ final int capWidth = captureDimension.width;
+ final int capHeight = captureDimension.height;
+ final byte[] buffer = (prevBuffer != null && capWidth == prevWidth && capHeight == prevHeight && prevBuffer.length == capWidth * capHeight * 4) ? prevBuffer : new byte[capWidth * capHeight * 4];
+ final int capWidthByteSize = capWidth * 4;
+ stream(dirty)
+ .parallel()
+ .filter(Objects::nonNull)
+ .forEach(tile -> {
+ final MemByteBuffer src = tile.getCapture();
+ final int tileWidthByteSize = tile.getWidth() * 4;
+ final int srcSize = tileWidthByteSize * tile.getHeight();
+ int destPos = tile.getY() * capWidthByteSize + tile.getX() * 4;
+ for (int srcPos = 0; srcPos < srcSize; srcPos += tileWidthByteSize) {
+ System.arraycopy(src.getInternal(), srcPos, buffer, destPos, tileWidthByteSize);
+ destPos += capWidthByteSize;
+ }
+ });
+
+ final DataBufferByte dbuffer = new DataBufferByte(buffer, buffer.length);
+ final WritableRaster raster = Raster.createInterleavedRaster(dbuffer, capWidth, capHeight, capWidthByteSize , 4, new int[] { 1, 2, 3 }, null);
+ final ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+ return new AbstractMap.SimpleEntry<>(new BufferedImage(cm, raster, false, null), buffer);
+ }
}
diff --git a/src/main/java/mpo/dayon/common/capture/CaptureEngineConfiguration.java b/src/main/java/mpo/dayon/common/capture/CaptureEngineConfiguration.java
index 1a1ca3d5..4c52c46c 100644
--- a/src/main/java/mpo/dayon/common/capture/CaptureEngineConfiguration.java
+++ b/src/main/java/mpo/dayon/common/capture/CaptureEngineConfiguration.java
@@ -10,6 +10,8 @@ public class CaptureEngineConfiguration extends Configuration {
private static final String PREF_CAPTURE_QUANTIZATION = "assistant.capture.grayLevelQuantization";
+ private static final String PREF_CAPTURE_COLORS = "assistant.capture.colors";
+
/**
* A capture is performed every tick (millis).
*/
@@ -20,6 +22,8 @@ public class CaptureEngineConfiguration extends Configuration {
*/
private final Gray8Bits captureQuantization;
+ private final boolean captureColors;
+
/**
* Default : takes its values from the current preferences.
*
@@ -29,11 +33,13 @@ public CaptureEngineConfiguration() {
final Preferences prefs = Preferences.getPreferences();
captureTick = prefs.getIntPreference(PREF_CAPTURE_TICK, 200);
captureQuantization = prefs.getEnumPreference(PREF_CAPTURE_QUANTIZATION, Gray8Bits.X_128, Gray8Bits.values());
+ captureColors = prefs.getBooleanPreference(PREF_CAPTURE_COLORS, false);
}
- public CaptureEngineConfiguration(int captureTick, Gray8Bits captureQuantization) {
+ public CaptureEngineConfiguration(int captureTick, Gray8Bits captureQuantization, boolean captureColor) {
this.captureTick = captureTick;
this.captureQuantization = captureQuantization;
+ this.captureColors = captureColor;
}
public int getCaptureTick() {
@@ -44,6 +50,10 @@ public Gray8Bits getCaptureQuantization() {
return captureQuantization;
}
+ public boolean isCaptureColors() {
+ return captureColors;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -55,12 +65,12 @@ public boolean equals(Object o) {
final CaptureEngineConfiguration that = (CaptureEngineConfiguration) o;
- return captureTick == that.getCaptureTick() && captureQuantization == that.getCaptureQuantization();
+ return captureTick == that.getCaptureTick() && captureQuantization == that.getCaptureQuantization() && captureColors == that.captureColors;
}
@Override
public int hashCode() {
- return 31 * captureTick + (captureQuantization != null ? captureQuantization.hashCode() : 0);
+ return 31 * captureTick + (captureQuantization != null ? captureQuantization.hashCode() : 0) + (captureColors ? 1 : 0);
}
/**
@@ -77,6 +87,7 @@ private Preferences.Props getProps(boolean clear) {
props.set(PREF_VERSION, String.valueOf(1));
props.set(PREF_CAPTURE_TICK, String.valueOf(captureTick));
props.set(PREF_CAPTURE_QUANTIZATION, String.valueOf(captureQuantization.ordinal()));
+ props.set(PREF_CAPTURE_COLORS, String.valueOf(captureColors));
// migration support (!)
if (clear) {
@@ -87,6 +98,6 @@ private Preferences.Props getProps(boolean clear) {
@Override
public String toString() {
- return "[tick:" + captureTick + "][quantization:" + captureQuantization + "]";
+ return "[tick:" + captureTick + "][quantization:" + captureQuantization + "][color:" + captureColors + "]";
}
}
diff --git a/src/main/java/mpo/dayon/common/capture/CaptureTile.java b/src/main/java/mpo/dayon/common/capture/CaptureTile.java
index 83e43859..a94c52a2 100644
--- a/src/main/java/mpo/dayon/common/capture/CaptureTile.java
+++ b/src/main/java/mpo/dayon/common/capture/CaptureTile.java
@@ -59,9 +59,6 @@ public CaptureTile(XYWH xywh, MemByteBuffer capture) {
this.width = xywh.w;
this.height = xywh.h;
this.capture = capture;
- if (width * height != capture.size()) {
- throw new IllegalArgumentException("Ouch!");
- }
this.singleLevel = -1;
this.fromCache = false;
}
@@ -74,7 +71,7 @@ public CaptureTile(XYWH xywh, byte singleLevel) {
this.position = new Position(xywh.x, xywh.y);
this.width = xywh.w;
this.height = xywh.h;
- final byte[] data = new byte[width * height];
+ final byte[] data = new byte[width * height * 4];
Arrays.fill(data, singleLevel);
this.capture = new MemByteBuffer(data);
this.singleLevel = singleLevel;
@@ -89,11 +86,8 @@ public CaptureTile(XYWH xywh, CaptureTile cached) {
this.position = new Position(xywh.x, xywh.y);
this.width = xywh.w;
this.height = xywh.h;
- this.capture = (cached == MISSING) ? new MemByteBuffer(new byte[width * height]) // black image (!)
+ this.capture = (cached == MISSING) ? new MemByteBuffer(new byte[width * height * 4]) // black image (!)
: cached.getCapture(); // sharing it (!)
- if (width * height != capture.size()) {
- throw new IllegalArgumentException("Ouch!");
- }
this.singleLevel = -1;
this.fromCache = true;
}
@@ -122,6 +116,10 @@ public int getWidth() {
return width;
}
+ public int getHeight() {
+ return height;
+ }
+
public MemByteBuffer getCapture() {
return capture;
}
diff --git a/src/main/java/mpo/dayon/common/network/NetworkSender.java b/src/main/java/mpo/dayon/common/network/NetworkSender.java
index da1afeb0..fb145961 100644
--- a/src/main/java/mpo/dayon/common/network/NetworkSender.java
+++ b/src/main/java/mpo/dayon/common/network/NetworkSender.java
@@ -100,8 +100,8 @@ public boolean sendMouseLocation(Point location) {
*
* Assistant 2 assisted.
*/
- public void sendCaptureConfiguration(CaptureEngineConfiguration configuration) {
- send(true, new NetworkCaptureConfigurationMessage(configuration));
+ public void sendCaptureConfiguration(CaptureEngineConfiguration configuration, boolean monochromePeer) {
+ send(true, new NetworkCaptureConfigurationMessage(configuration, monochromePeer));
}
/**
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkCaptureConfigurationMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkCaptureConfigurationMessage.java
index 485d4651..af61873c 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkCaptureConfigurationMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkCaptureConfigurationMessage.java
@@ -7,9 +7,11 @@
public class NetworkCaptureConfigurationMessage extends NetworkMessage {
private final CaptureEngineConfiguration configuration;
+ private final boolean monochromePeer;
- public NetworkCaptureConfigurationMessage(CaptureEngineConfiguration configuration) {
+ public NetworkCaptureConfigurationMessage(CaptureEngineConfiguration configuration, boolean monochromePeer) {
this.configuration = configuration;
+ this.monochromePeer = monochromePeer;
}
@Override
@@ -27,7 +29,11 @@ public CaptureEngineConfiguration getConfiguration() {
*/
@Override
public int getWireSize() {
- return 6; // type (byte) + quantization (byte) + tick (int)
+ // for backwards compatibility
+ if (monochromePeer) {
+ return 6;
+ }
+ return 8; // type (byte) + quantization (byte) + tick (int) + colors (short)
}
@Override
@@ -35,15 +41,21 @@ public void marshall(ObjectOutputStream out) throws IOException {
marshallEnum(out, getType());
marshallEnum(out, configuration.getCaptureQuantization());
out.writeInt(configuration.getCaptureTick());
+ // for backwards compatibility
+ if (!monochromePeer) {
+ out.writeShort(configuration.isCaptureColors() ? 1 : 0);
+ }
}
public static NetworkCaptureConfigurationMessage unmarshall(ObjectInputStream in) throws IOException {
final Gray8Bits quantization = unmarshallEnum(in, Gray8Bits.class);
- return new NetworkCaptureConfigurationMessage(new CaptureEngineConfiguration(in.readInt(), quantization));
+ final int tick = in.readInt();
+ final boolean colors = in.readShort() == 1;
+ return new NetworkCaptureConfigurationMessage(new CaptureEngineConfiguration(tick, quantization, colors), false);
}
public String toString() {
- return String.format("[quantization:%s] [tick:%d]", configuration.getCaptureQuantization(), configuration.getCaptureTick());
+ return String.format("[quantization:%s][tick:%d][colors:%b]", configuration.getCaptureQuantization(), configuration.getCaptureTick(), configuration.isCaptureColors());
}
}
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkCaptureMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkCaptureMessage.java
index b85fa0a7..f622916f 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkCaptureMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkCaptureMessage.java
@@ -102,6 +102,6 @@ public MemByteBuffer getPayload() {
}
public String toString() {
- return String.format("[id:%d] [%s]", id, UnitUtilities.toBitSize(8d * payload.size()));
+ return String.format("[id:%d][%s]", id, UnitUtilities.toBitSize(8d * payload.size()));
}
}
\ No newline at end of file
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkClipboardFilesMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkClipboardFilesMessage.java
index 5241b867..6adc85e4 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkClipboardFilesMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkClipboardFilesMessage.java
@@ -52,11 +52,14 @@ public static NetworkClipboardFilesHelper unmarshall(ObjectInputStream in, Netwo
if (!append) {
Log.info("Receiving " + fileName);
}
- String tempFilePath = format("%s%s%s%s", tmpDir, File.separator, helper.getTransferId(), fileName);
+ if (!tmpDir.endsWith(File.separator)) {
+ tmpDir += File.separator;
+ }
+ String tempFilePath = format("%s%s%s", tmpDir, helper.getTransferId(), fileName);
writeToTempFile(buffer, read, tempFilePath, append);
if (getRemainingTotalFilesSize(helper, read, position) == 0) {
- String rootPath = format("%s%s%s", tmpDir, File.separator, helper.getTransferId());
+ String rootPath = format("%s%s", tmpDir, helper.getTransferId());
File[] filesArray = new File(rootPath).listFiles();
if (filesArray != null) {
helper.setFiles(Arrays.asList(Objects.requireNonNull(filesArray)));
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkHelloMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkHelloMessage.java
index c287d18c..117f6064 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkHelloMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkHelloMessage.java
@@ -69,6 +69,6 @@ public static NetworkHelloMessage unmarshall(ObjectInputStream in) throws IOExce
}
public String toString() {
- return String.format("[major:%d] [minor:%d] [osId:%c] [inputLocale:%s]", major, minor, osId, inputLocale);
+ return String.format("[major:%d][minor:%d][osId:%c][inputLocale:%s]", major, minor, osId, inputLocale);
}
}
\ No newline at end of file
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkMouseControlMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkMouseControlMessage.java
index 78df660a..596e4dd8 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkMouseControlMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkMouseControlMessage.java
@@ -128,9 +128,9 @@ public static NetworkMouseControlMessage unmarshall(ObjectInputStream in) throws
public String toString() {
if (isWheel()) {
- return String.format("[x:%d] [y:%s] [WHEEL] [%d]", x, y, rotations);
+ return String.format("[x:%d][y:%s][WHEEL][%d]", x, y, rotations);
}
- return String.format("[x:%d] [y:%s] [%s] [%s]", x, y, toStringPressed(), toStringButton());
+ return String.format("[x:%d][y:%s][%s][%s]", x, y, toStringPressed(), toStringButton());
}
private String toStringPressed() {
diff --git a/src/main/java/mpo/dayon/common/network/message/NetworkMouseLocationMessage.java b/src/main/java/mpo/dayon/common/network/message/NetworkMouseLocationMessage.java
index 0b6ccdfa..ddd35177 100644
--- a/src/main/java/mpo/dayon/common/network/message/NetworkMouseLocationMessage.java
+++ b/src/main/java/mpo/dayon/common/network/message/NetworkMouseLocationMessage.java
@@ -51,6 +51,6 @@ public static NetworkMouseLocationMessage unmarshall(ObjectInputStream in) throw
}
public String toString() {
- return String.format("[x:%d] [y:%s]", x, y);
+ return String.format("[x:%d][y:%s]", x, y);
}
}
\ No newline at end of file
diff --git a/src/main/java/mpo/dayon/common/squeeze/Compressor.java b/src/main/java/mpo/dayon/common/squeeze/Compressor.java
index c32e9f2b..0a2061c5 100644
--- a/src/main/java/mpo/dayon/common/squeeze/Compressor.java
+++ b/src/main/java/mpo/dayon/common/squeeze/Compressor.java
@@ -64,7 +64,7 @@ public MemByteBuffer compress(TileCache cache, Capture capture) throws IOExcepti
encoded.write(capture.getSkipped()); // as a byte (!)
encoded.write(capture.getMerged()); // as a byte (!)
if (capture.isReset()) {
- Log.info("Clear compressor cache [tile:" + capture.getId() + "]");
+ Log.debug("Clear compressor cache [tile:" + capture.getId() + "]");
cache.clear(); // here for symmetry with the de-compressor (!)
}
encoded.writeShort(capture.getWidth());
@@ -139,7 +139,7 @@ public Capture decompress(TileCache cache, MemByteBuffer zipped) throws IOExcept
final int cId = in.readInt();
final boolean cReset = in.read() == 1;
if (cReset) {
- Log.info("Clear de-compressor cache [tile:" + cId + "]");
+ Log.debug("Clear de-compressor cache [tile:" + cId + "]");
cache.clear();
}
final int cSkipped = in.readByte() & 0xFF;
diff --git a/src/main/java/mpo/dayon/common/squeeze/RegularTileCache.java b/src/main/java/mpo/dayon/common/squeeze/RegularTileCache.java
index 3732c3dc..16828f36 100644
--- a/src/main/java/mpo/dayon/common/squeeze/RegularTileCache.java
+++ b/src/main/java/mpo/dayon/common/squeeze/RegularTileCache.java
@@ -11,14 +11,14 @@
public class RegularTileCache implements TileCache {
/**
- * Maximum number of tiles; currently a tile is basically a 32x32 byte array (i.e., 1K).
+ * Maximum number of tiles; currently a tile is basically a 32x32 byte array (i.e., 1K for gray, 4K for color).
*/
- public static final int DEFAULT_MAX_SIZE = 16 * 1024;
+ public static final int DEFAULT_MAX_SIZE = 32 * 4096;
/**
* Number of tiles after a purge.
*/
- public static final int DEFAULT_PURGE_SIZE = 14 * 1024;
+ public static final int DEFAULT_PURGE_SIZE = 24 * 4096;
private final Map tiles = new HashMap<>();
@@ -73,7 +73,7 @@ public int size() {
@Override
public void clear() {
- Log.info("Clearing the cache...");
+ Log.debug("Clearing the cache...");
tiles.clear();
lru.clear();
}
diff --git a/src/main/java/mpo/dayon/common/version/Version.java b/src/main/java/mpo/dayon/common/version/Version.java
index 31f95d61..e34e7dec 100644
--- a/src/main/java/mpo/dayon/common/version/Version.java
+++ b/src/main/java/mpo/dayon/common/version/Version.java
@@ -96,6 +96,17 @@ public static boolean isCompatibleVersion(int major, int minor, Version that) {
return that.getMajor() == major && that.getMinor() == minor;
}
+ public static boolean isOutdatedVersion(int major, int otherMajor) {
+ if (major == 0 || otherMajor == 0) {
+ return false;
+ }
+ return major > otherMajor;
+ }
+
+ public static boolean isColoredVersion(int major) {
+ return major > 14 || major == 0;
+ }
+
static boolean isProd(int major, int minor) {
return major + minor > 0;
}
diff --git a/src/main/resources/Babylon.properties b/src/main/resources/Babylon.properties
index e55daff0..36c7f5be 100644
--- a/src/main/resources/Babylon.properties
+++ b/src/main/resources/Babylon.properties
@@ -144,6 +144,7 @@ capture.reset = Reset screen capture (i.e., cache, etc...)
tick = Tick
tick.tooltip = The screen is captured every [ tick ] milliseconds
grays = Gray levels
+colors = True colors
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = Share all screens
compatibility.mode = Compatibility mode for previous versions
compatibility.mode.enable = Enable compatibility mode!
compatibility.mode.active = Compatibility mode active
-compatibility.mode.info = Please consider updating Assisted to the latest version to minimize risks.
+compatibility.mode.info = Please consider updating your peer to the latest version to minimize risks.
changeLanguage = Change language
startChat = Start a chat
keyboardlayout.msg1 = The assisted currently uses a different keyboard layout: %s
keyboardlayout.msg2 = This can lead to problems, especially when entering special characters.
-keyboardlayout.msg3 = If you experience problems, please ensure you are using the same on both computers.
\ No newline at end of file
+keyboardlayout.msg3 = If you experience problems, please ensure you are using the same on both computers.
+
+outdated.msg1 = Reduced functionality.
+outdated.msg2 = Update your peer to the latest version to enjoy all features.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_de.properties b/src/main/resources/Babylon_de.properties
index 7daa2e6c..01a815bf 100644
--- a/src/main/resources/Babylon_de.properties
+++ b/src/main/resources/Babylon_de.properties
@@ -140,6 +140,7 @@ capture.reset = Bildschirmerfassung zur\u00FCck setzen (Puffer, etc...)
tick = Tick
tick.tooltip = Bildschirmerfassungs-Intervall [ tick ] Millisekunden
grays = Graustufen
+colors = Farben
# Compression ...
@@ -183,11 +184,14 @@ share.all.screens = Alle Bildschirme teilen
compatibility.mode = Kompatibilit\u00E4tsmodus f\u00FCr Vorg\u00E4ngerversionen
compatibility.mode.enable = Kompatibilit\u00E4tsmodus aktivieren!
compatibility.mode.active = Kompatibilit\u00E4tsmodus aktiv
-compatibility.mode.info = Um Sicherheitsrisiken zu minimieren, aktualisieren Sie doch bitte den Assistierten auf die neuste Version.
+compatibility.mode.info = Um Sicherheitsrisiken zu minimieren, aktualisieren Sie doch bitte die Gegenseite auf die neuste Version.
changeLanguage = Sprache \u00E4ndern
startChat = Chat starten
keyboardlayout.msg1 = Der Assistierte verwendet derzeit eine andere Tastaturbelegung: %s
keyboardlayout.msg2 = Dies kann insbesondere bei der Eingabe von Sonderzeichen zu Problemen f\u00FChren.
-keyboardlayout.msg3 = Sollten Probleme auftreten, stellen Sie bitte sicher,\ndass Sie auf beiden Computern die gleiche Tastaturbelegung verwenden.
\ No newline at end of file
+keyboardlayout.msg3 = Sollten Probleme auftreten, stellen Sie bitte sicher,\ndass Sie auf beiden Computern die gleiche Tastaturbelegung verwenden.
+
+outdated.msg1 = Reduzierter Funktionsumfang.
+outdated.msg2 = Aktualisieren Sie die Gegenseite auf die neuste Version um alle Funktionen zu nutzen.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_es.properties b/src/main/resources/Babylon_es.properties
index 0d6a5724..56a56a27 100644
--- a/src/main/resources/Babylon_es.properties
+++ b/src/main/resources/Babylon_es.properties
@@ -144,6 +144,7 @@ capture.reset = Reiniciar grabaci\u00F3n de pantalla (cach\u00E9, etc...)
tick = Periodo
tick.tooltip = La pantalla est\u00E1 grabado cada [ periodo ] de milisegundos
grays = Escala de grises
+colors = Colores aut\u00E9nticos
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = Compartir todas las pantallas
compatibility.mode = Modo de compatibilidad para versiones anteriores
compatibility.mode.enable = \u00A1Habilite el modo de compatibilidad!
compatibility.mode.active = Modo de compatibilidad activo
-compatibility.mode.info = Por favor, considere actualizar Assisted a la \u00FAltima versi\u00F3n para minimizar los riesgos.
+compatibility.mode.info = Por favor, considere actualizar tu par a la \u00FAltima versi\u00F3n para minimizar los riesgos.
changeLanguage = Cambiar el idioma
startChat = Iniciar un chat
keyboardlayout.msg1 = Actualmente, el asistido utiliza una distribuci\u00F3n de teclado diferente: %s
keyboardlayout.msg2 = Esto puede ocasionar problemas, especialmente al introducir caracteres especiales.
-keyboardlayout.msg3 = Si se producen problemas, aseg\u00FArese de que utiliza la misma distribuci\u00F3n de teclado en ambos ordenadores.
\ No newline at end of file
+keyboardlayout.msg3 = Si se producen problemas, aseg\u00FArese de que utiliza la misma distribuci\u00F3n de teclado en ambos ordenadores.
+
+outdated.msg1 = Funciones reducidas.
+outdated.msg2 = Actualiza tu par a la \u00FAltima versi\u00F3n para disfrutar de todas las funciones.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_fr.properties b/src/main/resources/Babylon_fr.properties
index a8970a83..1f46f13e 100644
--- a/src/main/resources/Babylon_fr.properties
+++ b/src/main/resources/Babylon_fr.properties
@@ -144,6 +144,7 @@ capture.reset = Remise-\u00E0-Z\u00E9ro de la capture d'\u00E9cran (i.e.,
tick = Tic-tac
tick.tooltip = L'\u00E9cran est captur\u00E9 tous les [ tic-tac ] milli-secondes
grays = Niveaux de Gris
+colors = Couleurs r\u00E9elles
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = Partager tous les \u00E9crans
compatibility.mode = Mode de compatibilit\u00E9 pour les versions pr\u00E9c\u00E9dentes
compatibility.mode.enable = Activez le mode compatibilit\u00E9!
compatibility.mode.active = Mode de compatibilit\u00E9 actif
-compatibility.mode.info = Veuillez consid\u00E9rer la mise \u00E0 jour de l'assist\u00E9 vers la derni\u00E8re version afin de minimiser les risques.
+compatibility.mode.info = Veuillez consid\u00E9rer la mise \u00E0 jour de votre peer vers la derni\u00E8re version afin de minimiser les risques.
changeLanguage = Changer la langue
startChat = Commencer un chat
keyboardlayout.msg1 = L'assist\u00E9 utilise actuellement une autre disposition de clavier : %s
keyboardlayout.msg2 = Cela peut entra\u00EEner des probl\u00E8mes, notamment lors de la saisie de caract\u00E8res sp\u00E9ciaux.
-keyboardlayout.msg3 = En cas de probl\u00E8me, assurez-vous que vous utilisez la m\u00EAme disposition de clavier sur les deux ordinateurs.
\ No newline at end of file
+keyboardlayout.msg3 = En cas de probl\u00E8me, assurez-vous que vous utilisez la m\u00EAme disposition de clavier sur les deux ordinateurs.
+
+outdated.msg1 = Fonctionnalit\u00E9s r\u00E9duites.
+outdated.msg2 = Mettez \u00E0 jour votre peer vers la derni\u00E8re version pour profiter de toutes les fonctionnalit\u00E9s.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_it.properties b/src/main/resources/Babylon_it.properties
index 1652e63e..d62b27d7 100644
--- a/src/main/resources/Babylon_it.properties
+++ b/src/main/resources/Babylon_it.properties
@@ -144,6 +144,7 @@ capture.reset = Reimposta l'acquisizione dello schermo (ad esempio, cache
tick = Tick
tick.tooltip = Lo schermo viene catturato ogni [ tick ] milli-secondi
grays = Livelli di grigio
+colors = Colori reali
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = Condividi tutti gli schermi
compatibility.mode = Modalit\u00E0 di compatibilit\u00E0 per le versioni precedenti
compatibility.mode.enable = Abilita la modalit\u00E0 compatibilit\u00E0!
compatibility.mode.active = Modalit\u00E0 di compatibilit\u00E0 attiva
-compatibility.mode.info = Si consiglia di aggiornare assistito alla versione pi\u00F9 recente per ridurre al minimo i rischi.
+compatibility.mode.info = Si consiglia di aggiornare il tuo peer all'ultima versione per ridurre al minimo i rischi.
changeLanguage = Cambiare la lingua
startChat = Iniziare una chat
keyboardlayout.msg1 = L'assistito utilizza attualmente un layout di tastiera diverso: %s
keyboardlayout.msg2 = Questo pu\u00F2 causare problemi, soprattutto nell'inserimento di caratteri speciali.
-keyboardlayout.msg3 = In caso di problemi, accertarsi di utilizzare lo stesso layout di tastiera su entrambi i computer.
\ No newline at end of file
+keyboardlayout.msg3 = In caso di problemi, accertarsi di utilizzare lo stesso layout di tastiera su entrambi i computer.
+
+outdated.msg1 = Funzionalit\u00E0 ridotta.
+outdated.msg2 = Aggiorna il tuo peer all'ultima versione per usufruire di tutte le funzionalit\u00E0.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_ru.properties b/src/main/resources/Babylon_ru.properties
index 76f24767..9c62c4bb 100644
--- a/src/main/resources/Babylon_ru.properties
+++ b/src/main/resources/Babylon_ru.properties
@@ -144,6 +144,7 @@ capture.reset = \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u0441\u
tick = Tick
tick.tooltip = \u042D\u043A\u0440\u0430\u043D \u0441\u043D\u0438\u043C\u0430\u0435\u0442\u0441\u044F \u043A\u0430\u0436\u0434\u044B\u0435 [ tick ] \u043C\u0438\u043B\u043B\u0438\u0441\u0435\u043A\u0443\u043D\u0434\u044B
grays = \u0423\u0440\u043E\u0432\u043D\u0438 \u0441\u0435\u0440\u043E\u0433\u043E
+colors = \u041D\u0430\u0441\u0442\u043E\u044F\u0449\u0438\u0435 \u0446\u0432\u0435\u0442\u0430
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = \u0414\u0435\u043B\u0438\u0442\u0435\u0441\u044C \u0432\u044
compatibility.mode = \u0420\u0435\u0436\u0438\u043C \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438 \u0441 \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0438\u043C\u0438 \u0432\u0435\u0440\u0441\u0438\u044F\u043C\u0438
compatibility.mode.enable = \u0412\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u0440\u0435\u0436\u0438\u043C \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438!
compatibility.mode.active = \u0420\u0435\u0436\u0438\u043C \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438 \u0430\u043A\u0442\u0438\u0432\u0435\u043D
-compatibility.mode.info = \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 \u041F\u043E\u043C\u043E\u0433\u0430\u043B \u0434\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u0447\u0442\u043E\u0431\u044B \u043C\u0438\u043D\u0438\u043C\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0438\u0441\u043A\u0438.
+compatibility.mode.info = \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0440\u0430\u0441\u0441\u043C\u043E\u0442\u0440\u0438\u0442\u0435 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0432\u0430\u0448\u0435\u0433\u043E \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u0430 \u0434\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u0447\u0442\u043E\u0431\u044B \u043C\u0438\u043D\u0438\u043C\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0438\u0441\u043A\u0438.
changeLanguage = \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u044F\u0437\u044B\u043A
startChat = \u043D\u0430\u0447\u0430\u0442\u044C \u0447\u0430\u0442
keyboardlayout.msg1 = \u0412 \u043D\u0430\u0441\u0442\u043E\u044F\u0449\u0435\u0435 \u0432\u0440\u0435\u043C\u044F \u041F\u043E\u043C\u043E\u0433\u0430\u043B \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044E \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0443 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044B: %s
keyboardlayout.msg2 = \u042D\u0442\u043E \u043C\u043E\u0436\u0435\u0442 \u043F\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043A \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430\u043C, \u043E\u0441\u043E\u0431\u0435\u043D\u043D\u043E \u043F\u0440\u0438 \u0432\u0432\u043E\u0434\u0435 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0445 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432.
-keyboardlayout.msg3 = \u0415\u0441\u043B\u0438 \u0432\u043E\u0437\u043D\u0438\u043A\u043B\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C, \u0447\u0442\u043E \u043D\u0430 \u043E\u0431\u043E\u0438\u0445 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0430\u0445 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u043E\u0434\u0438\u043D\u0430\u043A\u043E\u0432\u0430\u044F \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044B.
\ No newline at end of file
+keyboardlayout.msg3 = \u0415\u0441\u043B\u0438 \u0432\u043E\u0437\u043D\u0438\u043A\u043B\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C, \u0447\u0442\u043E \u043D\u0430 \u043E\u0431\u043E\u0438\u0445 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0430\u0445 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u043E\u0434\u0438\u043D\u0430\u043A\u043E\u0432\u0430\u044F \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044B.
+
+outdated.msg1 = \u0421\u043D\u0438\u0436\u0435\u043D\u043D\u0430\u044F \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u043E\u0441\u0442\u044C.
+outdated.msg2 = \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 \u0441\u0432\u043E\u0435 \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u043E \u0434\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u0432\u0441\u0435\u043C\u0438 \u0444\u0443\u043D\u043A\u0446\u0438\u044F\u043C\u0438.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_sv.properties b/src/main/resources/Babylon_sv.properties
index 94ea07b3..5fde21e8 100644
--- a/src/main/resources/Babylon_sv.properties
+++ b/src/main/resources/Babylon_sv.properties
@@ -144,6 +144,7 @@ capture.reset = \u00C5terst\u00E4ll sk\u00E4rmbild (dvs. cache osv...)
tick = Tick
tick.tooltip = Sk\u00E4rmbilden avl\u00E4ses [ tick ] millisekunder
grays = Gr\u00E5skalor
+colors = Sanna f\u00E4rger
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = Dela alla sk\u00E4rmar
compatibility.mode = Kompatibelt l\u00E4ge f\u00F6r tidigare versioner
compatibility.mode.enable = Aktivera kompatibilitetsl\u00E4ge!
compatibility.mode.active = Kompatibiltetsl\u00E4ge aktiverat
-compatibility.mode.info = V\u00E4nligen uppdatera Hj\u00E4lptagare till den senaste versionen f\u00F6r att minimera risker.
+compatibility.mode.info = V\u00E4nligen uppdatera din peer till den senaste versionen f\u00F6r att minimera risker.
changeLanguage = V\u00E4xla spr\u00E5kl\u00E4ge
startChat = Starta en chatt
keyboardlayout.msg1 = Hj\u00E4lptagare anv\u00E4nder f\u00F6r n\u00E4rvarande en annan tangentbordslayout: %s
keyboardlayout.msg2 = Detta kan leda till problem, s\u00E4rskilt vid inmatning av specialtecken.
-keyboardlayout.msg3 = Om du upplever problem, kontrollera att du anv\u00E4nder samma tangentbord p\u00E5 b\u00E5da datorerna.
\ No newline at end of file
+keyboardlayout.msg3 = Om du upplever problem, kontrollera att du anv\u00E4nder samma tangentbord p\u00E5 b\u00E5da datorerna.
+
+outdated.msg1 = Reducerad funktionalitet.
+outdated.msg2 = Uppdatera din peer till den senaste versionen f\u00F6r att njuta av alla funktioner.
\ No newline at end of file
diff --git a/src/main/resources/Babylon_tr.properties b/src/main/resources/Babylon_tr.properties
index ee5bead5..a140ef32 100644
--- a/src/main/resources/Babylon_tr.properties
+++ b/src/main/resources/Babylon_tr.properties
@@ -144,6 +144,7 @@ capture.reset = Ekran g\u00F6r\u00FCnt\u00FCs\u00FCn\u00FC s\u0131f\u0131
tick = Tik
tick.tooltip = Ekran her [tik] milisaniyede bir yakalan\u0131r
grays = Gri seviyeleri
+colors = Ger\u00E7ek renkler
# Compression ...
@@ -187,11 +188,14 @@ share.all.screens = T\u00FCm ekranlar\u0131 payla\u015F
compatibility.mode = \u00D6nceki s\u00FCr\u00FCmler i\u00E7in uyumluluk modu
compatibility.mode.enable = Uyumluluk modunu etkinle\u015Ftirin!
compatibility.mode.active = Uyumluluk modu etkin
-compatibility.mode.info = Riskleri en aza indirmek i\u00E7in l\u00FCtfen yard\u0131ml\u0131 en son s\u00FCr\u00FCme g\u00FCncellemeyi d\u00FC\u015F\u00FCn\u00FCn.
+compatibility.mode.info = Riskleri en aza indirmek i\u00E7in l\u00FCtfen akran\u0131n\u0131z\u0131 en son s\u00FCr\u00FCme g\u00FCncellemeyi d\u00FC\u015F\u00FCn\u00FCn.
changeLanguage = Dili de\u011Fi\u015Ftir
startChat = Sohbet ba\u015Flat
keyboardlayout.msg1 = Yard\u0131ml\u0131 \u015Fu anda farkl\u0131 bir klavye d\u00FCzeni kullan\u0131yor: %s
keyboardlayout.msg2 = Bu, \u00F6zellikle \u00F6zel karakterleri girerken sorunlara neden olabilir.
-keyboardlayout.msg3 = Sorun ya\u015Farsan\u0131z, l\u00FCtfen her iki bilgisayarda da ayn\u0131 klavyeyi kulland\u0131\u011F\u0131n\u0131zdan emin olun.
\ No newline at end of file
+keyboardlayout.msg3 = Sorun ya\u015Farsan\u0131z, l\u00FCtfen her iki bilgisayarda da ayn\u0131 klavyeyi kulland\u0131\u011F\u0131n\u0131zdan emin olun.
+
+outdated.msg1 = Azalt\u0131lm\u0131\u015F i\u015Flevsellik.
+outdated.msg2 = T\u00FCm \u00F6zelliklerden yararlanabilmek i\u00E7in arkada\u015F\u0131n\u0131z\u0131 en son s\u00FCr\u00FCme g\u00FCncelleyin.
diff --git a/src/main/resources/Babylon_zh.properties b/src/main/resources/Babylon_zh.properties
index 1e4932e3..e671cc96 100644
--- a/src/main/resources/Babylon_zh.properties
+++ b/src/main/resources/Babylon_zh.properties
@@ -218,6 +218,8 @@ tick.tooltip = \u6BCF [\u6355\u83B7\u95F4\u9694] \u6BEB\u79D2\u6355\u83B
# The tick is not a valid number. (min. 50)
# Gray levels
grays = \u7070\u5EA6\uFF08\u753B\u8D28\uFF09
+# True colors
+colors = \u771F\u9762\u76EE
# Compression ...
@@ -297,6 +299,9 @@ compatibility.mode.info = \u8BF7\u8003\u8651\u5C06\u60A8\u7684\u540C\u884C\u7CFB
changeLanguage = \u6539\u53D8\u8BED\u8A00
startChat = \u5F00\u59CB\u804A\u5929
-Keyboardlayout.msg1 = Assisted - \u7528\u6237\u7AEF\u5F53\u524D\u4F7F\u7528\u4E0D\u540C\u7684\u952E\u76D8\u5E03\u5C40\uFF1A%s
-Keyboardlayout.msg2 = \u8FD9\u53EF\u80FD\u4F1A\u5BFC\u81F4\u95EE\u9898\uFF0C\u5C24\u5176\u662F\u5728\u8F93\u5165\u7279\u6B8A\u5B57\u7B26\u65F6\u3002
-Keyboardlayout.msg3 = \u5982\u679C\u60A8\u9047\u5230\u95EE\u9898\uFF0C\u8BF7\u786E\u4FDD\u60A8\u5728\u4E24\u53F0\u8BA1\u7B97\u673A\u4E0A\u4F7F\u7528\u76F8\u540C\u7684\u8BBE\u7F6E\u3002
\ No newline at end of file
+keyboardlayout.msg1 = Assisted - \u7528\u6237\u7AEF\u5F53\u524D\u4F7F\u7528\u4E0D\u540C\u7684\u952E\u76D8\u5E03\u5C40\uFF1A%s
+keyboardlayout.msg2 = \u8FD9\u53EF\u80FD\u4F1A\u5BFC\u81F4\u95EE\u9898\uFF0C\u5C24\u5176\u662F\u5728\u8F93\u5165\u7279\u6B8A\u5B57\u7B26\u65F6\u3002
+keyboardlayout.msg3 = \u5982\u679C\u60A8\u9047\u5230\u95EE\u9898\uFF0C\u8BF7\u786E\u4FDD\u60A8\u5728\u4E24\u53F0\u8BA1\u7B97\u673A\u4E0A\u4F7F\u7528\u76F8\u540C\u7684\u8BBE\u7F6E\u3002
+
+outdated.msg1 = \u529F\u80FD\u51CF\u5C11\u3002
+outdated.msg2 = \u5C06\u60A8\u7684\u5BF9\u7B49\u4F53\u66F4\u65B0\u81F3\u6700\u65B0\u7248\u672C\u4EE5\u4EAB\u53D7\u6240\u6709\u529F\u80FD\u3002
\ No newline at end of file
diff --git a/src/test/java/mpo/dayon/common/buffer/MemByteBufferTest.java b/src/test/java/mpo/dayon/common/buffer/MemByteBufferTest.java
index 04546b76..ec86632d 100644
--- a/src/test/java/mpo/dayon/common/buffer/MemByteBufferTest.java
+++ b/src/test/java/mpo/dayon/common/buffer/MemByteBufferTest.java
@@ -67,9 +67,10 @@ void writeLenAsShort() {
@Test
void copyConstructor() throws IOException {
- buffer.fill(33, BEAST);
+ int size = 42;
+ buffer.fill(size, BEAST);
try(MemByteBuffer memBuffer = new MemByteBuffer(buffer.getInternal())) {
- assertEquals(64, memBuffer.size());
+ assertEquals(size, memBuffer.size());
assertEquals(buffer.getInternal().length, memBuffer.getInternal().length);
}
}
diff --git a/src/test/java/mpo/dayon/common/network/NetworkSenderTest.java b/src/test/java/mpo/dayon/common/network/NetworkSenderTest.java
index 30249c9d..3e3b92f3 100644
--- a/src/test/java/mpo/dayon/common/network/NetworkSenderTest.java
+++ b/src/test/java/mpo/dayon/common/network/NetworkSenderTest.java
@@ -1,5 +1,6 @@
package mpo.dayon.common.network;
+import mpo.dayon.common.capture.Gray8Bits;
import mpo.dayon.common.compressor.CompressorEngineConfiguration;
import mpo.dayon.common.buffer.MemByteBuffer;
import mpo.dayon.common.capture.Capture;
@@ -104,11 +105,12 @@ void sendMouseLocation() throws IOException {
}
@Test
- void sendCaptureConfiguration() throws IOException {
+ void sendCaptureConfigurationToLegacyPeerShouldNotIncludeCaptureColorValue() throws IOException {
// given
CaptureEngineConfiguration configuration = new CaptureEngineConfiguration();
+ boolean monochromePeer = true;
// when
- sender.sendCaptureConfiguration(configuration);
+ sender.sendCaptureConfiguration(configuration, monochromePeer);
// then
verify(outMock, timeout(50)).writeByte(MAGIC_NUMBER);
verify(outMock).write(NetworkMessageType.CAPTURE_CONFIGURATION.ordinal());
@@ -116,6 +118,21 @@ void sendCaptureConfiguration() throws IOException {
verify(outMock).writeInt(configuration.getCaptureTick());
}
+ @Test
+ void sendCaptureConfigurationIncludeTheRightCaptureColorValue() throws IOException {
+ // given
+ CaptureEngineConfiguration configuration = new CaptureEngineConfiguration(333, Gray8Bits.X_16, true);
+ boolean monochromePeer = false;
+ // when
+ sender.sendCaptureConfiguration(configuration, monochromePeer);
+ // then
+ verify(outMock, timeout(50)).writeByte(MAGIC_NUMBER);
+ verify(outMock).write(NetworkMessageType.CAPTURE_CONFIGURATION.ordinal());
+ verify(outMock).write(configuration.getCaptureQuantization().ordinal());
+ verify(outMock).writeInt(configuration.getCaptureTick());
+ verify(outMock).writeShort(1);
+ }
+
@Test
void sendCompressorConfiguration() throws IOException {
// given
diff --git a/src/test/java/mpo/dayon/common/version/VersionTest.java b/src/test/java/mpo/dayon/common/version/VersionTest.java
index 1ea3d76c..a093df7b 100644
--- a/src/test/java/mpo/dayon/common/version/VersionTest.java
+++ b/src/test/java/mpo/dayon/common/version/VersionTest.java
@@ -4,8 +4,8 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
-import static mpo.dayon.common.version.Version.isCompatibleVersion;
-import static mpo.dayon.common.version.Version.isProd;
+import static java.lang.Integer.parseInt;
+import static mpo.dayon.common.version.Version.*;
import static org.junit.jupiter.api.Assertions.*;
class VersionTest {
@@ -103,4 +103,28 @@ void isCompatibleVersionShouldReturnTrueForHardCodedCompatibleVersions(String th
assertTrue(isCompatibleVersion(other.getMajor(), other.getMinor(), that));
}
+ @ParameterizedTest
+ @CsvSource({ "15,14", "15,13"})
+ void isOutdatedVersionShouldReturnTrueForOutdatedVersions(String thatV, String otherV) {
+ // given when then
+ assertTrue(isOutdatedVersion(parseInt(thatV), parseInt(otherV)));
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "15,16", "15,15", "0,13", "15,0", "0,0"})
+ void isOutdatedVersionShouldReturnFalseForNotOutdatedVersions(String thatV, String otherV) {
+ // given when then
+ assertFalse(isOutdatedVersion(parseInt(thatV), parseInt(otherV)));
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "15.0.0", "0.0.0" })
+ void isColoredVersionShouldReturnTrueForHardCodedVersions(String thatV) {
+ // given
+ Version that = new Version(thatV);
+
+ // when then
+ assertTrue(isColoredVersion(that.getMajor()));
+ }
+
}