Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized the system tray function #60

Merged
merged 3 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions assets/ArkPetsConfigDefault.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,5 @@
"physic_gravity_acc":800.0,
"physic_speed_limit_x":1000.0,
"physic_speed_limit_y":1000.0,
"physic_static_friction_acc":500.0,
"server_port": 8080,
"separate_arkpet_from_launcher": false
"physic_static_friction_acc":500.0
}
2 changes: 0 additions & 2 deletions core/src/cn/harryh/arkpets/ArkConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ public class ArkConfig {
public float physic_static_friction_acc;
public float physic_speed_limit_x;
public float physic_speed_limit_y;
public int server_port = 8080;
public boolean separate_arkpet_from_launcher;

private ArkConfig() {
}
Expand Down
3 changes: 1 addition & 2 deletions core/src/cn/harryh/arkpets/ArkPets.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void create() {
ArkConfig.Monitor primaryMonitor = ArkConfig.Monitor.getMonitors()[0];
initWindow((int)(primaryMonitor.size[0] * 0.1f), (int)(primaryMonitor.size[0] * 0.1f));
// 5.Tray icon setup
tray = new ArkTray(this, new SocketClient(config.server_port), UUID.randomUUID());
tray = new ArkTray(this, new SocketClient(), UUID.randomUUID());
// Setup complete
Logger.info("App", "Render");
}
Expand Down Expand Up @@ -142,7 +142,6 @@ public void resize(int x, int y) {
@Override
public void dispose() {
Logger.info("App", "Dispose");
tray.removeTray();
}

public boolean canChangeStage() {
Expand Down
65 changes: 57 additions & 8 deletions core/src/cn/harryh/arkpets/ArkTray.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import static cn.harryh.arkpets.Const.fontFileRegular;
import static cn.harryh.arkpets.Const.linearEasingDuration;
import static cn.harryh.arkpets.Const.*;


public class ArkTray extends Tray {
Expand All @@ -29,6 +32,7 @@ public class ArkTray extends Tray {
public static Font font;
private final JDialog popWindow;
private final JPopupMenu popMenu;
private final boolean[] button = {false, false};

static {
try {
Expand Down Expand Up @@ -65,7 +69,31 @@ public void firePopupMenuWillBecomeInvisible() {
};
name = (arkPets.config.character_label == null || arkPets.config.character_label.isEmpty()) ? "Unknown" : arkPets.config.character_label;
socketClient.connect(socketData -> {
if (socketData == null || socketData.uuid.compareTo(uuid) != 0)
if (socketData == null) {
Image image = Toolkit.getDefaultToolkit().createImage(getClass().getResource(iconFilePng));
TrayIcon icon = getTrayIcon(image);

// Add the icon to the system tray.
try {
SystemTray.getSystemTray().add(icon);
Logger.info("Tray", "Tray icon applied");
} catch (AWTException e) {
Logger.error("Tray", "Unable to apply tray icon, details see below", e);
}
socketClient.disconnect();
socketClient.reconnect(() -> {
SystemTray.getSystemTray().remove(icon);
socketClient.sendRequest(new SocketData(this.uuid, SocketData.OperateType.LOGIN, name, arkPets.canChangeStage()));
if (button[0]) {
socketClient.sendRequest(new SocketData(this.uuid, SocketData.OperateType.KEEP_ACTION));
}
if (button[1]) {
socketClient.sendRequest(new SocketData(this.uuid, SocketData.OperateType.TRANSPARENT_MODE));
}
});
return;
}
if (socketData.uuid.compareTo(uuid) != 0)
return;
switch (socketData.operateType) {
case LOGOUT -> optExitHandler();
Expand All @@ -80,6 +108,22 @@ public void firePopupMenuWillBecomeInvisible() {
addComponent();
}

private TrayIcon getTrayIcon(Image image) {
TrayIcon icon = new TrayIcon(image, name);
icon.setImageAutoSize(true);
icon.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() == 3 && e.isPopupTrigger()) {
// After right-click on the tray icon.
int x = e.getX();
int y = e.getY();
showDialog(x + 5, y);
}
}
});
return icon;
}

@Override
protected void addComponent() {
Expand Down Expand Up @@ -109,11 +153,12 @@ protected void optExitHandler() {
Logger.info("Tray", "Request to exit");
arkPets.windowAlpha.reset(0f);
removeTray();
try {
Thread.sleep((long) (linearEasingDuration * 1000));
Gdx.app.exit();
} catch (InterruptedException ignored) {
}
new Timer().schedule(new TimerTask() {
@Override
public void run() {
Gdx.app.exit();
}
}, (int) (linearEasingDuration * 1000));
}

@Override
Expand All @@ -130,6 +175,7 @@ protected void optChangeStageHandler() {
@Override
protected void optTransparentDisHandler() {
Logger.info("Tray", "Transparent disabled");
button[1] = false;
arkPets.windowAlpha.reset(1f);
arkPets.hWndMine.setWindowTransparent(false);
popMenu.remove(optTransparentDis);
Expand All @@ -139,6 +185,7 @@ protected void optTransparentDisHandler() {
@Override
protected void optTransparentEnHandler() {
Logger.info("Tray", "Transparent enabled");
button[1] = true;
arkPets.windowAlpha.reset(0.75f);
arkPets.hWndMine.setWindowTransparent(true);
popMenu.remove(optTransparentEn);
Expand All @@ -148,6 +195,7 @@ protected void optTransparentEnHandler() {
@Override
protected void optKeepAnimDisHandler() {
Logger.info("Tray", "Keep-Anim disabled");
button[0] = false;
keepAnim = null;
popMenu.remove(optKeepAnimDis);
popMenu.add(optKeepAnimEn, 1);
Expand All @@ -156,6 +204,7 @@ protected void optKeepAnimDisHandler() {
@Override
protected void optKeepAnimEnHandler() {
Logger.info("Tray", "Keep-Anim enabled");
button[0] = true;
keepAnim = arkPets.cha.getPlaying();
popMenu.remove(optKeepAnimEn);
popMenu.add(optKeepAnimDis, 1);
Expand Down
4 changes: 4 additions & 0 deletions core/src/cn/harryh/arkpets/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,8 @@ public static class LogConfig {
public static final String debugArg = "--debug";
}

// SocketServer Ports

public static final int[] serverPorts = {8686, 8866, 8989, 8899, 8800};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package cn.harryh.arkpets.exception;

public class NoPortAvailableException extends Exception {
public NoPortAvailableException() {
super("No port available");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package cn.harryh.arkpets.exception;

public class NoServerRunningException extends Exception {
public NoServerRunningException() {
super("Can not find a running server");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package cn.harryh.arkpets.exception;

public class ServerRunningException extends Exception {
public ServerRunningException() {
super("Server is already running");
}
}
20 changes: 15 additions & 5 deletions core/src/cn/harryh/arkpets/process_pool/ProcessPool.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package cn.harryh.arkpets.process_pool;

import cn.harryh.arkpets.socket.InteriorSocketServer;

import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;


public class ProcessPool {
private final Set<ProcessHolder> processHolderHashSet = new HashSet<>();
private final java.util.concurrent.ExecutorService executorService;
private final java.util.concurrent.ExecutorService executorService = InteriorSocketServer.getThreadPool();
private static ProcessPool instance = null;

public static ProcessPool getInstance() {
if (instance == null)
instance = new ProcessPool();
return instance;
}

public ProcessPool() {
this.executorService = Executors.newFixedThreadPool(10);
private ProcessPool() {
}

public void shutdown() {
processHolderHashSet.forEach(processHolder -> processHolder.getProcess().destroy());
executorService.shutdown();
}

public Future<?> submit(Runnable task) {
Expand Down
6 changes: 0 additions & 6 deletions core/src/cn/harryh/arkpets/process_pool/Status.java

This file was deleted.

6 changes: 6 additions & 0 deletions core/src/cn/harryh/arkpets/process_pool/TaskStatus.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package cn.harryh.arkpets.process_pool;

public class TaskStatus {

public enum Status {
SUCCESS,
FAILURE
}

private final Status status;
private final Throwable exception;
private final Long processId;
Expand Down
63 changes: 44 additions & 19 deletions core/src/cn/harryh/arkpets/socket/InteriorSocketServer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.harryh.arkpets.socket;

import cn.harryh.arkpets.ArkConfig;
import cn.harryh.arkpets.exception.NoPortAvailableException;
import cn.harryh.arkpets.exception.ServerRunningException;
import cn.harryh.arkpets.tray.ClientTrayHandler;
import cn.harryh.arkpets.utils.Logger;

Expand All @@ -9,11 +10,14 @@
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

import static cn.harryh.arkpets.utils.IOUtils.NetUtils.getAvailablePort;


public class InteriorSocketServer {
private final int port;
private int port;
private boolean checked = false;
private static final List<Socket> clientSockets = new ArrayList<>();
private static final List<ClientTrayHandler> clientHandlers = new ArrayList<>();
private static final ExecutorService executorService =
Expand All @@ -24,57 +28,78 @@ public class InteriorSocketServer {
thread.setDaemon(true);
return thread;
});
private ServerSocket serverSocket;
private static volatile boolean mainThreadExitFlag = false;
private ServerSocket serverSocket = null;
private static Thread mainThread;
private static InteriorSocketServer instance = null;

public static ExecutorService getThreadPool() {
return executorService;
}

public static InteriorSocketServer getInstance() {
if (instance == null)
if (instance == null) {
instance = new InteriorSocketServer();
}
return instance;
}

public int checkServerAvailable() {
try {
this.port = getAvailablePort();
checked = true;
return 1;
} catch (NoPortAvailableException e) {
return 0;
} catch (ServerRunningException e) {
return -1;
}
}

private InteriorSocketServer() {
this.port = Objects.requireNonNull(ArkConfig.getConfig()).server_port;
}

public synchronized void startServer() {
executorService.execute(() -> {
if (!checked)
return;
mainThread = new Thread(() -> {
try {
serverSocket = new ServerSocket(port);
Logger.info("Socket", "Server is running on port " + port);
while (!mainThreadExitFlag) {
while (true) {
Socket clientSocket = serverSocket.accept();
clientSockets.add(clientSocket);
Logger.info("Socket", "New client connection from %s:%d".formatted(clientSocket.getInetAddress().getHostAddress(), clientSocket.getPort()));
ClientTrayHandler clientTrayHandler = new ClientTrayHandler(clientSocket);
clientHandlers.add(clientTrayHandler);
if (executorService.isShutdown())
break;
executorService.execute(clientTrayHandler);
}
Logger.info("Socket", "Server stop");
} catch (IOException e) {
throw new RuntimeException(e);
}
});
executorService.execute(mainThread);
}

public synchronized void stopServer() {
mainThreadExitFlag = true;
clientSockets.forEach(socket -> {
try {
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
if (!(Objects.requireNonNull(ArkConfig.getConfig()).separate_arkpet_from_launcher))
clientHandlers.forEach(ClientTrayHandler::stopThread);
if (!checked)
return;
mainThread.interrupt();
clientHandlers.forEach(ClientTrayHandler::stopThread);
executorService.shutdown();
}

public void removeClientSocket(Socket socket) {
if (!checked)
return;
clientSockets.remove(socket);
}

public void removeClientHandler(ClientTrayHandler handler) {
if (!checked)
return;
clientHandlers.remove(handler);
}

Expand Down
Loading
Loading