server

Clone or download

Optimised Client/Server Settings Sync

Modified Files

package com.stream_pi.server.connection;
package com.stream_pi.server.connection;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.action_api.actionproperty.ClientProperties;
import com.stream_pi.action_api.actionproperty.ClientProperties;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.ExternalPlugin;
import com.stream_pi.action_api.externalplugin.ExternalPlugin;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.otheractions.CombineAction;
import com.stream_pi.action_api.otheractions.CombineAction;
import com.stream_pi.action_api.otheractions.FolderAction;
import com.stream_pi.action_api.otheractions.FolderAction;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientTheme;
import com.stream_pi.server.client.ClientTheme;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.comms.Message;
import com.stream_pi.util.comms.Message;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.ReleaseStatus;
import com.stream_pi.util.platform.ReleaseStatus;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.version.Version;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import java.io.*;
import java.io.*;
import java.net.Socket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.Logger;
public class ClientConnection extends Thread
public class ClientConnection extends Thread
{
{
private Socket socket;
private Socket socket;
private ServerListener serverListener;
private ServerListener serverListener;
private AtomicBoolean stop = new AtomicBoolean(false);
private AtomicBoolean stop = new AtomicBoolean(false);
private ObjectOutputStream oos;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private ObjectInputStream ois;
private Logger logger;
private Logger logger;
private Client client = null;
private Client client = null;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
public ClientConnection(Socket socket, ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
public ClientConnection(Socket socket, ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
{
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.socket = socket;
this.socket = socket;
this.serverListener = serverListener;
this.serverListener = serverListener;
logger = Logger.getLogger(ClientConnection.class.getName());
logger = Logger.getLogger(ClientConnection.class.getName());
try
try
{
{
oos = new ObjectOutputStream(socket.getOutputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
} catch (IOException e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException("Unable to start socket streams"));
exceptionAndAlertHandler.handleMinorException(new MinorException("Unable to start socket streams"));
}
}
start();
start();
}
}
public synchronized void exit()
public synchronized void exit()
{
{
if(stop.get())
if(stop.get())
return;
return;
logger.info("Stopping ...");
logger.info("Stopping ...");
try
try
{
{
if(socket !=null)
if(socket !=null)
{
{
logger.info("Stopping connection "+getRemoteSocketAddress());
logger.info("Stopping connection "+getRemoteSocketAddress());
disconnect();
disconnect();
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
}
}
public SocketAddress getRemoteSocketAddress()
public SocketAddress getRemoteSocketAddress()
{
{
return socket.getRemoteSocketAddress();
return socket.getRemoteSocketAddress();
}
}
public synchronized void exitAndRemove()
public synchronized void exitAndRemove()
{
{
exit();
exit();
callOnClientDisconnectOnAllActions();
callOnClientDisconnectOnAllActions();
removeConnection();
removeConnection();
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public void callOnClientDisconnectOnAllActions()
public void callOnClientDisconnectOnAllActions()
{
{
for(ClientProfile profile : getClient().getAllClientProfiles())
for(ClientProfile profile : getClient().getAllClientProfiles())
{
{
for (String actionID : profile.getActionsKeySet())
for (String actionID : profile.getActionsKeySet())
{
{
Action action = profile.getActionByID(actionID);
Action action = profile.getActionByID(actionID);
if(action instanceof ExternalPlugin)
if(action instanceof ExternalPlugin)
{
{
try
try
{
{
((ExternalPlugin) action).onClientDisconnected();
((ExternalPlugin) action).onClientDisconnected();
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(
exceptionAndAlertHandler.handleMinorException(
new MinorException(
new MinorException(
"Unable to run onClientDisconnected for "+action.getModuleName(),
"Unable to run onClientDisconnected for "+action.getModuleName(),
"Detailed message : "+e.getMessage()
"Detailed message : "+e.getMessage()
)
)
);
);
}
}
}
}
}
}
}
}
}
}
public void removeConnection()
public void removeConnection()
{
{
ClientConnections.getInstance().removeConnection(this);
ClientConnections.getInstance().removeConnection(this);
}
}
public void sendIcon(String profileID, String actionID, String state, byte[] icon) throws SevereException
public void sendIcon(String profileID, String actionID, String state, byte[] icon) throws SevereException
{
{
try
try
{
{
Thread.sleep(50);
Thread.sleep(50);
}
}
catch (InterruptedException e)
catch (InterruptedException e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
Message message = new Message("action_icon");
Message message = new Message("action_icon");
message.setStringArrValue(profileID, actionID, state);
message.setStringArrValue(profileID, actionID, state);
message.setByteArrValue(icon);
message.setByteArrValue(icon);
sendMessage(message);
sendMessage(message);
}
}
public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
{
{
String[] ar = message.getStringArrValue();
String[] ar = message.getStringArrValue();
logger.info("Setting up client object ...");
logger.info("Setting up client object ...");
Version clientVersion;
Version clientVersion;
Version commsStandard;
Version commsStandard;
Version themesStandard;
Version themesStandard;
ReleaseStatus releaseStatus;
ReleaseStatus releaseStatus;
try
try
{
{
clientVersion = new Version(ar[0]);
clientVersion = new Version(ar[0]);
releaseStatus = ReleaseStatus.valueOf(ar[1]);
releaseStatus = ReleaseStatus.valueOf(ar[1]);
commsStandard = new Version(ar[2]);
commsStandard = new Version(ar[2]);
themesStandard = new Version(ar[3]);
themesStandard = new Version(ar[3]);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
exitAndRemove();
exitAndRemove();
throw new MinorException(e.getShortMessage()+" (client '"+socket.getRemoteSocketAddress()+"' )");
throw new MinorException(e.getShortMessage()+" (client '"+socket.getRemoteSocketAddress()+"' )");
}
}
if(!commsStandard.isEqual(ServerInfo.getInstance().getCommStandardVersion()))
if(!commsStandard.isEqual(ServerInfo.getInstance().getCommStandardVersion()))
{
{
String errTxt = "Server and client Communication standards do not match. Make sure you are on the latest version of server and client.\n" +
String errTxt = "Server and client Communication standards do not match. Make sure you are on the latest version of server and client.\n" +
"Server Comms. Standard : "+ServerInfo.getInstance().getCommStandardVersion().getText()+
"Server Comms. Standard : "+ServerInfo.getInstance().getCommStandardVersion().getText()+
"\nclient Comms. Standard : "+commsStandard.getText();
"\nclient Comms. Standard : "+commsStandard.getText();
disconnect(errTxt);
disconnect(errTxt);
throw new MinorException(errTxt);
throw new MinorException(errTxt);
}
}
client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
client.setDisplayWidth(Double.parseDouble(ar[5]));
client.setDisplayWidth(Double.parseDouble(ar[5]));
client.setDisplayHeight(Double.parseDouble(ar[6]));
client.setDisplayHeight(Double.parseDouble(ar[6]));
client.setDefaultProfileID(ar[8]);
client.setDefaultProfileID(ar[8]);
client.setDefaultThemeFullName(ar[9]);
client.setDefaultThemeFullName(ar[9]);
//call get profiles command.
//call get profiles command.
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public void updateClientDetails(Message message)
{
String[] ar = message.getStringArrValue();
logger.info("Setting up client object ...");
client.setNickName(ar[4]);
client.setDisplayWidth(Double.parseDouble(ar[5]));
client.setDisplayHeight(Double.parseDouble(ar[6]));
client.setDefaultProfileID(ar[8]);
client.setDefaultThemeFullName(ar[9]);
serverListener.getSettingsBase().getClientsSettings().loadData();
}
public synchronized Client getClient()
public synchronized Client getClient()
{
{
return client;
return client;
}
}
@Override
@Override
public void run() {
public void run() {
try {
try {
initAfterConnectionQuerySend();
initAfterConnectionQuerySend();
} catch (SevereException e) {
} catch (SevereException e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
exitAndRemove();
exitAndRemove();
return;
return;
}
}
try
try
{
{
while(!stop.get())
while(!stop.get())
{
{
try
try
{
{
Message message = (Message) ois.readObject();
Message message = (Message) ois.readObject();
String header = message.getHeader();
String header = message.getHeader();
switch (header)
switch (header)
{
{
case "action_icon" : onActionIconReceived(message);
case "action_icon" : onActionIconReceived(message);
break;
break;
case "disconnect" : clientDisconnected(message);
case "disconnect" : clientDisconnected(message);
break;
break;
case "client_details" : initAfterConnectionQueryReceive(message);
case "register_client_details" : initAfterConnectionQueryReceive(message);
getProfilesFromClient();
getProfilesFromClient();
getThemesFromClient();
getThemesFromClient();
break;
break;
case "update_client_details" : updateClientDetails(message);
break;
case "client_screen_details" : onClientScreenDetailsReceived(message);
case "client_screen_details" : onClientScreenDetailsReceived(message);
break;
break;
case "profiles" : registerProfilesFromClient(message);
case "profiles" : registerProfilesFromClient(message);
break;
break;
case "profile_details" : registerProfileDetailsFromClient(message);
case "profile_details" : registerProfileDetailsFromClient(message);
break;
break;
case "action_details" : registerActionToProfile(message);
case "action_details" : registerActionToProfile(message);
break;
break;
case "themes": registerThemes(message);
case "themes": registerThemes(message);
break;
break;
case "action_clicked": onActionClicked(message);
case "action_clicked": onActionClicked(message);
break;
break;
default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
}
}
}
}
catch (IOException | ClassNotFoundException e)
catch (IOException | ClassNotFoundException e)
{
{
logger.log(Level.SEVERE, e.getMessage());
logger.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
e.printStackTrace();
serverListener.clearTemp();
serverListener.clearTemp();
if(!stop.get())
if(!stop.get())
{
{
removeConnection();
removeConnection();
throw new MinorException("Accidentally disconnected from "+getClient().getNickName()+".");
throw new MinorException("Accidentally disconnected from "+getClient().getNickName()+".");
}
}
exitAndRemove();
exitAndRemove();
return;
return;
}
}
}
}
}
}
catch (StreamPiException e)
catch (StreamPiException e)
{
{
e.printStackTrace();
e.printStackTrace();
if(e instanceof MinorException)
if(e instanceof MinorException)
exceptionAndAlertHandler.handleMinorException((MinorException) e);
exceptionAndAlertHandler.handleMinorException((MinorException) e);
else if (e instanceof SevereException)
else if (e instanceof SevereException)
exceptionAndAlertHandler.handleSevereException((SevereException) e);
exceptionAndAlertHandler.handleSevereException((SevereException) e);
}
}
}
}
// commands
// commands
private void onActionIconReceived(Message message) throws MinorException
private void onActionIconReceived(Message message) throws MinorException
{
{
String[] s = message.getStringArrValue();
String[] s = message.getStringArrValue();
String profileID = s[0];
String profileID = s[0];
String actionID = s[1];
String actionID = s[1];
String iconState = s[2];
String iconState = s[2];
getClient()
getClient()
.getProfileByID(profileID)
.getProfileByID(profileID)
.getActionByID(actionID)
.getActionByID(actionID)
.addIcon(iconState,message.getByteArrValue());
.addIcon(iconState,message.getByteArrValue());
}
}
public void initAfterConnectionQuerySend() throws SevereException
public void initAfterConnectionQuerySend() throws SevereException
{
{
logger.info("Asking client details ...");
logger.info("Asking client details ...");
sendMessage(new Message("get_client_details"));
sendMessage(new Message("get_client_details"));
}
}
public void disconnect() throws SevereException {
public void disconnect() throws SevereException {
disconnect("");
disconnect("");
}
}
public void disconnect(String message) throws SevereException {
public void disconnect(String message) throws SevereException {
if(stop.get())
if(stop.get())
return;
return;
stop.set(true);
stop.set(true);
logger.info("Sending client disconnect message ...");
logger.info("Sending client disconnect message ...");
Message m = new Message("disconnect");
Message m = new Message("disconnect");
m.setStringValue(message);
m.setStringValue(message);
sendMessage(m);
sendMessage(m);
try
try
{
{
if(!socket.isClosed())
if(!socket.isClosed())
socket.close();
socket.close();
}
}
catch (IOException e)
catch (IOException e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException("Unable to close socket");
throw new SevereException("Unable to close socket");
}
}
}
}
public synchronized void sendMessage(Message message) throws SevereException
public synchronized void sendMessage(Message message) throws SevereException
{
{
try
try
{
{
oos.writeObject(message);
oos.writeObject(message);
oos.flush();
oos.flush();
}
}
catch (IOException e)
catch (IOException e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
throw new SevereException("Unable to write to io Stream!");
}
}
}
}
public void clientDisconnected(Message message)
public void clientDisconnected(Message message)
{
{
stop.set(true);
stop.set(true);
String txt = "Disconnected!";
String txt = "Disconnected!";
String msg = message.getStringValue();
String msg = message.getStringValue();
if(!msg.isBlank())
if(!msg.isBlank())
txt = "Message : "+msg;
txt = "Message : "+msg;
new StreamPiAlert("Disconnected from "+getClient().getNickName()+".", txt, StreamPiAlertType.WARNING).show();;
new StreamPiAlert("Disconnected from "+getClient().getNickName()+".", txt, StreamPiAlertType.WARNING).show();;
exitAndRemove();
exitAndRemove();
}
}
public void getProfilesFromClient() throws StreamPiException
public void getProfilesFromClient() throws StreamPiException
{
{
logger.info("Asking client to send profiles ...");
logger.info("Asking client to send profiles ...");
sendMessage(new Message("get_profiles"));
sendMessage(new Message("get_profiles"));
}
}
public void getThemesFromClient() throws StreamPiException
public void getThemesFromClient() throws StreamPiException
{
{
logger.info("Asking clients to send themes ...");
logger.info("Asking clients to send themes ...");
sendMessage(new Message("get_themes"));
sendMessage(new Message("get_themes"));
}
}
public void registerThemes(Message message)
public void registerThemes(Message message)
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
for(int i =0; i<(r.length);i+=4)
for(int i =0; i<(r.length);i+=4)
{
{
ClientTheme clientTheme = new ClientTheme(
ClientTheme clientTheme = new ClientTheme(
r[i],
r[i],
r[i+1],
r[i+1],
r[i+2],
r[i+2],
r[i+3]
r[i+3]
);
);
try
try
{
{
getClient().addTheme(clientTheme);
getClient().addTheme(clientTheme);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
logger.log(Level.SEVERE, e.getMessage());
logger.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
e.printStackTrace();
}
}
}
}
}
}
public void registerProfilesFromClient(Message message) throws StreamPiException
public void registerProfilesFromClient(Message message) throws StreamPiException
{
{
logger.info("Registering profiles ...");
logger.info("Registering profiles ...");
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
for (String profileID : r) {
for (String profileID : r) {
getProfileDetailsFromClient(profileID);
getProfileDetailsFromClient(profileID);
}
}
}
}
public void getProfileDetailsFromClient(String ID) throws StreamPiException
public void getProfileDetailsFromClient(String ID) throws StreamPiException
{
{
logger.info("Asking client to send details of profile : "+ID);
logger.info("Asking client to send details of profile : "+ID);
Message message = new Message("get_profile_details");
Message message = new Message("get_profile_details");
message.setStringValue(ID);
message.setStringValue(ID);
sendMessage(message);
sendMessage(message);
}
}
public void registerProfileDetailsFromClient(Message message)
public void registerProfileDetailsFromClient(Message message)
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String ID = r[0];
String ID = r[0];
logger.info("Registering details for profile : "+ID);
logger.info("Registering details for profile : "+ID);
String name = r[1];
String name = r[1];
int rows = Integer.parseInt(r[2]);
int rows = Integer.parseInt(r[2]);
int cols = Integer.parseInt(r[3]);
int cols = Integer.parseInt(r[3]);
int actionSize = Integer.parseInt(r[4]);
int actionSize = Integer.parseInt(r[4]);
int actionGap = Integer.parseInt(r[5]);
int actionGap = Integer.parseInt(r[5]);
ClientProfile clientProfile = new ClientProfile(name, ID, rows, cols, actionSize, actionGap);
ClientProfile clientProfile = new ClientProfile(name, ID, rows, cols, actionSize, actionGap);
logger.info("Added client profile "+clientProfile.getName());
logger.info("Added client profile "+clientProfile.getName());
try
try
{
{
getClient().addProfile(clientProfile);
getClient().addProfile(clientProfile);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
logger.severe(e.getMessage());
logger.severe(e.getMessage());
e.printStackTrace();
e.printStackTrace();
}
}
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public synchronized void registerActionToProfile(Message message) throws StreamPiException
public synchronized void registerActionToProfile(Message message) throws StreamPiException
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String profileID = r[0];
String profileID = r[0];
String ID = r[1];
String ID = r[1];
ActionType actionType = ActionType.valueOf(r[2]);
ActionType actionType = ActionType.valueOf(r[2]);
//3 - Version
//3 - Version
//4 - ModuleName
//4 - ModuleName
//display
//display
String bgColorHex = r[5];
String bgColorHex = r[5];
//icon
//icon
String[] allIconStateNames = r[6].split("::");
String[] allIconStateNames = r[6].split("::");
String defaultIconState = r[7];
String defaultIconState = r[7];
//text
//text
boolean isShowDisplayText = r[8].equals("true");
boolean isShowDisplayText = r[8].equals("true");
String displayFontColor = r[9];
String displayFontColor = r[9];
String displayText = r[10];
String displayText = r[10];
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
//location
//location
String row = r[12];
String row = r[12];
String col = r[13];
String col = r[13];
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
String root = r[14];
String root = r[14];
int delayBeforeRunning = Integer.parseInt(r[15]);
int delayBeforeRunning = Integer.parseInt(r[15]);
//client properties
//client properties
int clientPropertiesSize = Integer.parseInt(r[16]);
int clientPropertiesSize = Integer.parseInt(r[16]);
ClientProperties clientProperties = new ClientProperties();
ClientProperties clientProperties = new ClientProperties();
if(actionType == ActionType.FOLDER)
if(actionType == ActionType.FOLDER)
clientProperties.setDuplicatePropertyAllowed(true);
clientProperties.setDuplicatePropertyAllowed(true);
for(int i = 17;i<((clientPropertiesSize*2) + 17); i+=2)
for(int i = 17;i<((clientPropertiesSize*2) + 17); i+=2)
{
{
Property property = new Property(r[i], Type.STRING);
Property property = new Property(r[i], Type.STRING);
property.setRawValue(r[i+1]);
property.setRawValue(r[i+1]);
clientProperties.addProperty(property);
clientProperties.addProperty(property);
}
}
//set up action
//set up action
//action toBeAdded = null;
//action toBeAdded = null;
boolean isInvalidAction = false;
boolean isInvalidAction = false;
if(actionType == ActionType.NORMAL || actionType == ActionType.TOGGLE)
if(actionType == ActionType.NORMAL || actionType == ActionType.TOGGLE)
{
{
String moduleName = r[4];
String moduleName = r[4];
Version version = new Version(r[3]);
Version version = new Version(r[3]);
ExternalPlugin originalAction = ExternalPlugins.getInstance().getPluginByModuleName(moduleName);
ExternalPlugin originalAction = ExternalPlugins.getInstance().getPluginByModuleName(moduleName);
if(originalAction == null)
if(originalAction == null)
{
{
isInvalidAction = true;
isInvalidAction = true;
}
}
else
else
{
{
if(originalAction.getVersion().getMajor() != version.getMajor())
if(originalAction.getVersion().getMajor() != version.getMajor())
{
{
isInvalidAction = true;
isInvalidAction = true;
}
}
else
else
{
{
try
try
{
{
ExternalPlugin newPlugin = originalAction.clone();
ExternalPlugin newPlugin = originalAction.clone();
newPlugin.setID(ID);
newPlugin.setID(ID);
System.out.println("SAVVEEEEEEEEEEEEEEE@@@@@ : "+profileID);
System.out.println("SAVVEEEEEEEEEEEEEEE@@@@@ : "+profileID);
newPlugin.setProfileID(profileID);
newPlugin.setProfileID(profileID);
newPlugin.setSocketAddressForClient(socket.getRemoteSocketAddress());
newPlugin.setSocketAddressForClient(socket.getRemoteSocketAddress());
newPlugin.setBgColourHex(bgColorHex);
newPlugin.setBgColourHex(bgColorHex);
newPlugin.setCurrentIconState(defaultIconState);
newPlugin.setCurrentIconState(defaultIconState);
newPlugin.setShowDisplayText(isShowDisplayText);
newPlugin.setShowDisplayText(isShowDisplayText);
newPlugin.setDisplayTextFontColourHex(displayFontColor);
newPlugin.setDisplayTextFontColourHex(displayFontColor);
newPlugin.setDisplayText(displayText);
newPlugin.setDisplayText(displayText);
newPlugin.setDisplayTextAlignment(displayTextAlignment);
newPlugin.setDisplayTextAlignment(displayTextAlignment);
newPlugin.setLocation(location);
newPlugin.setLocation(location);
newPlugin.setParent(root);
newPlugin.setParent(root);
newPlugin.setDelayBeforeExecuting(delayBeforeRunning);
newPlugin.setDelayBeforeExecuting(delayBeforeRunning);
ClientProperties finalClientProperties = new ClientProperties();
ClientProperties finalClientProperties = new ClientProperties();
for(Property property : originalAction.getClientProperties().get())
for(Property property : originalAction.getClientProperties().get())
{
{
for(int i = 0;i<clientProperties.getSize();i++)
for(int i = 0;i<clientProperties.getSize();i++)
{
{
Property property1 = clientProperties.get().get(i);
Property property1 = clientProperties.get().get(i);
if (property.getName().equals(property1.getName()))
if (property.getName().equals(property1.getName()))
{
{
property.setRawValue(property1.getRawValue());
property.setRawValue(property1.getRawValue());
finalClientProperties.addProperty(property);
finalClientProperties.addProperty(property);
}
}
}
}
}
}
newPlugin.setClientProperties(finalClientProperties);
newPlugin.setClientProperties(finalClientProperties);
getClient().getProfileByID(profileID).addAction(newPlugin);
getClient().getProfileByID(profileID).addAction(newPlugin);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
}
}
return;
return;
}
}
}
}
}
}
Action action = null;
Action action = null;
if(isInvalidAction)
if(isInvalidAction)
{
{
String moduleName = r[4];
String moduleName = r[4];
Version version = new Version(r[3]);
Version version = new Version(r[3]);
action = new Action();
action = new Action();
action.setInvalid(true);
action.setInvalid(true);
action.setVersion(version);
action.setVersion(version);
action.setModuleName(moduleName);
action.setModuleName(moduleName);
}
}
else
else
{
{
if(actionType == ActionType.COMBINE)
if(actionType == ActionType.COMBINE)
{
{
action = new CombineAction();
action = new CombineAction();
}
}
else if(actionType == ActionType.FOLDER)
else if(actionType == ActionType.FOLDER)
{
{
action = new FolderAction();
action = new FolderAction();
}
}
}
}
action.setID(ID);
action.setID(ID);
action.setProfileID(profileID);
action.setProfileID(profileID);
action.setSocketAddressForClient(socket.getRemoteSocketAddress());
action.setSocketAddressForClient(socket.getRemoteSocketAddress());
action.setBgColourHex(bgColorHex);
action.setBgColourHex(bgColorHex);
action.setCurrentIconState(defaultIconState);
action.setCurrentIconState(defaultIconState);
action.setShowDisplayText(isShowDisplayText);
action.setShowDisplayText(isShowDisplayText);
action.setDisplayTextFontColourHex(displayFontColor);
action.setDisplayTextFontColourHex(displayFontColor);
action.setDisplayText(displayText);
action.setDisplayText(displayText);
action.setDisplayTextAlignment(displayTextAlignment);
action.setDisplayTextAlignment(displayTextAlignment);
action.setLocation(location);
action.setLocation(location);
action.setParent(root);
action.setParent(root);
action.setClientProperties(clientProperties);
action.setClientProperties(clientProperties);
try
try
{
{
getClient().getProfileByID(profileID).addAction(action);
getClient().getProfileByID(profileID).addAction(action);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
}
}
}
}
public synchronized void saveActionDetails(String profileID, Action action) throws SevereException
public synchronized void saveActionDetails(String profileID, Action action) throws SevereException
{
{
ArrayList<String> a = new ArrayList<>();
ArrayList<String> a = new ArrayList<>();
a.add(profileID);
a.add(profileID);
a.add(action.getID());
a.add(action.getID());
a.add(action.getActionType()+"");
a.add(action.getActionType()+"");
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
{
a.add(action.getVersion().getText());
a.add(action.getVersion().getText());
System.out.println("VERSION :sdd "+action.getVersion().getText());
System.out.println("VERSION :sdd "+action.getVersion().getText());
}
}
else
else
{
{
a.add("no");
a.add("no");
}
}
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
{
a.add(action.getModuleName());
a.add(action.getModuleName());
}
}
else
else
{
{
a.add("nut");
a.add("nut");
}
}
//display
//display
a.add(action.getBgColourHex());
a.add(action.getBgColourHex());
//icon
//icon
StringBuilder allIconStatesNames = new StringBuilder();
StringBuilder allIconStatesNames = new StringBuilder();
for(String eachState : action.getIcons().keySet())
for(String eachState : action.getIcons().keySet())
{
{
allIconStatesNames.append(eachState).append("::");
allIconStatesNames.append(eachState).append("::");
}
}
a.add(allIconStatesNames.toString());
a.add(allIconStatesNames.toString());
a.add(action.getCurrentIconState());
a.add(action.getCurrentIconState());
//text
//text
a.add(action.isShowDisplayText()+"");
a.add(action.isShowDisplayText()+"");
a.add(action.getDisplayTextFontColourHex());
a.add(action.getDisplayTextFontColourHex());
a.add(action.getDisplayText());
a.add(action.getDisplayText());
a.add(action.getDisplayTextAlignment()+"");
a.add(action.getDisplayTextAlignment()+"");
//location
//location
if(action.getLocation() == null)
if(action.getLocation() == null)
{
{
a.add("-1");
a.add("-1");
a.add("-1");
a.add("-1");
}
}
else
else
{
{
a.add(action.getLocation().getRow()+"");
a.add(action.getLocation().getRow()+"");
a.add(action.getLocation().getCol()+"");
a.add(action.getLocation().getCol()+"");
}
}
a.add(action.getParent());
a.add(action.getParent());
a.add(action.getDelayBeforeExecuting()+"");
a.add(action.getDelayBeforeExecuting()+"");
//client properties
//client properties
ClientProperties clientProperties = action.getClientProperties();
ClientProperties clientProperties = action.getClientProperties();
a.add(clientProperties.getSize()+"");
a.add(clientProperties.getSize()+"");
for(Property property : clientProperties.get())
for(Property property : clientProperties.get())
{
{
a.add(property.getName());
a.add(property.getName());
a.add(property.getRawValue());
a.add(property.getRawValue());
}
}
Message message = new Message("save_action_details");
Message message = new Message("save_action_details");
String[] x = new String[a.size()];
String[] x = new String[a.size()];
x = a.toArray(x);
x = a.toArray(x);
message.setStringArrValue(x);
message.setStringArrValue(x);
sendMessage(message);
sendMessage(message);
}
}
public void getClientScreenDetails() throws SevereException
public void getClientScreenDetails() throws SevereException
{
{
Message message = new Message("get_client_screen_details");
Message message = new Message("get_client_screen_details");
sendMessage(message);
sendMessage(message);
}
}
public void onClientScreenDetailsReceived(Message message)
public void onClientScreenDetailsReceived(Message message)
{
{
double width = Double.parseDouble(message.getStringArrValue()[0]);
double width = Double.parseDouble(message.getStringArrValue()[0]);
double height = Double.parseDouble(message.getStringArrValue()[1]);
double height = Double.parseDouble(message.getStringArrValue()[1]);
getClient().setDisplayWidth(width);
getClient().setDisplayWidth(width);
getClient().setDisplayHeight(height);
getClient().setDisplayHeight(height);
}
}
public void deleteAction(String profileID, String actionID) throws SevereException
public void deleteAction(String profileID, String actionID) throws SevereException
{
{
Message message = new Message("delete_action");
Message message = new Message("delete_action");
message.setStringArrValue(profileID, actionID);
message.setStringArrValue(profileID, actionID);
sendMessage(message);
sendMessage(message);
}
}
public void saveClientDetails(String clientNickname, String defaultProfileID,
public void saveClientDetails(String clientNickname, String defaultProfileID,
String defaultThemeFullName) throws SevereException
String defaultThemeFullName) throws SevereException
{
{
Message message = new Message("save_client_details");
Message message = new Message("save_client_details");
message.setStringArrValue(
message.setStringArrValue(
clientNickname,
clientNickname,
defaultProfileID,
defaultProfileID,
defaultThemeFullName
defaultThemeFullName
);
);
sendMessage(message);
sendMessage(message);
client.setNickName(clientNickname);
client.setNickName(clientNickname);
client.setDefaultProfileID(defaultProfileID);
client.setDefaultProfileID(defaultProfileID);
client.setDefaultThemeFullName(defaultThemeFullName);
client.setDefaultThemeFullName(defaultThemeFullName);
}
}
public void saveProfileDetails(ClientProfile clientProfile) throws SevereException, CloneNotSupportedException {
public void saveProfileDetails(ClientProfile clientProfile) throws SevereException, CloneNotSupportedException {
if(client.getProfileByID(clientProfile.getID()) !=null)
if(client.getProfileByID(clientProfile.getID()) !=null)
{
{
client.getProfileByID(clientProfile.getID()).setName(clientProfile.getName());
client.getProfileByID(clientProfile.getID()).setName(clientProfile.getName());
client.getProfileByID(clientProfile.getID()).setRows(clientProfile.getRows());
client.getProfileByID(clientProfile.getID()).setRows(clientProfile.getRows());
client.getProfileByID(clientProfile.getID()).setCols(clientProfile.getCols());
client.getProfileByID(clientProfile.getID()).setCols(clientProfile.getCols());
client.getProfileByID(clientProfile.getID()).setActionSize(clientProfile.getActionSize());
client.getProfileByID(clientProfile.getID()).setActionSize(clientProfile.getActionSize());
client.getProfileByID(clientProfile.getID()).setActionGap(clientProfile.getActionGap());
client.getProfileByID(clientProfile.getID()).setActionGap(clientProfile.getActionGap());
}
}
else
else
client.addProfile(clientProfile);
client.addProfile(clientProfile);
Message message = new Message("save_client_profile");
Message message = new Message("save_client_profile");
message.setStringArrValue(
message.setStringArrValue(
clientProfile.getID(),
clientProfile.getID(),
clientProfile.getName(),
clientProfile.getName(),
clientProfile.getRows()+"",
clientProfile.getRows()+"",
clientProfile.getCols()+"",
clientProfile.getCols()+"",
clientProfile.getActionSize()+"",
clientProfile.getActionSize()+"",
clientProfile.getActionGap()+""
clientProfile.getActionGap()+""
);
);
sendMessage(message);
sendMessage(message);
}
}
public void deleteProfile(String ID) throws SevereException
public void deleteProfile(String ID) throws SevereException
{
{
Message message = new Message("delete_profile");
Message message = new Message("delete_profile");
message.setStringValue(ID);
message.setStringValue(ID);
sendMessage(message);
sendMessage(message);
}
}
public void onActionClicked(Message message)
public void onActionClicked(Message message)
{
{
try
try
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String profileID = r[0];
String profileID = r[0];
String actionID = r[1];
String actionID = r[1];
boolean toggle = r[2].equals("true");
boolean toggle = r[2].equals("true");
Action action = client.getProfileByID(profileID).getActionByID(actionID);
Action action = client.getProfileByID(profileID).getActionByID(actionID);
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
{
if(action.isInvalid())
if(action.isInvalid())
{
{
throw new MinorException(
throw new MinorException(
"The action isn't installed on the server."
"The action isn't installed on the server."
);
);
}
}
else
else
{
{
if(action instanceof ToggleAction)
if(action instanceof ToggleAction)
{
{
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
boolean result = serverListener.onToggleActionClicked((ToggleAction) action, toggle, profileID);
boolean result = serverListener.onToggleActionClicked((ToggleAction) action, toggle, profileID);
if(!result)
if(!result)
{
{
sendActionFailed(profileID, actionID);
sendActionFailed(profileID, actionID);
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
return null;
return null;
}
}
}).start();
}).start();
}
}
else if(action instanceof NormalAction)
else if(action instanceof NormalAction)
{
{
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
boolean result = serverListener.onNormalActionClicked((NormalAction) action, profileID);
boolean result = serverListener.onNormalActionClicked((NormalAction) action, profileID);
if(!result)
if(!result)
{
{
sendActionFailed(profileID, actionID);
sendActionFailed(profileID, actionID);
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
return null;
return null;
}
}
}).start();
}).start();
}
}
}
}
}
}
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
}
}
}
}
public void sendActionFailed(String profileID, String actionID) throws SevereException {
public void sendActionFailed(String profileID, String actionID) throws SevereException {
logger.info("Sending failed status ...");
logger.info("Sending failed status ...");
Message message = new Message("action_failed");
Message message = new Message("action_failed");
message.setStringArrValue(profileID, actionID);
message.setStringArrValue(profileID, actionID);
sendMessage(message);
sendMessage(message);
}
}
}
}
package com.stream_pi.server.connection;
package com.stream_pi.server.connection;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.server.window.dashboard.ClientAndProfileSelectorPane;
import com.stream_pi.server.window.dashboard.ClientAndProfileSelectorPane;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.settings.SettingsBase;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import javafx.stage.Stage;
import javafx.stage.Stage;
public interface ServerListener
public interface ServerListener
{
{
boolean onNormalActionClicked(NormalAction action, String profileID);
boolean onNormalActionClicked(NormalAction action, String profileID);
boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID);
boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID);
void clearTemp();
void clearTemp();
void init();
void init();
void othInit();
void othInit();
Stage getStage();
Stage getStage();
DashboardBase getDashboardBase();
DashboardBase getDashboardBase();
SettingsBase getSettingsBase();
void initLogger() throws SevereException;
void initLogger() throws SevereException;
}
}
package com.stream_pi.server.controller;
package com.stream_pi.server.controller;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.server.Main;
import com.stream_pi.server.Main;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.connection.MainServer;
import com.stream_pi.server.connection.MainServer;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.window.Base;
import com.stream_pi.server.window.Base;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.dashboard.DonatePopupContent;
import com.stream_pi.server.window.dashboard.DonatePopupContent;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.server.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.server.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.server.window.settings.SettingsBase;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import javafx.animation.Animation;
import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.stage.WindowEvent;
import javafx.util.Duration;
import javafx.util.Duration;
import java.awt.MenuItem;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.TrayIcon;
import java.net.SocketAddress;
import java.net.SocketAddress;
import java.util.Random;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Level;
public class Controller extends Base implements PropertySaver, ServerConnection
public class Controller extends Base implements PropertySaver, ServerConnection
{
{
private ExecutorService executor = Executors.newCachedThreadPool();
private ExecutorService executor = Executors.newCachedThreadPool();
private MainServer mainServer;
private MainServer mainServer;
private Animation openSettingsAnimation;
private Animation openSettingsAnimation;
private Animation closeSettingsAnimation;
private Animation closeSettingsAnimation;
public Controller(){
public Controller(){
mainServer = null;
mainServer = null;
}
}
public void setupDashWindow() throws SevereException
public void setupDashWindow() throws SevereException
{
{
try
try
{
{
getStage().setOnCloseRequest(this::onCloseRequest);
getStage().setOnCloseRequest(this::onCloseRequest);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException(e.getMessage());
throw new SevereException(e.getMessage());
}
}
}
}
@Override
@Override
public void init()
public void init()
{
{
try {
try {
initBase();
initBase();
setupDashWindow();
setupDashWindow();
setupSettingsWindowsAnimations();
setupSettingsWindowsAnimations();
ExternalPlugins.getInstance().setPropertySaver(this);
ExternalPlugins.getInstance().setPropertySaver(this);
ExternalPlugins.getInstance().setServerConnection(this);
ExternalPlugins.getInstance().setServerConnection(this);
getDashboardPane().getPluginsPane().getSettingsButton().setOnAction(event -> {
getDashboardBase().getPluginsPane().getSettingsButton().setOnAction(event -> {
openSettingsAnimation.play();
openSettingsAnimation.play();
});
});
getSettingsPane().getCloseButton().setOnAction(event -> {
getSettingsBase().getCloseButton().setOnAction(event -> {
closeSettingsAnimation.play();
closeSettingsAnimation.play();
});
});
getSettingsPane().getThemesSettings().setController(this);
getSettingsBase().getThemesSettings().setController(this);
mainServer = new MainServer(this, this);
mainServer = new MainServer(this, this);
if(getConfig().isFirstTimeUse())
if(getConfig().isFirstTimeUse())
{
{
Stage stage = new Stage();
Stage stage = new Stage();
Scene s = new Scene(new FirstTimeUse(this, this),
Scene s = new Scene(new FirstTimeUse(this, this),
getConfig().getStartupWindowWidth(), getConfig().getStartupWindowHeight());
getConfig().getStartupWindowWidth(), getConfig().getStartupWindowHeight());
stage.setResizable(false);
stage.setResizable(false);
stage.setScene(s);
stage.setScene(s);
stage.setTitle("Stream-Pi Server Setup");
stage.setTitle("Stream-Pi Server Setup");
stage.initModality(Modality.APPLICATION_MODAL);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setOnCloseRequest(event->Platform.exit());
stage.setOnCloseRequest(event->Platform.exit());
stage.show();
stage.show();
}
}
else
else
{
{
if(getConfig().isAllowDonatePopup())
if(getConfig().isAllowDonatePopup())
{
{
if(new Random().nextInt(5) == 3)
if(new Random().nextInt(5) == 3)
new DonatePopupContent(getHostServices(), this).show();
new DonatePopupContent(getHostServices(), this).show();
}
}
othInit();
othInit();
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
@Override
@Override
public void othInit()
public void othInit()
{
{
try
try
{
{
if(ServerInfo.getInstance().isStartMinimised() && SystemTray.isSupported())
if(ServerInfo.getInstance().isStartMinimised() && SystemTray.isSupported())
minimiseApp();
minimiseApp();
else
else
getStage().show();
getStage().show();
}
}
catch(MinorException e)
catch(MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
executor.execute(new Task<Void>() {
executor.execute(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
getSettingsPane().getGeneralSettings().loadDataFromConfig();
getSettingsBase().getGeneralSettings().loadDataFromConfig();
//themes
//themes
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsBase().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsBase().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().loadThemes();
getSettingsBase().getThemesSettings().loadThemes();
//clients
//clients
getSettingsPane().getClientsSettings().loadData();
getSettingsBase().getClientsSettings().loadData();
try
try
{
{
//Plugins
//Plugins
Platform.runLater(()->{
Platform.runLater(()->{
getDashboardPane().getPluginsPane().clearData();
getDashboardBase().getPluginsPane().clearData();
getDashboardPane().getPluginsPane().loadOtherActions();
getDashboardBase().getPluginsPane().loadOtherActions();
});
});
ExternalPlugins.setPluginsLocation(getConfig().getPluginsPath());
ExternalPlugins.setPluginsLocation(getConfig().getPluginsPath());
ExternalPlugins.getInstance().init();
ExternalPlugins.getInstance().init();
Platform.runLater(()->getDashboardPane().getPluginsPane().loadData());
Platform.runLater(()->getDashboardBase().getPluginsPane().loadData());
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsBase().getPluginsSettings().loadPlugins();
}
}
catch (MinorException e)
catch (MinorException e)
{
{
getSettingsPane().getPluginsSettings().showPluginInitError();
getSettingsBase().getPluginsSettings().showPluginInitError();
handleMinorException(e);
handleMinorException(e);
}
}
//Server
//Server
mainServer.setPort(getConfig().getPort());
mainServer.setPort(getConfig().getPort());
mainServer.start();
mainServer.start();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
return null;
return null;
}
}
});
});
}
}
@Override
public DashboardBase getDashboardBase() {
return getDashboardPane();
}
private void setupSettingsWindowsAnimations()
private void setupSettingsWindowsAnimations()
{
{
Node settingsNode = getSettingsPane();
Node settingsNode = getSettingsBase();
Node dashboardNode = getDashboardPane();
Node dashboardNode = getDashboardBase();
openSettingsAnimation = createOpenSettingsAnimation(settingsNode, dashboardNode);
openSettingsAnimation = createOpenSettingsAnimation(settingsNode, dashboardNode);
closeSettingsAnimation = createCloseSettingsAnimation(settingsNode, dashboardNode);
closeSettingsAnimation = createCloseSettingsAnimation(settingsNode, dashboardNode);
}
}
public void onCloseRequest(WindowEvent event)
public void onCloseRequest(WindowEvent event)
{
{
try
try
{
{
if(Config.getInstance().getMinimiseToSystemTrayOnClose() &&
if(Config.getInstance().getMinimiseToSystemTrayOnClose() &&
SystemTray.isSupported())
SystemTray.isSupported())
{
{
minimiseApp();
minimiseApp();
event.consume();
event.consume();
return;
return;
}
}
getConfig().setStartupWindowSize(getWidth(), getHeight());
getConfig().setStartupWindowSize(getWidth(), getHeight());
getConfig().save();
getConfig().save();
onQuitApp();
onQuitApp();
ExternalPlugins.getInstance().shutDownActions();
ExternalPlugins.getInstance().shutDownActions();
Platform.exit();
Platform.exit();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
finally
finally
{
{
closeLogger();
closeLogger();
}
}
}
}
public void onQuitApp()
public void onQuitApp()
{
{
if(mainServer!=null)
if(mainServer!=null)
mainServer.stopListeningForConnections();
mainServer.stopListeningForConnections();
ClientConnections.getInstance().disconnectAll();
ClientConnections.getInstance().disconnectAll();
executor.shutdown();
executor.shutdown();
getLogger().info("Shutting down ...");
getLogger().info("Shutting down ...");
}
}
public void minimiseApp() throws MinorException
public void minimiseApp() throws MinorException
{
{
try
try
{
{
SystemTray systemTray = SystemTray.getSystemTray();
SystemTray systemTray = SystemTray.getSystemTray();
if(getTrayIcon() == null)
if(getTrayIcon() == null)
initIconTray(systemTray);
initIconTray(systemTray);
systemTray.add(getTrayIcon());
systemTray.add(getTrayIcon());
getStage().hide();
getStage().hide();
getStage().setOnShown(windowEvent -> {
getStage().setOnShown(windowEvent -> {
systemTray.remove(getTrayIcon());
systemTray.remove(getTrayIcon());
});
});
}
}
catch(Exception e)
catch(Exception e)
{
{
throw new MinorException(e.getMessage());
throw new MinorException(e.getMessage());
}
}
}
}
public void initIconTray(SystemTray systemTray)
public void initIconTray(SystemTray systemTray)
{
{
Platform.setImplicitExit(false);
Platform.setImplicitExit(false);
PopupMenu popup = new PopupMenu();
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit");
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(l->{
exitItem.addActionListener(l->{
systemTray.remove(getTrayIcon());
systemTray.remove(getTrayIcon());
onQuitApp();
onQuitApp();
Platform.exit();
Platform.exit();
});
});
popup.add(exitItem);
popup.add(exitItem);
TrayIcon trayIcon = new TrayIcon(
TrayIcon trayIcon = new TrayIcon(
Toolkit.getDefaultToolkit().getImage(Main.class.getResource("app_icon.png")),
Toolkit.getDefaultToolkit().getImage(Main.class.getResource("app_icon.png")),
"Stream-Pi Server",
"Stream-Pi Server",
popup
popup
);
);
trayIcon.addActionListener(l-> Platform.runLater(()-> getStage().show()));
trayIcon.addActionListener(l-> Platform.runLater(()-> getStage().show()));
trayIcon.setImageAutoSize(true);
trayIcon.setImageAutoSize(true);
this.trayIcon = trayIcon;
this.trayIcon = trayIcon;
}
}
private TrayIcon trayIcon = null;
private TrayIcon trayIcon = null;
public TrayIcon getTrayIcon()
public TrayIcon getTrayIcon()
{
{
return trayIcon;
return trayIcon;
}
}
@Override
@Override
public void handleMinorException(MinorException e)
public void handleMinorException(MinorException e)
{
{
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()-> new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
Platform.runLater(()-> new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
}
}
@Override
@Override
public void handleSevereException(SevereException e) {
public void handleSevereException(SevereException e) {
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()->{
Platform.runLater(()->{
StreamPiAlert alert = new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
StreamPiAlert alert = new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
alert.setOnClicked(new StreamPiAlertListener()
alert.setOnClicked(new StreamPiAlertListener()
{
{
@Override
@Override
public void onClick(String txt)
public void onClick(String txt)
{
{
onQuitApp();
onQuitApp();
Platform.exit();
Platform.exit();
}
}
});
});
alert.show();
alert.show();
});
});
}
}
@Override
@Override
public synchronized boolean onNormalActionClicked(NormalAction action, String profileID)
public synchronized boolean onNormalActionClicked(NormalAction action, String profileID)
{
{
try{
try{
getLogger().info("action "+action.getID()+" clicked!");
getLogger().info("action "+action.getID()+" clicked!");
action.onActionClicked();
action.onActionClicked();
return true;
return true;
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
//check if its windows UAC related
//check if its windows UAC related
if(e.getMessage().contains("operation requires elevation"))
if(e.getMessage().contains("operation requires elevation"))
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
);
);
}
}
else
else
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
);
);
}
}
return false;
return false;
}
}
}
}
@Override
@Override
public boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID)
public boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID)
{
{
try{
try{
getLogger().info("action "+action.getID()+" clicked!");
getLogger().info("action "+action.getID()+" clicked!");
if(toggle)
if(toggle)
{
{
action.onToggleOn();
action.onToggleOn();
}
}
else
else
{
{
action.onToggleOff();
action.onToggleOff();
}
}
// ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
// ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
// action.getID(),
// action.getID(),
// profileID
// profileID
// );
// );
//
//
// if(actionBox != null)
// if(actionBox != null)
// {
// {
// Platform.runLater(()->actionBox.init(toggle));
// Platform.runLater(()->actionBox.init(toggle));
// }
// }
return true;
return true;
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
//check if its windows UAC related
//check if its windows UAC related
if(e.getMessage().contains("operation requires elevation"))
if(e.getMessage().contains("operation requires elevation"))
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
);
);
}
}
else
else
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
);
);
}
}
return false;
return false;
}
}
}
}
@Override
@Override
public void clearTemp() {
public void clearTemp() {
Platform.runLater(() -> {
Platform.runLater(() -> {
getDashboardPane().getClientAndProfileSelectorPane().refresh();
getDashboardBase().getClientAndProfileSelectorPane().refresh();
getDashboardPane().getActionGridPane().clear();
getDashboardBase().getActionGridPane().clear();
getDashboardPane().getActionGridPane().setFreshRender(true);
getDashboardBase().getActionGridPane().setFreshRender(true);
getDashboardPane().getActionDetailsPane().clear();
getDashboardBase().getActionDetailsPane().clear();
getSettingsPane().getClientsSettings().loadData();
getSettingsBase().getClientsSettings().loadData();
});
});
}
}
@Override
@Override
public void saveServerProperties()
public void saveServerProperties()
{
{
try
try
{
{
ExternalPlugins.getInstance().saveServerSettings();
ExternalPlugins.getInstance().saveServerSettings();
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsBase().getPluginsSettings().loadPlugins();
} catch (MinorException e) {
} catch (MinorException e) {
e.printStackTrace();
e.printStackTrace();
handleMinorException(e);
handleMinorException(e);
}
}
}
}
private void saveClientActionMain(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons)
private void saveClientActionMain(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons)
{
{
try {
try {
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
Action action = clientProfile.getActionByID(actionID);
Action action = clientProfile.getActionByID(actionID);
clientConnection.saveActionDetails(profileID, action);
clientConnection.saveActionDetails(profileID, action);
if(sendIcons && action.isHasIcon())
if(sendIcons && action.isHasIcon())
{
{
saveAllIcons(profileID, actionID, socketAddress, false);
saveAllIcons(profileID, actionID, socketAddress, false);
}
}
Platform.runLater(()->{
Platform.runLater(()->{
try {
try {
ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
action.getID(),
action.getID(),
profileID
profileID
);
);
if(actionBox != null)
if(actionBox != null)
{
{
Platform.runLater(actionBox::init);
Platform.runLater(actionBox::init);
}
}
if(getDashboardBase().getActionDetailsPane().getAction() != null)
if(getDashboardBase().getActionDetailsPane().getAction() != null)
{
{
// This block is executed when no Action is selected.
// This block is executed when no Action is selected.
if(getDashboardPane().getActionDetailsPane().getAction().getID().equals(actionID))
if(getDashboardBase().getActionDetailsPane().getAction().getID().equals(actionID))
{
{
getDashboardPane().getActionDetailsPane().setAction(action);
getDashboardBase().getActionDetailsPane().setAction(action);
getDashboardPane().getActionDetailsPane().refresh();
getDashboardBase().getActionDetailsPane().refresh();
}
}
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
});
});
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
@Override
@Override
public void saveClientAction(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons, boolean runAsync)
public void saveClientAction(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons, boolean runAsync)
{
{
if(runAsync)
if(runAsync)
{
{
executor.execute(new Task<Void>() {
executor.execute(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
return null;
return null;
}
}
});
});
}
}
else
else
{
{
saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
}
}
}
}
@Override
@Override
public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress)
public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress)
{
{
saveAllIcons(profileID, actionID, socketAddress, true);
saveAllIcons(profileID, actionID, socketAddress, true);
}
}
public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress, boolean async)
public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress, boolean async)
{
{
if(async)
if(async)
{
{
executor.execute(new Task<Void>() {
executor.execute(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
saveAllIconsMain(profileID, actionID, socketAddress);
saveAllIconsMain(profileID, actionID, socketAddress);
return null;
return null;
}
}
});
});
}
}
else
else
{
{
saveAllIconsMain(profileID, actionID, socketAddress);
saveAllIconsMain(profileID, actionID, socketAddress);
}
}
}
}
private void saveAllIconsMain(String profileID, String actionID, SocketAddress socketAddress)
private void saveAllIconsMain(String profileID, String actionID, SocketAddress socketAddress)
{
{
try {
try {
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
Action action = clientProfile.getActionByID(actionID);
Action action = clientProfile.getActionByID(actionID);
for(String eachState : action.getIcons().keySet())
for(String eachState : action.getIcons().keySet())
{
{
clientConnection.sendIcon(profileID, actionID, eachState,
clientConnection.sendIcon(profileID, actionID, eachState,
action.getIcon(eachState));
action.getIcon(eachState));
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
@Override
@Override
public void saveIcon(String state, String profileID, String actionID, SocketAddress socketAddress) {
public void saveIcon(String state, String profileID, String actionID, SocketAddress socketAddress) {
executor.execute(new Task<Void>() {
executor.execute(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try {
try {
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
Action action = clientProfile.getActionByID(actionID);
Action action = clientProfile.getActionByID(actionID);
clientConnection.sendIcon(profileID, actionID, state, action.getIcon(state));
clientConnection.sendIcon(profileID, actionID, state, action.getIcon(state));
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
return null;
return null;
}
}
});
});
}
}
@Override
@Override
public com.stream_pi.util.platform.Platform getPlatform() {
public com.stream_pi.util.platform.Platform getPlatform() {
return ServerInfo.getInstance().getPlatform();
return ServerInfo.getInstance().getPlatform();
}
}
private Animation createOpenSettingsAnimation(Node settingsNode, Node dashboardNode) {
private Animation createOpenSettingsAnimation(Node settingsNode, Node dashboardNode) {
Timeline openSettingsTimeline = new Timeline();
Timeline openSettingsTimeline = new Timeline();
openSettingsTimeline.setCycleCount(1);
openSettingsTimeline.setCycleCount(1);
openSettingsTimeline.getKeyFrames().addAll(
openSettingsTimeline.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.EASE_IN),
0.0D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.1D, Interpolator.EASE_IN),
1.1D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.1D, Interpolator.EASE_IN),
1.1D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.1D, Interpolator.EASE_IN)),
1.1D, Interpolator.EASE_IN)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
0.9D, Interpolator.LINEAR))
0.9D, Interpolator.LINEAR))
);
);
openSettingsTimeline.setOnFinished(e -> settingsNode.toFront());
openSettingsTimeline.setOnFinished(e -> settingsNode.toFront());
return openSettingsTimeline;
return openSettingsTimeline;
}
}
private Animation createCloseSettingsAnimation(Node settingsNode, Node dashboardNode) {
private Animation createCloseSettingsAnimation(Node settingsNode, Node dashboardNode) {
Timeline closeSettingsTimeline = new Timeline();
Timeline closeSettingsTimeline = new Timeline();
closeSettingsTimeline.setCycleCount(1);
closeSettingsTimeline.setCycleCount(1);
closeSettingsTimeline.getKeyFrames().addAll(
closeSettingsTimeline.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.1D, Interpolator.LINEAR),
1.1D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.1D, Interpolator.LINEAR),
1.1D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.1D, Interpolator.LINEAR)),
1.1D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
0.9D, Interpolator.LINEAR)),
0.9D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
1.0D, Interpolator.LINEAR))
1.0D, Interpolator.LINEAR))
);
);
closeSettingsTimeline.setOnFinished(event1 -> {
closeSettingsTimeline.setOnFinished(event1 -> {
dashboardNode.toFront();
dashboardNode.toFront();
executor.execute(new Task<Void>() {
executor.execute(new Task<Void>() {
@Override
@Override
protected Void call() {
protected Void call() {
try {
try {
getSettingsPane().getClientsSettings().loadData();
getSettingsBase().getClientsSettings().loadData();
getSettingsPane().getGeneralSettings().loadDataFromConfig();
getSettingsBase().getGeneralSettings().loadDataFromConfig();
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsBase().getPluginsSettings().loadPlugins();
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsBase().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsBase().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().loadThemes();
getSettingsBase().getThemesSettings().loadThemes();
getSettingsPane().setDefaultTabToGeneral();
getSettingsBase().setDefaultTabToGeneral();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
return null;
return null;
}
}
});
});
});
});
return closeSettingsTimeline;
return closeSettingsTimeline;
}
}
}
}
package com.stream_pi.server.window;
package com.stream_pi.server.window;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.Main;
import com.stream_pi.server.Main;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.settings.SettingsBase;
import com.stream_pi.server.window.settings.SettingsBase;
import com.stream_pi.theme_api.Theme;
import com.stream_pi.theme_api.Theme;
import com.stream_pi.theme_api.Themes;
import com.stream_pi.theme_api.Themes;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.loggerhelper.StreamPiLogFallbackHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFallbackHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFileHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFileHandler;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.Platform;
import javafx.application.HostServices;
import javafx.application.HostServices;
import javafx.scene.image.Image;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.stage.Stage;
import java.awt.*;
import java.awt.*;
import java.io.File;
import java.io.File;
import java.util.logging.Logger;
import java.util.logging.Logger;
public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ServerListener {
public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ServerListener {
private Config config;
private Config config;
private ServerInfo serverInfo;
private ServerInfo serverInfo;
private Stage stage;
private Stage stage;
private HostServices hostServices;
private HostServices hostServices;
private SettingsBase settingsBase;
private SettingsBase settingsBase;
private DashboardBase dashboardBase;
private DashboardBase dashboardBase;
private StackPane alertStackPane;
private StackPane alertStackPane;
private StreamPiLogFileHandler logFileHandler = null;
private StreamPiLogFileHandler logFileHandler = null;
private StreamPiLogFallbackHandler logFallbackHandler = null;
private StreamPiLogFallbackHandler logFallbackHandler = null;
private Logger logger = null;
private Logger logger = null;
public Logger getLogger(){
public Logger getLogger(){
return logger;
return logger;
}
}
public void setHostServices(HostServices hostServices)
public void setHostServices(HostServices hostServices)
{
{
this.hostServices = hostServices;
this.hostServices = hostServices;
}
}
public HostServices getHostServices()
public HostServices getHostServices()
{
{
return hostServices;
return hostServices;
}
}
@Override
@Override
public void initLogger()
public void initLogger()
{
{
try
try
{
{
if(logFileHandler != null)
if(logFileHandler != null)
return;
return;
closeLogger();
closeLogger();
logger = Logger.getLogger("");
logger = Logger.getLogger("");
if(new File(ServerInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
if(new File(ServerInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
{
{
String path = ServerInfo.getInstance().getPrePath()+"../stream-pi-server.log";
String path = ServerInfo.getInstance().getPrePath()+"../stream-pi-server.log";
if(ServerInfo.getInstance().getPlatform() == Platform.ANDROID)
if(ServerInfo.getInstance().getPlatform() == Platform.ANDROID)
path = ServerInfo.getInstance().getPrePath()+"stream-pi-server.log";
path = ServerInfo.getInstance().getPrePath()+"stream-pi-server.log";
logFileHandler = new StreamPiLogFileHandler(path);
logFileHandler = new StreamPiLogFileHandler(path);
logger.addHandler(logFileHandler);
logger.addHandler(logFileHandler);
}
}
else
else
{
{
logFallbackHandler = new StreamPiLogFallbackHandler();
logFallbackHandler = new StreamPiLogFallbackHandler();
logger.addHandler(logFallbackHandler);
logger.addHandler(logFallbackHandler);
}
}
}
}
catch(Exception e)
catch(Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
logFallbackHandler = new StreamPiLogFallbackHandler();
logFallbackHandler = new StreamPiLogFallbackHandler();
logger.addHandler(logFallbackHandler);
logger.addHandler(logFallbackHandler);
}
}
}
}
public void closeLogger()
public void closeLogger()
{
{
if(logFileHandler != null)
if(logFileHandler != null)
logFileHandler.close();
logFileHandler.close();
else if(logFallbackHandler != null)
else if(logFallbackHandler != null)
logFallbackHandler.close();
logFallbackHandler.close();
}
}
public void initBase() throws SevereException
public void initBase() throws SevereException
{
{
stage = (Stage) getScene().getWindow();
stage = (Stage) getScene().getWindow();
getStage().getIcons().add(new Image(Main.class.getResourceAsStream("app_icon.png")));
getStage().getIcons().add(new Image(Main.class.getResourceAsStream("app_icon.png")));
getStage().setMinWidth(500);
getStage().setMinWidth(500);
getStage().setMinHeight(500);
getStage().setMinHeight(500);
serverInfo = ServerInfo.getInstance();
serverInfo = ServerInfo.getInstance();
settingsBase = new SettingsBase(getHostServices(), this, this);
settingsBase = new SettingsBase(getHostServices(), this, this);
settingsBase.prefWidthProperty().bind(widthProperty());
settingsBase.prefWidthProperty().bind(widthProperty());
settingsBase.prefHeightProperty().bind(heightProperty());
settingsBase.prefHeightProperty().bind(heightProperty());
dashboardBase = new DashboardBase(this, getHostServices());
dashboardBase = new DashboardBase(this, getHostServices());
dashboardBase.prefWidthProperty().bind(widthProperty());
dashboardBase.prefWidthProperty().bind(widthProperty());
dashboardBase.prefHeightProperty().bind(heightProperty());
dashboardBase.prefHeightProperty().bind(heightProperty());
alertStackPane = new StackPane();
alertStackPane = new StackPane();
alertStackPane.setVisible(false);
alertStackPane.setVisible(false);
StreamPiAlert.setParent(alertStackPane);
StreamPiAlert.setParent(alertStackPane);
getChildren().clear();
getChildren().clear();
getChildren().addAll(alertStackPane);
getChildren().addAll(alertStackPane);
initLogger();
initLogger();
checkPrePathDirectory();
checkPrePathDirectory();
getChildren().addAll(settingsBase, dashboardBase);
getChildren().addAll(settingsBase, dashboardBase);
config = Config.getInstance();
config = Config.getInstance();
initThemes();
initThemes();
stage.setWidth(config.getStartupWindowWidth());
stage.setWidth(config.getStartupWindowWidth());
stage.setHeight(config.getStartupWindowHeight());
stage.setHeight(config.getStartupWindowHeight());
stage.centerOnScreen();
stage.centerOnScreen();
dashboardBase.toFront();
dashboardBase.toFront();
}
}
private void checkPrePathDirectory() throws SevereException
private void checkPrePathDirectory() throws SevereException
{
{
try
try
{
{
File filex = new File(ServerInfo.getInstance().getPrePath());
File filex = new File(ServerInfo.getInstance().getPrePath());
if(!filex.exists())
if(!filex.exists())
{
{
boolean result = filex.mkdirs();
boolean result = filex.mkdirs();
if(result)
if(result)
{
{
IOHelper.unzip(Main.class.getResourceAsStream("Default.zip"), ServerInfo.getInstance().getPrePath());
IOHelper.unzip(Main.class.getResourceAsStream("Default.zip"), ServerInfo.getInstance().getPrePath());
Config.getInstance().setThemesPath(ServerInfo.getInstance().getPrePath()+"Themes/");
Config.getInstance().setThemesPath(ServerInfo.getInstance().getPrePath()+"Themes/");
Config.getInstance().setPluginsPath(ServerInfo.getInstance().getPrePath()+"Plugins/");
Config.getInstance().setPluginsPath(ServerInfo.getInstance().getPrePath()+"Plugins/");
if(SystemTray.isSupported())
if(SystemTray.isSupported())
{
{
Config.getInstance().setMinimiseToSystemTrayOnClose(true);
Config.getInstance().setMinimiseToSystemTrayOnClose(true);
}
}
Config.getInstance().save();
Config.getInstance().save();
initLogger();
initLogger();
}
}
else
else
{
{
setPrefSize(300,300);
setPrefSize(300,300);
clearStylesheets();
clearStylesheets();
applyDefaultStylesheet();
applyDefaultStylesheet();
applyDefaultIconsStylesheet();
applyDefaultIconsStylesheet();
getStage().show();
getStage().show();
throw new SevereException("No storage permission. Give it!");
throw new SevereException("No storage permission. Give it!");
}
}
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException(e.getMessage());
throw new SevereException(e.getMessage());
}
}
}
}
public void initThemes() throws SevereException {
public void initThemes() throws SevereException {
clearStylesheets();
clearStylesheets();
registerThemes();
registerThemes();
applyDefaultStylesheet();
applyDefaultStylesheet();
applyDefaultTheme();
applyDefaultTheme();
applyDefaultIconsStylesheet();
applyDefaultIconsStylesheet();
}
}
@Override
@Override
public Stage getStage()
public Stage getStage()
{
{
return stage;
return stage;
}
}
public void applyDefaultStylesheet()
public void applyDefaultStylesheet()
{
{
logger.info("Applying default stylesheet ...");
logger.info("Applying default stylesheet ...");
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
logger.info("... Done!");
logger.info("... Done!");
}
}
public void applyDefaultIconsStylesheet()
public void applyDefaultIconsStylesheet()
{
{
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
getStylesheets().add(Main.class.getResource("default_icons.css").toExternalForm());
getStylesheets().add(Main.class.getResource("default_icons.css").toExternalForm());
}
}
public DashboardBase getDashboardPane()
public DashboardBase getDashboardBase()
{
{
return dashboardBase;
return dashboardBase;
}
}
public SettingsBase getSettingsPane()
public SettingsBase getSettingsBase()
{
{
return settingsBase;
return settingsBase;
}
}
public Config getConfig()
public Config getConfig()
{
{
return config;
return config;
}
}
public ServerInfo getServerInfo()
public ServerInfo getServerInfo()
{
{
return serverInfo;
return serverInfo;
}
}
private Theme currentTheme;
private Theme currentTheme;
public Theme getCurrentTheme()
public Theme getCurrentTheme()
{
{
return currentTheme;
return currentTheme;
}
}
public void applyTheme(Theme t)
public void applyTheme(Theme t)
{
{
logger.info("Applying theme '"+t.getFullName()+"' ...");
logger.info("Applying theme '"+t.getFullName()+"' ...");
if(t.getFonts() != null)
if(t.getFonts() != null)
{
{
for(String fontFile : t.getFonts())
for(String fontFile : t.getFonts())
{
{
Font.loadFont(fontFile.replace("%20",""), 13);
Font.loadFont(fontFile.replace("%20",""), 13);
}
}
}
}
currentTheme = t;
currentTheme = t;
getStylesheets().addAll(t.getStylesheets());
getStylesheets().addAll(t.getStylesheets());
logger.info("... Theme applied successfully!");
logger.info("... Theme applied successfully!");
}
}
public void clearStylesheets()
public void clearStylesheets()
{
{
getStylesheets().clear();
getStylesheets().clear();
}
}
Themes themes;
Themes themes;
public void registerThemes() throws SevereException
public void registerThemes() throws SevereException
{
{
logger.info("Loading themes ...");
logger.info("Loading themes ...");
themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), serverInfo.getMinThemeSupportVersion());
themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), serverInfo.getMinThemeSupportVersion());
if(!themes.getErrors().isEmpty())
if(!themes.getErrors().isEmpty())
{
{
StringBuilder themeErrors = new StringBuilder();
StringBuilder themeErrors = new StringBuilder();
for(MinorException eachException : themes.getErrors())
for(MinorException eachException : themes.getErrors())
{
{
themeErrors.append("\n * ").append(eachException.getShortMessage());
themeErrors.append("\n * ").append(eachException.getShortMessage());
}
}
if(themes.getIsBadThemeTheCurrentOne())
if(themes.getIsBadThemeTheCurrentOne())
{
{
themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
getConfig().save();
getConfig().save();
}
}
handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
}
}
logger.info("...Themes loaded successfully !");
logger.info("...Themes loaded successfully !");
}
}
public Themes getThemes()
public Themes getThemes()
{
{
return themes;
return themes;
}
}
public void applyDefaultTheme()
public void applyDefaultTheme()
{
{
logger.info("Applying default theme ...");
logger.info("Applying default theme ...");
boolean foundTheme = false;
boolean foundTheme = false;
for(Theme t: themes.getThemeList())
for(Theme t: themes.getThemeList())
{
{
if(t.getFullName().equals(config.getCurrentThemeFullName()))
if(t.getFullName().equals(config.getCurrentThemeFullName()))
{
{
foundTheme = true;
foundTheme = true;
applyTheme(t);
applyTheme(t);
break;
break;
}
}
}
}
if(!foundTheme)
if(!foundTheme)
{
{
logger.info("Theme not found. reverting to light theme ...");
logger.info("Theme not found. reverting to light theme ...");
try {
try {
Config.getInstance().setCurrentThemeFullName("com.streampi.DefaultLight");
Config.getInstance().setCurrentThemeFullName("com.streampi.DefaultLight");
Config.getInstance().save();
Config.getInstance().save();
applyDefaultTheme();
applyDefaultTheme();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
}
}
}
}