server
Clone or download
Modified Files
/*
/*
Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
This program is free software: you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
(at your option) any later version.
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License for more details.
Written by : Debayan Sutradhar (rnayabed)
Written by : Debayan Sutradhar (rnayabed)
*/
*/
package com.stream_pi.server.client;
package com.stream_pi.server.client;
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 java.net.SocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
import java.util.List;
import java.util.List;
public class Client {
public class Client
{
private String nickName;
private String nickName;
private final SocketAddress remoteSocketAddress;
private final SocketAddress remoteSocketAddress;
private final Platform platform;
private final Platform platform;
private final Version version;
private final Version version;
private final Version commStandardVersion;
private final Version commStandardVersion;
private final Version themeAPIVersion;
private final Version themeAPIVersion;
private final ReleaseStatus releaseStatus;
private final ReleaseStatus releaseStatus;
private double startupDisplayHeight, startupDisplayWidth;
private double startupDisplayHeight, startupDisplayWidth;
private final HashMap<String,ClientProfile> profiles;
private final HashMap<String,ClientProfile> profiles;
private final HashMap<String,ClientTheme> themes;
private final HashMap<String,ClientTheme> themes;
private String defaultProfileID;
private String defaultProfileID;
private String defaultThemeFullName;
private String defaultThemeFullName;
public Client(Version version, ReleaseStatus releaseStatus, Version commStandardVersion, Version themeAPIVersion, String nickName, Platform platform, SocketAddress remoteSocketAddress)
public Client(Version version, ReleaseStatus releaseStatus, Version commStandardVersion, Version themeAPIVersion, String nickName, Platform platform, SocketAddress remoteSocketAddress)
{
{
this.version = version;
this.version = version;
this.releaseStatus = releaseStatus;
this.releaseStatus = releaseStatus;
this.commStandardVersion = commStandardVersion;
this.commStandardVersion = commStandardVersion;
this.themeAPIVersion = themeAPIVersion;
this.themeAPIVersion = themeAPIVersion;
this.nickName = nickName;
this.nickName = nickName;
this.remoteSocketAddress = remoteSocketAddress;
this.remoteSocketAddress = remoteSocketAddress;
this.platform = platform;
this.platform = platform;
this.profiles = new HashMap<>();
this.profiles = new HashMap<>();
this.themes = new HashMap<>();
this.themes = new HashMap<>();
}
}
public ReleaseStatus getReleaseStatus() {
public ReleaseStatus getReleaseStatus() {
return releaseStatus;
return releaseStatus;
}
}
public void setDefaultThemeFullName(String defaultThemeFullName) {
public void setDefaultThemeFullName(String defaultThemeFullName) {
this.defaultThemeFullName = defaultThemeFullName;
this.defaultThemeFullName = defaultThemeFullName;
}
}
public String getDefaultThemeFullName() {
public String getDefaultThemeFullName() {
return defaultThemeFullName;
return defaultThemeFullName;
}
}
public void setDefaultProfileID(String ID)
public void setDefaultProfileID(String ID)
{
{
defaultProfileID = ID;
defaultProfileID = ID;
}
}
public void addTheme(ClientTheme clientTheme) throws CloneNotSupportedException
public void addTheme(ClientTheme clientTheme) throws CloneNotSupportedException
{
{
themes.put(clientTheme.getThemeFullName(), (ClientTheme) clientTheme.clone());
themes.put(clientTheme.getThemeFullName(), (ClientTheme) clientTheme.clone());
}
}
public ArrayList<ClientTheme> getThemes()
public ArrayList<ClientTheme> getThemes()
{
{
ArrayList<ClientTheme> clientThemes = new ArrayList<>();
ArrayList<ClientTheme> clientThemes = new ArrayList<>();
for(String clientTheme : themes.keySet())
for(String clientTheme : themes.keySet())
{
{
clientThemes.add(themes.get(clientTheme));
clientThemes.add(themes.get(clientTheme));
}
}
return clientThemes;
return clientThemes;
}
}
public ClientTheme getThemeByFullName(String fullName)
public ClientTheme getThemeByFullName(String fullName)
{
{
return themes.getOrDefault(fullName, null);
return themes.getOrDefault(fullName, null);
}
}
public String getDefaultProfileID()
public String getDefaultProfileID()
{
{
return defaultProfileID;
return defaultProfileID;
}
}
//client Profiles
//client Profiles
public void setNickName(String nickName)
public void setNickName(String nickName)
{
{
this.nickName = nickName;
this.nickName = nickName;
}
}
public List<ClientProfile> getAllClientProfiles()
public List<ClientProfile> getAllClientProfiles()
{
{
ArrayList<ClientProfile> clientProfiles = new ArrayList<>();
ArrayList<ClientProfile> clientProfiles = new ArrayList<>();
for(String profile : profiles.keySet())
for(String profile : profiles.keySet())
clientProfiles.add(profiles.get(profile));
clientProfiles.add(profiles.get(profile));
return clientProfiles;
return clientProfiles;
}
}
public void removeProfileFromID(String ID)
public void removeProfileFromID(String ID)
{
{
profiles.remove(ID);
profiles.remove(ID);
}
}
public void addProfile(ClientProfile clientProfile) throws CloneNotSupportedException {
public void addProfile(ClientProfile clientProfile) throws CloneNotSupportedException {
profiles.put(clientProfile.getID(), (ClientProfile) clientProfile.clone());
profiles.put(clientProfile.getID(), (ClientProfile) clientProfile.clone());
}
}
public synchronized ClientProfile getProfileByID(String ID) {
public synchronized ClientProfile getProfileByID(String ID) {
return profiles.getOrDefault(ID, null);
return profiles.getOrDefault(ID, null);
}
}
public SocketAddress getRemoteSocketAddress()
public SocketAddress getRemoteSocketAddress()
{
{
return remoteSocketAddress;
return remoteSocketAddress;
}
}
public Platform getPlatform()
public Platform getPlatform()
{
{
return platform;
return platform;
}
}
public String getNickName()
public String getNickName()
{
{
return nickName;
return nickName;
}
}
public Version getVersion()
public Version getVersion()
{
{
return version;
return version;
}
}
public Version getCommStandardVersion()
public Version getCommStandardVersion()
{
{
return commStandardVersion;
return commStandardVersion;
}
}
public Version getThemeAPIVersion()
public Version getThemeAPIVersion()
{
{
return themeAPIVersion;
return themeAPIVersion;
}
}
public double getStartupDisplayHeight()
public double getStartupDisplayHeight()
{
{
return startupDisplayHeight;
return startupDisplayHeight;
}
}
public double getStartupDisplayWidth()
public double getStartupDisplayWidth()
{
{
return startupDisplayWidth;
return startupDisplayWidth;
}
}
public void setStartupDisplayHeight(double height)
public void setStartupDisplayHeight(double height)
{
{
startupDisplayHeight = height;
startupDisplayHeight = height;
}
}
public void setStartupDisplayWidth(double width)
public void setStartupDisplayWidth(double width)
{
{
startupDisplayWidth = width;
startupDisplayWidth = width;
}
}
private int getMaxRows(int eachActionSize)
private int getMaxRows(int eachActionSize)
{
{
return (int) (startupDisplayHeight / eachActionSize);
return (int) (startupDisplayHeight / eachActionSize);
}
}
public int getMaxCols(int eachActionSize)
public int getMaxCols(int eachActionSize)
{
{
return (int) (startupDisplayWidth / eachActionSize);
return (int) (startupDisplayWidth / eachActionSize);
}
}
}
}
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.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.server.action.NormalActionPlugins;
import com.stream_pi.server.action.NormalActionPlugins;
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.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.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.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.*;
import java.io.DataOutputStream;
import java.lang.reflect.Array;
import java.io.IOException;
import java.net.Socket;
import java.net.Socket;
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 DataInputStream dis;
private ObjectOutputStream oos;
private DataOutputStream dos;
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;
//actionIconsToBeSent = new ArrayList__();
//actionIconsToBeSent = new ArrayList__();
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
{
{
dis = new DataInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
dos = new DataOutputStream(socket.getOutputStream());
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 "+socket.getRemoteSocketAddress());
logger.info("Stopping connection "+socket.getRemoteSocketAddress());
disconnect();
disconnect();
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
}
}
public synchronized void exitAndRemove()
public synchronized void exitAndRemove()
{
{
exit();
exit();
removeConnection();
removeConnection();
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public void removeConnection()
public void removeConnection()
{
{
ClientConnections.getInstance().removeConnection(this);
ClientConnections.getInstance().removeConnection(this);
}
}
public synchronized void writeToStream(String text) throws SevereException
public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
{
try
{
byte[] txtBytes = text.getBytes();
Thread.sleep(50);
dos.writeUTF("string:: ::");
dos.flush();
dos.writeInt(txtBytes.length);
dos.flush();
write(txtBytes);
dos.flush();
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
}
}
public synchronized void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
{
{
try
Message message = new Message("action_icon");
{
message.setStringArrValue(profileID, actionID);
logger.info("Sending action Icon...");
message.setByteArrValue(icon);
//Thread.sleep(50);
sendMessage(message);
System.out.println("1");
dos.writeUTF("action_icon::"+profileID+"!!"+actionID+"!!::"+icon.length);
System.out.println("2");
dos.flush();
System.out.println("3");
dos.writeInt(icon.length);
System.out.println("4");
dos.flush();
System.out.println("5");
write(icon);
System.out.println("6");
dos.flush();
System.out.println("7");
}
catch (IOException e)
{
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
}
}
}
public void write(byte[] array) throws SevereException
public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
{
{
try
String[] ar = message.getStringArrValue();
{
dos.write(array);
}
catch (IOException e)
{
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
}
}
public void initAfterConnectionQueryReceive(String[] arr) throws StreamPiException
{
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(arr[1]);
clientVersion = new Version(ar[0]);
releaseStatus = ReleaseStatus.valueOf(arr[2]);
releaseStatus = ReleaseStatus.valueOf(ar[1]);
commsStandard = new Version(arr[3]);
commsStandard = new Version(ar[2]);
themesStandard = new Version(arr[4]);
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, arr[5], Platform.valueOf(arr[8]), socket.getRemoteSocketAddress());
client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
client.setStartupDisplayWidth(Double.parseDouble(arr[6]));
client.setStartupDisplayWidth(Double.parseDouble(ar[5]));
client.setStartupDisplayHeight(Double.parseDouble(arr[7]));
client.setStartupDisplayHeight(Double.parseDouble(ar[6]));
client.setDefaultProfileID(arr[9]);
client.setDefaultProfileID(ar[8]);
client.setDefaultThemeFullName(arr[10]);
client.setDefaultThemeFullName(ar[9]);
//call get profiles command.
//call get profiles command.
serverListener.clearTemp();
serverListener.clearTemp();
}
}
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())
{
{
String msg = "";
try
try
{
{
String raw = dis.readUTF();
Message message = (Message) ois.readObject();
int length = dis.readInt();
System.out.println("SIZE TO READ : "+length);
String[] precursor = raw.split("::");
String inputType = precursor[0];
String secondArg = precursor[1];
String header = message.getHeader();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
switch (header)
/*int count;
int chunkSize = 512;
while (length>0)
{
{
if(chunkSize > length)
case "action_icon" : onActionIconReceived(message);
chunkSize = length;
break;
else
chunkSize = 512;
byte[] buffer = new byte[chunkSize];
count = dis.read(buffer);
System.out.println(count);
case "disconnect" : clientDisconnected(message);
break;
byteArrayOutputStream.write(buffer);
case "client_details" : initAfterConnectionQueryReceive(message);
getProfilesFromClient();
getThemesFromClient();
break;
length-=count;
case "profiles" : registerProfilesFromClient(message);
}*/
break;
/*byte[] buffer = new byte[8192];
int read;
while((read = dis.read(buffer)) != -1){
System.out.println("READ : "+read);
byteArrayOutputStream.write(buffer, 0, read);
}
System.out.println("READ : "+byteArrayOutputStream.size());
case "profile_details" : registerProfileDetailsFromClient(message);
break;
byteArrayOutputStream.close();
case "action_details" : registerActionToProfile(message);
break;
byte[] bArr = byteArrayOutputStream.toByteArray();*/
case "themes": registerThemes(message);
break;
byte[] bArr = new byte[length];
case "action_clicked": actionClicked(message);
break;
dis.readFully(bArr);
if(inputType.equals("string"))
{
msg = new String(bArr);
}
else if(inputType.equals("action_icon"))
{
String[] secondArgSep = secondArg.split("!!");
String profileID = secondArgSep[0];
default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
String actionID = secondArgSep[1];
getClient().getProfileByID(profileID).getActionByID(actionID).setIcon(bArr);
//serverListener.clearTemp();
continue;
}
}
}
}
catch (IOException 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;
}
}
logger.info("Received text : '"+msg+"'");
String[] sep = msg.split("::");
String command = sep[0];
switch (command)
{
case "disconnect" : clientDisconnected(msg);
break;
case "client_details" : initAfterConnectionQueryReceive(sep);
getProfilesFromClient();
getThemesFromClient();
break;
case "profiles" : registerProfilesFromClient(sep);
break;
case "profile_details" : registerProfileDetailsFromClient(sep);
break;
case "action_details" : registerActionToProfile(sep);
break;
case "themes": registerThemes(sep);
break;
case "action_clicked": actionClicked(sep[1], sep[2]);
break;
default: logger.warning("Command '"+command+"' does not match records. Make sure client and server versions are equal.");
}
}
}
}
}
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
private void onActionIconReceived(Message message)
{
String[] s = message.getStringArrValue();
String profileID = s[0];
String actionID = s[1];
getClient().getProfileByID(profileID).getActionByID(actionID).setIcon(message.getByteArrValue());
}
// commands
public void initAfterConnectionQuerySend() throws SevereException
public void initAfterConnectionQuerySend() throws SevereException
{
{
logger.info("Asking client details ...");
logger.info("Asking client details ...");
writeToStream("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 ...");
writeToStream("disconnect::"+message+"::");
Message m = new Message("disconnect");
m.setStringValue(message);
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 void clientDisconnected(String message)
public synchronized void sendMessage(Message message) throws SevereException
{
try
{
oos.writeObject(message);
oos.flush();
}
catch (IOException e)
{
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
}
}
public void clientDisconnected(Message message)
{
{
stop.set(true);
stop.set(true);
String txt = "Disconnected!";
String txt = "Disconnected!";
if(!message.equals("disconnect::::"))
String msg = message.getStringValue();
txt = "Message : "+message.split("::")[1];
if(!msg.isBlank())
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 ...");
writeToStream("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 ...");
writeToStream("get_themes::");
sendMessage(new Message("get_themes"));
}
}
public void registerThemes(String[] sep)
public void registerThemes(Message message)
{
{
for(int i =1; i<sep.length;i++)
String[] r = message.getStringArrValue();
{
String[] internal = sep[i].split("__");
for(int i =0; i<(r.length);i+=4)
{
ClientTheme clientTheme = new ClientTheme(
ClientTheme clientTheme = new ClientTheme(
internal[0],
r[i],
internal[1],
r[i+1],
internal[2],
r[i+2],
internal[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(String[] sep) throws StreamPiException
public void registerProfilesFromClient(Message message) throws StreamPiException
{
{
logger.info("Registering profiles ...");
logger.info("Registering profiles ...");
int noOfProfiles = Integer.parseInt(sep[1]);
String[] r = message.getStringArrValue();
for(int i = 2; i<(noOfProfiles + 2); i++)
for (String profileID : r) {
{
String profileID = sep[i];
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);
writeToStream("get_profile_details::"+ID+"::");
Message message = new Message("get_profile_details");
message.setStringValue(ID);
sendMessage(message);
}
}
public void registerProfileDetailsFromClient(String[] sep)
public void registerProfileDetailsFromClient(Message message)
{
{
String ID = sep[1];
String[] r = message.getStringArrValue();
String ID = r[0];
logger.info("Registering details for profile : "+ID);
logger.info("Registering details for profile : "+ID);
String name = sep[2];
String name = r[1];
int rows = Integer.parseInt(sep[3]);
int rows = Integer.parseInt(r[2]);
int cols = Integer.parseInt(sep[4]);
int cols = Integer.parseInt(r[3]);
int actionSize = Integer.parseInt(sep[5]);
int actionSize = Integer.parseInt(r[4]);
int actionGap = Integer.parseInt(sep[6]);
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 void getActionIcon(String profileID, String actionID) throws StreamPiException
/*public void getActionIcon(String profileID, String actionID) throws StreamPiException
{
{
System.out.println("getting action icon from "+profileID+", "+actionID);
System.out.println("getting action icon from "+profileID+", "+actionID);
writeToStream("get_action_icon::"+profileID+"::"+actionID);
writeToStream("get_action_icon::"+profileID+"::"+actionID);
}*/
}*/
public synchronized void registerActionToProfile(String[] sep) throws StreamPiException
public synchronized void registerActionToProfile(Message message) throws StreamPiException
{
{
String profileID = sep[1];
String[] r = message.getStringArrValue();
String ID = sep[2];
String profileID = r[0];
ActionType actionType = ActionType.valueOf(sep[3]);
//4 - Version
String ID = r[1];
//5 - ModuleName
ActionType actionType = ActionType.valueOf(r[2]);
//3 - Version
//4 - ModuleName
//display
//display
String bgColorHex = sep[6];
String bgColorHex = r[5];
//icon
//icon
boolean isHasIcon = sep[7].equals("true");
boolean isHasIcon = r[6].equals("true");
boolean isShowIcon = sep[8].equals("true");
boolean isShowIcon = r[7].equals("true");
//text
//text
boolean isShowDisplayText = sep[9].equals("true");
boolean isShowDisplayText = r[8].equals("true");
String displayFontColor = sep[10];
String displayFontColor = r[9];
String displayText = sep[11];
String displayText = r[10];
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(sep[12]);
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
//location
//location
String row = sep[13];
String row = r[12];
String col = sep[14];
String col = r[13];
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
Action action = new Action(ID, actionType);
Action action = new Action(ID, actionType);
action.setBgColourHex(bgColorHex);
action.setBgColourHex(bgColorHex);
action.setShowIcon(isShowIcon);
action.setShowIcon(isShowIcon);
action.setHasIcon(isHasIcon);
action.setHasIcon(isHasIcon);
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);
String root = r[14];
action.setParent(root);
//client properties
//client properties
int clientPropertiesSize = Integer.parseInt(sep[15]);
int clientPropertiesSize = Integer.parseInt(r[15]);
String root = sep[17];
action.setParent(root);
String[] clientPropertiesRaw = sep[16].split("!!");
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 = 0;i<clientPropertiesSize; i++)
for(int i = 16;i<((clientPropertiesSize*2) + 16); i+=2)
{
{
String[] clientPraw = clientPropertiesRaw[i].split("__");
Property property = new Property(r[i], Type.STRING);
property.setRawValue(r[i+1]);
Property property = new Property(clientPraw[0], Type.STRING);
if(clientPraw.length > 1)
property.setRawValue(clientPraw[1]);
clientProperties.addProperty(property);
clientProperties.addProperty(property);
}
}
action.setClientProperties(clientProperties);
action.setClientProperties(clientProperties);
action.setModuleName(sep[5]);
action.setModuleName(r[4]);
//set up action
//set up action
//action toBeAdded = null;
//action toBeAdded = null;
if(actionType == ActionType.NORMAL)
if(actionType == ActionType.NORMAL)
{
{
NormalAction actionCopy = NormalActionPlugins.getInstance().getPluginByModuleName(sep[5]);
NormalAction actionCopy = NormalActionPlugins.getInstance().getPluginByModuleName(r[4]);
if(actionCopy == null)
if(actionCopy == null)
{
{
action.setInvalid(true);
action.setInvalid(true);
}
}
else
else
{
{
action.setVersion(new Version(sep[4]));
action.setVersion(new Version(r[3]));
//action.setHelpLink(actionCopy.getHelpLink());
//action.setHelpLink(actionCopy.getHelpLink());
if(actionCopy.getVersion().getMajor() != action.getVersion().getMajor())
if(actionCopy.getVersion().getMajor() != action.getVersion().getMajor())
{
{
action.setInvalid(true);
action.setInvalid(true);
}
}
else
else
{
{
action.setName(actionCopy.getName());
action.setName(actionCopy.getName());
ClientProperties finalClientProperties = new ClientProperties();
ClientProperties finalClientProperties = new ClientProperties();
for(Property property : actionCopy.getClientProperties().get())
for(Property property : actionCopy.getClientProperties().get())
{
{
for(int i = 0;i<action.getClientProperties().getSize();i++)
for(int i = 0;i<action.getClientProperties().getSize();i++)
{
{
Property property1 = action.getClientProperties().get().get(i);
Property property1 = action.getClientProperties().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);
}
}
}
}
}
}
action.setClientProperties(finalClientProperties);
action.setClientProperties(finalClientProperties);
}
}
}
}
}
}
try
try
{
{
for(Property prop : action.getClientProperties().get())
for(Property prop : action.getClientProperties().get())
{
{
logger.info("G@@@@@ : "+prop.getRawValue());
logger.info("G@@@@@ : "+prop.getRawValue());
}
}
getClient().getProfileByID(profileID).addAction(action);
getClient().getProfileByID(profileID).addAction(action);
for(String action1x : getClient().getProfileByID(profileID).getActionsKeySet())
for(String action1x : getClient().getProfileByID(profileID).getActionsKeySet())
{
{
Action action1 = getClient().getProfileByID(profileID).getActionByID(action1x);
Action action1 = getClient().getProfileByID(profileID).getActionByID(action1x);
logger.info("231cc : "+action1.getID());
logger.info("231cc : "+action1.getID());
for(Property prop : action1.getClientProperties().get())
for(Property prop : action1.getClientProperties().get())
{
{
logger.info("G@VVVV@@@ : "+prop.getRawValue());
logger.info("G@VVVV@@@ : "+prop.getRawValue());
}
}
}
}
}
}
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 void saveActionDetails(String profileID, Action action) throws SevereException
public void saveActionDetails(String profileID, Action action) throws SevereException
{
{
StringBuilder finalQuery = new StringBuilder("save_action_details::");
ArrayList<String> a = new ArrayList<>();
//failsafes
if(action.getDisplayText().endsWith(":"))
action.setDisplayText(action.getDisplayText()+" ");
a.add(profileID);
finalQuery.append(profileID)
a.add(action.getID());
.append("::")
a.add(action.getActionType()+"");
.append(action.getID())
.append("::")
.append(action.getActionType())
.append("::");
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
{
{
finalQuery.append(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
{
a.add("no");
}
finalQuery.append("::");
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
finalQuery.append(action.getModuleName());
{
a.add(action.getModuleName());
}
else
{
a.add("nut");
}
finalQuery.append("::");
//display
//display
finalQuery.append(action.getBgColourHex())
a.add(action.getBgColourHex());
.append("::");
//icon
//icon
finalQuery.append(action.isHasIcon())
a.add(action.isHasIcon()+"");
.append("::")
a.add(action.isShowIcon()+"");
.append(action.isShowIcon())
.append("::");
//text
//text
finalQuery.append(action.isShowDisplayText())
a.add(action.isShowDisplayText()+"");
.append("::")
a.add(action.getDisplayTextFontColourHex());
.append(action.getDisplayTextFontColourHex())
a.add(action.getDisplayText());
.append("::")
a.add(action.getDisplayTextAlignment()+"");
.append(action.getDisplayText())
.append("::")
.append(action.getDisplayTextAlignment())
.append("::");
//location
//location
if(action.getLocation() == null)
if(action.getLocation() == null)
finalQuery.append("-1::-1::");
{
a.add("-1");
a.add("-1");
}
else
else
finalQuery.append(action.getLocation().getRow())
{
.append("::")
a.add(action.getLocation().getRow()+"");
.append(action.getLocation().getCol())
a.add(action.getLocation().getCol()+"");
.append("::");
}
a.add(action.getParent());
//client properties
//client properties
ClientProperties clientProperties = action.getClientProperties();
ClientProperties clientProperties = action.getClientProperties();
finalQuery.append(clientProperties.getSize())
.append("::");
a.add(clientProperties.getSize()+"");
for(Property property : clientProperties.get())
for(Property property : clientProperties.get())
{
{
finalQuery.append(property.getName())
a.add(property.getName());
.append("__")
a.add(property.getRawValue());
.append(property.getRawValue())
.append("__");
finalQuery.append("!!");
}
}
finalQuery.append("::")
.append(action.getParent())
.append("::");
writeToStream(finalQuery.toString());
Message message = new Message("save_action_details");
String[] x = new String[a.size()];
x = a.toArray(x);
message.setStringArrValue(x);
sendMessage(message);
}
}
public void deleteAction(String profileID, String actionID) throws SevereException
public void deleteAction(String profileID, String actionID) throws SevereException
{
{
writeToStream("delete_action::"+profileID+"::"+actionID);
Message message = new Message("delete_action");
message.setStringArrValue(profileID, actionID);
sendMessage(message);
}
}
public void saveClientDetails(String clientNickname, String screenWidth, String screenHeight, String defaultProfileID,
public void saveClientDetails(String clientNickname, String screenWidth, String screenHeight, String defaultProfileID,
String defaultThemeFullName) throws SevereException
String defaultThemeFullName) throws SevereException
{
{
writeToStream("save_client_details::"+
Message message = new Message("save_client_details");
clientNickname+"::"+
message.setStringArrValue(
screenWidth+"::"+
clientNickname,
screenHeight+"::"+
screenWidth,
defaultProfileID+"::"+
screenHeight,
defaultThemeFullName+"::");
defaultProfileID,
defaultThemeFullName
);
sendMessage(message);
client.setNickName(clientNickname);
client.setNickName(clientNickname);
client.setStartupDisplayWidth(Double.parseDouble(screenWidth));
client.setStartupDisplayWidth(Double.parseDouble(screenWidth));
client.setStartupDisplayHeight(Double.parseDouble(screenHeight));
client.setStartupDisplayHeight(Double.parseDouble(screenHeight));
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);
writeToStream("save_client_profile::"+
Message message = new Message("save_client_profile");
clientProfile.getID()+"::"+
clientProfile.getName()+"::"+
message.setStringArrValue(
clientProfile.getRows()+"::"+
clientProfile.getID(),
clientProfile.getCols()+"::"+
clientProfile.getName(),
clientProfile.getActionSize()+"::"+
clientProfile.getRows()+"",
clientProfile.getActionGap()+"::");
clientProfile.getCols()+"",
clientProfile.getActionSize()+"",
clientProfile.getActionGap()+""
);
sendMessage(message);
}
}
public void deleteProfile(String ID) throws SevereException
public void deleteProfile(String ID) throws SevereException
{
{
writeToStream("delete_profile::"+ID+"::");
Message message = new Message("delete_profile");
message.setStringValue(ID);
sendMessage(message);
}
}
public void actionClicked(String profileID, String actionID) {
public void actionClicked(Message message) {
try
try
{
{
String[] r = message.getStringArrValue();
String profileID = r[0];
String actionID = r[1];
Action action = client.getProfileByID(profileID).getActionByID(actionID);
Action action = client.getProfileByID(profileID).getActionByID(actionID);
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
{
{
NormalAction original = NormalActionPlugins.getInstance().getPluginByModuleName(
NormalAction original = NormalActionPlugins.getInstance().getPluginByModuleName(
action.getModuleName()
action.getModuleName()
);
);
if(original == null)
if(original == null)
{
{
throw new MinorException(
throw new MinorException(
"The action isn't installed on the server."
"The action isn't installed on the server."
);
);
}
}
NormalAction normalAction = original.clone();
NormalAction normalAction = original.clone();
normalAction.setLocation(action.getLocation());
normalAction.setLocation(action.getLocation());
normalAction.setDisplayText(action.getDisplayText());
normalAction.setDisplayText(action.getDisplayText());
normalAction.setID(actionID);
normalAction.setID(actionID);
normalAction.setClientProperties(action.getClientProperties());
normalAction.setClientProperties(action.getClientProperties());
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);
boolean result = serverListener.onNormalActionClicked(normalAction);
if(!result)
if(!result)
{
{
sendActionFailed(profileID, actionID);
sendActionFailed(profileID, actionID);
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
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 ...");
writeToStream("action_failed::"+
Message message = new Message("action_failed");
profileID+"::"+
message.setStringArrValue(profileID, actionID);
actionID+"::");
sendMessage(message);
}
}
}
}