41 Commits

Author SHA1 Message Date
praktimarc
b58ceaf732 Merge branch 'main' into Jul25 2025-07-22 00:03:07 +02:00
Marc Froehlich
ee5ee535bb <changeLog>
<changedVersionNumber>1.263</changedVersionNumber>
<date>2025-06-08</date>
<description>Airscout communication and Loginname</description>
<added> nothing </added>
<changed> The shema of AS-calculation messages from KST4Contest to Airscout had been changed due to some reports of Mats Helgöstam and other nice OMs who wasn´t able to track AP by the button. Before: EACH entry of the userlist had been sent to AirScout for AS plane path calculation in 12s intervals. EACH entry of the userlist had been added to the AirScout map. New in v1.263: Only entries of the userlist with a QRB lower than the setted max-QRB will be sent to AirScout for AS plane path calculation in 60s intervals. Only entries of the userlist with a QRB lower than the setted max-QRB will be added to the AS map. </changed>
<fixed> First: By changing the AS communication there is a huge decrease of the amount of messages which have to be queued by AS and also a huge decrease of the calculation operations of AS. That most likely will speed up also the issue of the very laggy "track in AS"-button. And also it will save a lot of computing power. The new 1min interval seems to be enough. Second: Name in chat is now saveable, whoohoo! Third: Some beauty fixes before and after login (visibiity of fields) 4th: Fixed issue which 9A2HM / Kreso told me. The name of the AS client had been hard wired to "KST" and the AS servers name had been hard wired to "AS", which results out of a time where I never mentioned to publish this client. It´s now fixed, so that the name-preferences will have a real effect.... 73 / DO5AMF </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.262</changedVersionNumber>
<date>2025-05-21</date>
<description>Freezes caused by getting messages before user login should be fixed now</description>
<added> nothing </added>
<changed> nothing </changed>
<fixed> ON4KST is delivering messages of stations which are not logged in already. That caused an error at the message processing engine which now should be fixed. </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.26</changedVersionNumber>
<date>2025-05</date>
<description>Login to multiple Channels via single signon / spend some colors</description>
<added> 1. UI: There is a dark mode, now. Switch in "Window -> use dark mode" 2. Usage of two Chatcategories at the same time. 3. opposite station multi-callsign login-tagging 73 / DO5AMF </added>
<changed> - coloring mechanic of the software. Modify colors via css by yourself... </changed>
<fixed> - Station tagging fixed completely </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.251</changedVersionNumber>
<date>2025-02</date>
<description>BUGFIX of 1.25, tnx Steve Clements!</description>
<added> - Steve spotted a problem in udp broadcast spot info reading, it´s now fixed! 73 / DO5AMF </added>
<changed> </changed>
<fixed> - Station tagging </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.25</changedVersionNumber>
<date>2025-02</date>
<description>Wishlist-time</description>
<added> - New configuration Tab: Messagehandling You can find options to wether auto-answering all messages which arriving or answer your CQ qrg automatically if someone asks you for it. - New configuration Tab: Messagehandling There you can configure the default userinfo-window message filter [for my friend Gianluca :-)] - There is a big amount of planned new features during april. Stay tuned! 73 / DO5AMF </added>
- Added coloured lines: new personal message rows will appear in red and changes its colours every 30 seconds as they get older, rainbow like via yellow to white (tnx Gianluca, good idea)
<changed> </changed>
<fixed> - Users with suffixes like "-2 and -70" had not been marked as worked. These will now be ignored and the stations will be marked correctly </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.24</changedVersionNumber>
<date>2024-11</date>
<description>Wishlist-time</description>
<added> - Button to show qrz.com profile of a selected station - Button to show qrzcq.com profile of a selected station </added>
- Added coloured lines: new personal message rows will appear in red and changes its colours every 30 seconds as they get older, rainbow like via yellow to white (tnx Gianluca, good idea)
<changed> </changed>
<fixed> - Users with suffixes like "-2 and -70" had not been marked as worked. These will now be ignored and the stations will be marked correctly </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.23</changedVersionNumber>
<date>2024-10</date>
<description>DXCluster Server is now implemented</description>
<added>- DXCluster Server (tnx OMAAO): KST4Contest inhibts a DXCluster server now. It generates a DXCluster message to feed your log client with station-reachable warnings. As a default, the dxcluster warnings will only be sent if a chatter writes to another and due to this is most likely pointing it´s antenna to your direction. For correct spot processing of your log program, you must use another spotters callsign than your contest callsign. Otherwise the filter will not work. </added>
<changed> </changed>
<fixed> </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.22</changedVersionNumber>
<date>2024-05</date>
<description>Increase usability, fixed AS button</description>
<added>- Variables (tnx OMAAO): * MYLOCATORSHORT * MYQRGSHORT * QRZNAME </added>
<changed>- Sendtext-field focus Focus is now on the text field when clicking on the list of people in the chat to avoid double clicking. You can just begin to type after clicking a callsign. </changed>
<fixed>- Worked-station-filter (tnx Gianluca) Filter is now live, if you activate the worked-filter, the worked(and user tagged not-qrv-for-this-band) will disappear without manually reactivating the filter - Chatters list sorting by QRB (tnx Alessandro) Fixed sorting, was lexicographically, now it´s handled as numbers - Airscout-showpath-button The button inhibits an arrow, directed to the selected station in the chatmembers list. A click to this button will now maximize AirScout which then shows the path and the airplanes which are reflectable to reach the selected station </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.21</changedVersionNumber>
<date>2024-04</date>
<description>Increase usability</description>
<added> </added>
<changed> - GUI-behaviour After a click to the save button, the sizes of all windows will be stored in the configfile and restored at the next startup of the client. Also the dividers of the splitpanels will be stored and restored. On problems delete config-file! Further the filters section is now a flowpane to make the software viewable at lower resolutions. </changed>
<fixed> </fixed>
<removed/>
</changeLog>
<changeLog>
<changedVersionNumber>1.2</changedVersionNumber>
<date>2024-04</date>
<description>Increase usability</description>
<added> - Selectable bands Its now possible to select which bands you want to activate. Please select your bands and click save and restart the software. There will only appear buttonds and field which are related to the bands which you have choosen. - Unworkable tags for each callsign. It´s now possible to set NOT-QRV tags for each station for each band. If an OM tells you for example, that he is not QRV at 144 MHz, you can set the "unworkable" flag for him and able to filter his callsign out of the chatmember-list - QTF-Arrow The button "show path in AS" now got an arrow which shows the QTF of the selected station while the button is still out of function (will work that out some time) </added>
<changed> </changed>
<fixed/>
<removed/>
</changeLog>
2025-07-21 23:52:37 +02:00
Marc Froehlich
5cca2923c2 * New variables: MYLOCATORSHORT, MYQRGSHORT, QRZNAME (Viliam Petrik)
* Sendtext-field focus is now on the text field when clicking on the list of people in the chat. You can just begin to type after clicking a callsign (Gian Luca)
* Worked-station-filter (tnx Gianluca) Filter is now live, if you activate the worked-filter, the worked (and user tagged not-qrv-for-this-band) will disappear without manually reactivating the filter
* Chatters list sorting by QRB (tnx Alessandro); sorting, was lexicographically, now it's handled as numbers
* Airscout-showpath-button works now
2024-05-16 10:08:47 +02:00
praktimarc
9169afbbc0 Update ChatPreferences.java 2024-05-03 00:06:42 +02:00
praktimarc
a8b58d6eb8 Update AirPlane.java 2024-05-03 00:05:13 +02:00
praktimarc
7adc3d54a8 Update AirPlane.java 2024-05-03 00:01:09 +02:00
praktimarc
6aeebfc21b Update MessageBusManagementThread.java 2024-05-02 23:56:10 +02:00
praktimarc
61877e0886 Update DBController.java 2024-05-02 23:54:48 +02:00
praktimarc
eac02aecc9 Update DirectionUtils.java 2024-05-02 23:42:23 +02:00
praktimarc
a51cb1afe6 Update Kst4ContestApplication.java 2024-05-02 23:41:04 +02:00
praktimarc
a898680149 Merge branch 'featureMessagefilter' into main 2024-05-02 23:16:05 +02:00
Marc Froehlich
1663b0fd7f - Windows-sizes and dividers of the panels will be saved now in the xml file
- changed the filter panel to a flowpanel to increase usability at smaller screens
2024-05-02 22:50:20 +02:00
Marc Froehlich
3e8783d7cd - There had been changes at the preferences xml and the database. Thatswhy for the DB there is an update method now and some checks if the XML is valid. That are simple checks, just to prevent crashing...
- Selectable bands
Its now possible to select which bands you want to activate. Please select your bands and
click save and restart the software. There will only appear buttonds and field which are
related to the bands which you have choosen.

- Unworkable tags for each callsign.
It´s now possible to set NOT-QRV tags for each station for each band. If an OM tells
you for example, that he is not QRV at 144 MHz, you can set the "unworkable" flag for him
and able to filter his callsign out of the chatmember-list

- QTF-Arrow
The button "show path in AS" now got an arrow which shows the QTF of the selected station
while the button is still out of function (will work that out some time)
2024-04-14 23:09:37 +02:00
Marc Froehlich
8bea4111f0 - introduced qrv tags for callsigns, only UI so far 2024-03-30 00:50:16 +01:00
Marc Froehlich
136cf08f08 - reachable function: If a message-sender writes another to ask a sked, I assume that his antenna is directed to this receiver-chatter.
If this causes that the sender-antenna is directed most likely in my direction (with a difference of ~25deg), the callsign will appear fat and green in the userlist. As the sender often propagates his frequency at the chat (that means, we have saved this already), there is a high probability to work him at this short term opportunity
- mark new connected stations
- made some UI improvements (Behaviour of messagefilter-radiobutton corrected)
- removed UI bug, caused if you send a message to your onwn station....
2024-03-17 23:35:13 +01:00
Marc Froehlich
e7d13401be implemented all filters to the chatmemberlist, activity-displays in chatmember table and userinfopanel, linked selected messages to the userinfopanel for better UI feeling, begin of AS-Showpath-function (not yet ready) 2024-02-27 23:35:18 +01:00
Marc Froehlich
d13b7785af implemented some of the new filters to the chatmemberlist, changed list-subtype to make it sortable again 2024-02-27 23:35:18 +01:00
Marc Froehlich
c369888c37 Changed lists mechanic: not 3 messagelists any more but one oversable messagelist for all messages. The 3 categories of messages are now filteredlists, derived from this global messagelist.
Added a new panel down of the userlist which will be dynamically generated and shows filtered messages to a selected callsign
2024-02-27 23:35:18 +01:00
praktimarc
7fe2930ee2 Merge pull request #5 from praktimarc/featureAudio_jan
Feature audio jan
2024-02-27 23:34:22 +01:00
Marc Froehlich
416ce5b82f Update information service mechanic implemented 2024-02-27 23:31:52 +01:00
Marc Froehlich
de87c217f6 Some bugfixes to make the client robust against crashes after deconnects 2024-02-27 23:31:52 +01:00
Marc Froehlich
be99925b62 Chat is now disconnectable and reconnectable without closing. Made some changes in the thread management to make that possible 2024-02-27 23:31:52 +01:00
Marc Froehlich
3602a252b4 added contextmenu to cq-message-table 2024-02-27 23:31:52 +01:00
Marc Froehlich
7f48698278 added audio support 2024-02-27 23:31:52 +01:00
Marc Froehlich
4549314446 added audio support 2024-02-27 23:31:52 +01:00
Marc Froehlich
eb04ad3f33 implemented all filters to the chatmemberlist, activity-displays in chatmember table and userinfopanel, linked selected messages to the userinfopanel for better UI feeling, begin of AS-Showpath-function (not yet ready) 2024-02-27 01:53:24 +01:00
Marc Froehlich
51712a1f85 implemented some of the new filters to the chatmemberlist, changed list-subtype to make it sortable again 2024-02-20 23:59:46 +01:00
Marc Froehlich
4a605f54ba Changed lists mechanic: not 3 messagelists any more but one oversable messagelist for all messages. The 3 categories of messages are now filteredlists, derived from this global messagelist.
Added a new panel down of the userlist which will be dynamically generated and shows filtered messages to a selected callsign
2024-02-18 02:39:37 +01:00
Marc Froehlich
037dc8a05b Update information service mechanic implemented 2024-02-08 23:52:08 +01:00
Marc Froehlich
476b4a7dd1 Some bugfixes to make the client robust against crashes after deconnects 2024-02-06 23:56:04 +01:00
Marc Froehlich
bd687dc50f Chat is now disconnectable and reconnectable without closing. Made some changes in the thread management to make that possible 2024-02-01 22:35:06 +01:00
Marc Froehlich
7bce7be2ba added contextmenu to cq-message-table 2024-01-26 22:42:45 +01:00
Marc Froehlich
3286a34a08 added audio support 2024-01-26 11:09:15 +01:00
Marc Froehlich
c2086a73b0 added audio support 2024-01-16 22:51:30 +01:00
praktimarc
686c277ac0 Merge pull request #3 from praktimarc/bugfix_nov
Bugfix nov
2023-11-21 23:34:06 +01:00
Marc Froehlich
d57880d945 fixed another bug which had been caused due to owncall is not longer in the userlist 2023-11-21 23:31:19 +01:00
Marc Froehlich
d79886d4c9 removed own callsign of userlist, which made neccessarry some changes for processing rxed commandlines of the server 2023-11-21 20:24:58 +01:00
praktimarc
eca0dfdf61 Merge pull request #2 from praktimarc/bugfix_nov
bugfixes in view and msgbus
2023-11-14 00:56:28 +01:00
Marc Froehlich
499b58965c changed way of db init 2023-11-14 00:50:10 +01:00
Marc Froehlich
7d9adeba1a changed way of db init 2023-11-13 00:23:12 +01:00
praktimarc
fcc46b3c3b Merge pull request #1 from praktimarc/CreateMavenProjectstructure
Create maven projectstructure
2023-11-10 23:27:26 +01:00
138 changed files with 27123 additions and 1146 deletions

View File

@@ -1 +1,2 @@
do5sa dr2x
oe3cin

15832
bugsept24.txt Normal file

File diff suppressed because it is too large Load Diff

3
jdk.cmd Normal file
View File

@@ -0,0 +1,3 @@
@echo off
SET JAVA_HOME=C:\Program Files\Java\jdk-17
SET PATH=%JAVA_HOME%\bin,%PATH%

0
null Normal file
View File

View File

@@ -5,4 +5,24 @@ public class ApplicationConstants {
* Name of the Application. * Name of the Application.
*/ */
public static final String APPLICATION_NAME = "praktiKST"; public static final String APPLICATION_NAME = "praktiKST";
/**
* Name of file to store preferences in.
*/
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.263;
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://do5amf.funkerportal.de/kst4ContestVersionInfo.xml";
public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml";
public static final String STYLECSSFILE_DEFAULT_DAYLIGHT = "KST4ContestDefaultDay.css";
public static final String STYLECSSFILE_DEFAULT_EVENING = "KST4ContestDefaultEvening.css";
public static final String DISCSTRING_DISCONNECT_AND_CLOSE = "CLOSEALL";
public static final String DISCSTRING_DISCONNECT_DUE_PAWWORDERROR = "JUSTDSICCAUSEPWWRONG";
public static final String DISCSTRING_DISCONNECTONLY = "ONLYDISCONNECT";
public static final String DISCONNECT_RDR_POISONPILL = "POISONPILL_KILLTHREAD"; //whereever a (blocking) udp or tcp reader in an infinite loop gets this message, it will break this loop
} }

View File

@@ -11,6 +11,7 @@ import java.net.UnknownHostException;
import java.util.TimerTask; import java.util.TimerTask;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import kst4contest.locatorUtils.Location;
import kst4contest.model.ChatMember; import kst4contest.model.ChatMember;
@@ -29,21 +30,29 @@ public class AirScoutPeriodicalAPReflectionInquirerTask extends TimerTask {
Thread.currentThread().setName("AirscoutPeriodicalReflectionInquirierTask"); Thread.currentThread().setName("AirscoutPeriodicalReflectionInquirierTask");
String KSTClientsNameForQuery = this.client.getChatPreferences().getAirScout_asClientNameString();
String ASServerNameStringForAnswer = this.client.getChatPreferences().getAirScout_asServerNameString();
//TODO: Manage prefixes kst and as via preferences file and instance //TODO: Manage prefixes kst and as via preferences file and instance
//TODO: Check if locator is changeable via the preferences object, need to be correct if it changes //TODO: Check if locator is changeable via the preferences object, need to be correct if it changes
DatagramSocket dsocket; DatagramSocket dsocket;
String prefix_asSetpath ="ASSETPATH: \"KST\" \"AS\" "; // String prefix_asSetpath ="ASSETPATH: \"KST\" \"AS\" "; //working original
String prefix_asWatchList = "ASWATCHLIST: \"KST\" \"AS\" "; // String prefix_asWatchList = "ASWATCHLIST: \"KST\" \"AS\" "; //working original
String prefix_asSetpath ="ASSETPATH: \"" + this.client.getChatPreferences().getAirScout_asClientNameString() + "\" \"" + this.client.getChatPreferences().getAirScout_asServerNameString() + "\" ";
String prefix_asWatchList = "ASWATCHLIST:\" "+ this.client.getChatPreferences().getAirScout_asClientNameString()+ "\" \"" + this.client.getChatPreferences().getAirScout_asServerNameString() + "\" ";
String bandString = "1440000"; String bandString = "1440000";
String myCallAndMyLocString = this.client.getChatPreferences().getLoginCallSign() + "," + this.client.getChatPreferences().getLoginLocator(); String myCallAndMyLocString = this.client.getChatPreferences().getStn_loginCallSign() + "," + this.client.getChatPreferences().getStn_loginLocatorMainCat();
String suffix = ""; //"FOREIGNCALL,FOREIGNLOC " -- dont forget the space at the end!!! String suffix = ""; //"FOREIGNCALL,FOREIGNLOC " -- dont forget the space at the end!!!
String asWatchListString = prefix_asWatchList + bandString + "," + myCallAndMyLocString; String asWatchListString = prefix_asWatchList + bandString + "," + myCallAndMyLocString;
String asWatchListStringSuffix = asWatchListString; String asWatchListStringSuffix = asWatchListString;
String host = "255.255.255.255"; String host = "255.255.255.255";
int port = 9872; // int port = 9872;
int port = client.getChatPreferences().getAirScout_asCommunicationPort();
// byte[] message = "ASSETPATH: \"KST\" \"AS\" 1440000,DO5AMF,JN49GL,OK1MZM,JN89IW ".getBytes(); Original, ging // byte[] message = "ASSETPATH: \"KST\" \"AS\" 1440000,DO5AMF,JN49GL,OK1MZM,JN89IW ".getBytes(); Original, ging
InetAddress address; InetAddress address;
@@ -61,8 +70,13 @@ public class AirScoutPeriodicalAPReflectionInquirerTask extends TimerTask {
for (ChatMember i : ary_threadSafeChatMemberArray) { for (ChatMember i : ary_threadSafeChatMemberArray) {
if (i.getQrb() < this.client.getChatPreferences().getStn_maxQRBDefault())
//Here: check if maximum distance to the chatmember is reached, only ask AS if distance is lower!
{
suffix = i.getCallSign() + "," + i.getQra() + " "; suffix = i.getCallSign() + "," + i.getQra() + " ";
//
String queryStringToAirScout = ""; String queryStringToAirScout = "";
queryStringToAirScout += prefix_asSetpath + bandString + "," + myCallAndMyLocString + "," + suffix; queryStringToAirScout += prefix_asSetpath + bandString + "," + myCallAndMyLocString + "," + suffix;
@@ -77,95 +91,19 @@ public class AirScoutPeriodicalAPReflectionInquirerTask extends TimerTask {
dsocket.send(packet); dsocket.send(packet);
dsocket.close(); dsocket.close();
} catch (UnknownHostException e1) { } catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} catch (NoRouteToHostException e) { } catch (NoRouteToHostException e) {
e.printStackTrace(); e.printStackTrace();
} } catch (SocketException e) {
catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// System.out.println("[ASUDPTask, info:] sent query " + queryStringToAirScout); // System.out.println("[ASUDPTask, info:] sent query " + queryStringToAirScout);
asWatchListStringSuffix += "," + i.getCallSign() + "," + i.getQra(); asWatchListStringSuffix += "," + i.getCallSign() + "," + i.getQra();
} }
}
// for (Iterator iterator = praktiKSTActiveUserList.iterator(); iterator.hasNext();) {
// ChatMember chatMember = (ChatMember) iterator.next();
//
// suffix = chatMember.getCallSign() + "," + chatMember.getQra() + " ";
//
// String queryStringToAirScout = "";
//
// queryStringToAirScout += prefix_asSetpath + bandString + "," + myCallAndMyLocString + "," + suffix;
//
// byte[] queryStringToAirScoutMSG = queryStringToAirScout.getBytes();
//
// try {
// address = InetAddress.getByName("255.255.255.255");
// DatagramPacket packet = new DatagramPacket(queryStringToAirScoutMSG, queryStringToAirScoutMSG.length, address, port);
// dsocket = new DatagramSocket();
// dsocket.setBroadcast(true);
// dsocket.send(packet);
// dsocket.close();
// } catch (UnknownHostException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// } catch (SocketException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
//// System.out.println("[ASUDPTask, info:] sent query " + queryStringToAirScout);
//
// asWatchListStringSuffix += "," + chatMember.getCallSign() + "," + chatMember.getQra();
//
// }}
// for (Iterator iterator = praktiKSTActiveUserList.iterator(); iterator.hasNext();) {
// ChatMember chatMember = (ChatMember) iterator.next();
//
// suffix = chatMember.getCallSign() + "," + chatMember.getQra() + " ";
//
// String queryStringToAirScout = "";
//
// queryStringToAirScout += prefix_asSetpath + bandString + "," + myCallAndMyLocString + "," + suffix;
//
// byte[] queryStringToAirScoutMSG = queryStringToAirScout.getBytes();
//
// try {
// address = InetAddress.getByName("255.255.255.255");
// DatagramPacket packet = new DatagramPacket(queryStringToAirScoutMSG, queryStringToAirScoutMSG.length, address, port);
// dsocket = new DatagramSocket();
// dsocket.setBroadcast(true);
// dsocket.send(packet);
// dsocket.close();
// } catch (UnknownHostException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// } catch (SocketException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
//// System.out.println("[ASUDPTask, info:] sent query " + queryStringToAirScout);
//
// asWatchListStringSuffix += "," + chatMember.getCallSign() + "," + chatMember.getQra();
//
// }
/** /**
* As next we will set the ASWatchlist. All stations in chat will be watched by airscout causing following code.\n\n * As next we will set the ASWatchlist. All stations in chat will be watched by airscout causing following code.\n\n
@@ -183,14 +121,7 @@ public class AirScoutPeriodicalAPReflectionInquirerTask extends TimerTask {
dsocket.setBroadcast(true); dsocket.setBroadcast(true);
dsocket.send(packet); dsocket.send(packet);
dsocket.close(); dsocket.close();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -33,30 +33,74 @@ public class BeaconTask extends TimerTask {
ChatMessage beaconMSG = new ChatMessage(); ChatMessage beaconMSG = new ChatMessage();
String replaceVariables = this.chatController.getChatPreferences().getBcn_beaconText(); String replaceVariables = this.chatController.getChatPreferences().getBcn_beaconTextMainCat();
// replaceVariables = bcn_beaconText;
replaceVariables = replaceVariables.replaceAll("MYQRG", this.chatController.getChatPreferences().getMYQRG().getValue()); replaceVariables = replaceVariables.replaceAll("MYQRG", this.chatController.getChatPreferences().getMYQRGFirstCat().getValue());
replaceVariables = replaceVariables.replaceAll("MYCALL", this.chatController.getChatPreferences().getLoginCallSign()); replaceVariables = replaceVariables.replaceAll("MYCALL", this.chatController.getChatPreferences().getStn_loginCallSign());
replaceVariables = replaceVariables.replaceAll("MYLOCATOR", this.chatController.getChatPreferences().getLoginLocator()); replaceVariables = replaceVariables.replaceAll("MYLOCATOR", this.chatController.getChatPreferences().getStn_loginLocatorMainCat());
replaceVariables = replaceVariables.replaceAll("MYQTF", this.chatController.getChatPreferences().getActualQTF().getValue() + ""); replaceVariables = replaceVariables.replaceAll("MYQTF", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
replaceVariables = replaceVariables.replaceAll("SECONDQRG", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
beaconMSG.setMessageText( beaconMSG.setMessageText(
"MSG|" + this.chatController.getChatPreferences().getLoginChatCategory().getCategoryNumber() + "|0|" + replaceVariables + "|0|"); "MSG|" + this.chatController.getChatPreferences().getLoginChatCategoryMain().getCategoryNumber() + "|0|" + replaceVariables + "|0|");
beaconMSG.setMessageDirectedToServer(true); beaconMSG.setMessageDirectedToServer(true);
// System.out.println("########### " + replaceVariables);
if (this.chatController.getChatPreferences().isBcn_beaconsEnabled() ) {
ChatMessage beaconMSG2 = new ChatMessage();
String replaceVariables2 = this.chatController.getChatPreferences().getBcn_beaconTextSecondCat();
replaceVariables2 = replaceVariables2.replaceAll("MYQRG", this.chatController.getChatPreferences().getMYQRGFirstCat().getValue());
replaceVariables2 = replaceVariables2.replaceAll("MYCALL", this.chatController.getChatPreferences().getStn_loginCallSign());
replaceVariables2 = replaceVariables2.replaceAll("MYLOCATOR", this.chatController.getChatPreferences().getStn_loginLocatorMainCat());
replaceVariables2 = replaceVariables2.replaceAll("MYQTF", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
replaceVariables2 = replaceVariables2.replaceAll("SECONDQRG", this.chatController.getChatPreferences().getMYQRGSecondCat().getValue() + "");
beaconMSG2.setMessageText(
"MSG|" + this.chatController.getChatPreferences().getLoginChatCategorySecond().getCategoryNumber() + "|0|" + replaceVariables + "|0|");
beaconMSG2.setMessageDirectedToServer(true);
/**
* beacon 1st Chatcategory
*/
if (this.chatController.getChatPreferences().isBcn_beaconsEnabledMainCat() ) {
System.out.println(new Utils4KST().time_generateCurrentMMDDhhmmTimeString() System.out.println(new Utils4KST().time_generateCurrentMMDDhhmmTimeString()
+ " [BeaconTask, Info]: Sending CQ: " + beaconMSG.getMessageText()); + " [BeaconTask, Info]: Sending CQ: " + beaconMSG.getMessageText());
this.chatController.getMessageTXBus().add(beaconMSG); this.chatController.getMessageTXBus().add(beaconMSG);
} else { } else {
//do nothing, CQ is disabled //do nothing, CQ is disabled
} }
/**
* beacon 2nd Chatcategory
*/
if (this.chatController.getChatPreferences().isLoginToSecondChatEnabled()) { //only send if 2nd cat enabled
if (this.chatController.getChatPreferences().isBcn_beaconsEnabledSecondCat()) {
beaconMSG2.setMessageText(
"MSG|" + this.chatController.getChatPreferences().getLoginChatCategorySecond().getCategoryNumber() + "|0|" + replaceVariables2 + "|0|");
beaconMSG2.setMessageDirectedToServer(true);
System.out.println(new Utils4KST().time_generateCurrentMMDDhhmmTimeString()
+ " [BeaconTask, Info]: Sending CQ 2nd Cat: " + beaconMSG2.getMessageText());
this.chatController.getMessageTXBus().add(beaconMSG2);
} else {
//do nothing, CQ is disabled
}
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -27,8 +27,7 @@ public class DBController {
private static final DBController dbcontroller = new DBController(); private static final DBController dbcontroller = new DBController();
private static Connection connection; private static Connection connection;
// private static final String DB_PATH = System.getProperty("praktiKST.db"); // private static final String DB_PATH = System.getProperty("praktiKST.db");
private static final String DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE); private static String DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE);
/* /*
static { static {
@@ -62,6 +61,9 @@ public class DBController {
} }
private void initDBConnection() { private void initDBConnection() {
System.out.println("DBH: initiate new db connection");
try { try {
ApplicationFileUtils.copyResourceIfRequired( ApplicationFileUtils.copyResourceIfRequired(
ApplicationConstants.APPLICATION_NAME, ApplicationConstants.APPLICATION_NAME,
@@ -71,7 +73,17 @@ public class DBController {
if (connection != null) if (connection != null)
return; return;
System.out.println("Creating Connection to Database..."); System.out.println("Creating Connection to Database...");
DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE);
connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH); connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);
//connection = DriverManager.getConnection("jdbc:sqlite:" + "C:\\Users\\prakt\\.praktiKST\\praktiKST.db");
System.out.println("[DBH, Info]: Path = " + DB_PATH);
if (!connection.isClosed()) if (!connection.isClosed())
System.out.println("...Connection established"); System.out.println("...Connection established");
} catch (SQLException e) { } catch (SQLException e) {
@@ -91,6 +103,75 @@ public class DBController {
} }
} }
}); });
versionUpdateOfDBCheckAndChangeV11ToV12(); //TODO: newer version DB update should be called here
}
/**
* While the first version of this software has other needs to the db tables than the 1.2 and following versions
* this method will check if the database file of the user is compatible and make it compatible if it´s not.
* <br/>
* v1.1 -> v1.2: Chatmember entities will get additional fields for not-QRV-band-info
* <br/>
* I check only the first field "notqrv144", if it does not exist, I creating all fields neccessarry for v1.2
*/
public void versionUpdateOfDBCheckAndChangeV11ToV12() {
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT * FROM ChatMember where notQRV144 != 0;");
stmt.close();
} catch (SQLException ex) {
System.out.println("DBH, Info: updating DB fields for version change v1.1 -> v1.2");
try {
PreparedStatement ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV144 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV432 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV1240 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV2300 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV3400 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV5600 BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement(
"ALTER TABLE ChatMember ADD notQRV10G BOOLEAN DEFAULT 0" + ";");
ps.addBatch();
ps.executeBatch();
connection.setAutoCommit(false);
connection.setAutoCommit(true);
} catch (SQLException e) {
}
}
} }
// private void handleDB() { // private void handleDB() {
@@ -158,6 +239,7 @@ public class DBController {
* "worked3400" BOOLEAN,<br/> * "worked3400" BOOLEAN,<br/>
* "worked5600" BOOLEAN,<br/> * "worked5600" BOOLEAN,<br/>
* "worked10G" BOOLEAN,<br/> * "worked10G" BOOLEAN,<br/>
* <br/><b>!!! since v1.2 there is a not-qrv info for each band, too !!!</b>
* *
* @throws SQLException * @throws SQLException
*/ */
@@ -170,7 +252,7 @@ public class DBController {
// if (!rs.next()) { // if (!rs.next()) {
PreparedStatement ps = connection.prepareStatement( PreparedStatement ps = connection.prepareStatement(
"INSERT OR IGNORE INTO ChatMember VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(callsign) DO UPDATE SET qra = '" "INSERT OR IGNORE INTO ChatMember VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(callsign) DO UPDATE SET qra = '"
+ chatMemberToStore.getQra() + "', name = '" + chatMemberToStore.getName() + chatMemberToStore.getQra() + "', name = '" + chatMemberToStore.getName()
+ "', lastActivityDateTime = '" + chatMemberToStore.getLastActivity() + "', lastActivityDateTime = '" + chatMemberToStore.getLastActivity()
+ "' where callsign = '" + chatMemberToStore.getCallSign() + "';"); + "' where callsign = '" + chatMemberToStore.getCallSign() + "';");
@@ -187,6 +269,16 @@ public class DBController {
ps.setInt(10, helper_booleanIntConverter(chatMemberToStore.isWorked3400())); ps.setInt(10, helper_booleanIntConverter(chatMemberToStore.isWorked3400()));
ps.setInt(11, helper_booleanIntConverter(chatMemberToStore.isWorked5600())); ps.setInt(11, helper_booleanIntConverter(chatMemberToStore.isWorked5600()));
ps.setInt(12, helper_booleanIntConverter(chatMemberToStore.isWorked10G())); ps.setInt(12, helper_booleanIntConverter(chatMemberToStore.isWorked10G()));
/**
* Here starts v1.2
*/
ps.setInt(13, helper_booleanIntConverter(!chatMemberToStore.isQrv144()));
ps.setInt(14, helper_booleanIntConverter(!chatMemberToStore.isQrv432()));
ps.setInt(15, helper_booleanIntConverter(!chatMemberToStore.isQrv1240()));
ps.setInt(16, helper_booleanIntConverter(!chatMemberToStore.isQrv2300()));
ps.setInt(17, helper_booleanIntConverter(!chatMemberToStore.isQrv3400()));
ps.setInt(18, helper_booleanIntConverter(!chatMemberToStore.isQrv5600()));
ps.setInt(19, helper_booleanIntConverter(!chatMemberToStore.isQrv10G()));
ps.addBatch(); ps.addBatch();
@@ -206,7 +298,7 @@ public class DBController {
} catch (SQLException e) { } catch (SQLException e) {
System.err.println("[DBH, ERROR:] Chatmember could not been stored."); System.err.println("[DBH, ERROR:] Chatmember could not been stored.");
e.printStackTrace(); e.printStackTrace();
connection.close(); // connection.close(); //Todo commented out due to errors
} }
} }
@@ -259,6 +351,18 @@ public class DBController {
updateWkdData.setWorked5600(helper_IntToBooleanConverter(rs.getInt("worked5600"))); updateWkdData.setWorked5600(helper_IntToBooleanConverter(rs.getInt("worked5600")));
updateWkdData.setWorked10G(helper_IntToBooleanConverter(rs.getInt("worked10G"))); updateWkdData.setWorked10G(helper_IntToBooleanConverter(rs.getInt("worked10G")));
/**
* v1.2 since here
*/
updateWkdData.setQrv144(!helper_IntToBooleanConverter(rs.getInt("notQRV144")));
updateWkdData.setQrv432(!helper_IntToBooleanConverter(rs.getInt("notQRV432")));
updateWkdData.setQrv1240(!helper_IntToBooleanConverter(rs.getInt("notQRV1240")));
updateWkdData.setQrv2300(!helper_IntToBooleanConverter(rs.getInt("notQRV2300")));
updateWkdData.setQrv3400(!helper_IntToBooleanConverter(rs.getInt("notQRV3400")));
updateWkdData.setQrv5600(!helper_IntToBooleanConverter(rs.getInt("notQRV5600")));
updateWkdData.setQrv10G(!helper_IntToBooleanConverter(rs.getInt("notQRV10G")));
fetchedWorkeddata.put(updateWkdData.getCallSign(), updateWkdData); fetchedWorkeddata.put(updateWkdData.getCallSign(), updateWkdData);
// System.out.println( // System.out.println(
@@ -301,15 +405,10 @@ public class DBController {
ResultSet rs = stmt ResultSet rs = stmt
.executeQuery("SELECT * FROM ChatMember where callsign = '" + checkForThis.getCallSign() + "' ;"); .executeQuery("SELECT * FROM ChatMember where callsign = '" + checkForThis.getCallSign() + "' ;");
// ChatMember updateWkdData; // System.out.println("DBH stmt: " + rs.getStatement().toString());
// if (!rs.isBeforeFirst()) { //if there are no data to update....
while (rs.next()) { while (rs.next()) {
// updateWkdData = new ChatMember();
// updateWkdData.setCallSign(rs.getString("callsign"));
checkForThis.setWorked(helper_IntToBooleanConverter(rs.getInt("worked"))); checkForThis.setWorked(helper_IntToBooleanConverter(rs.getInt("worked")));
checkForThis.setWorked144(helper_IntToBooleanConverter(rs.getInt("worked144"))); checkForThis.setWorked144(helper_IntToBooleanConverter(rs.getInt("worked144")));
checkForThis.setWorked432(helper_IntToBooleanConverter(rs.getInt("worked432"))); checkForThis.setWorked432(helper_IntToBooleanConverter(rs.getInt("worked432")));
@@ -319,12 +418,26 @@ public class DBController {
checkForThis.setWorked5600(helper_IntToBooleanConverter(rs.getInt("worked5600"))); checkForThis.setWorked5600(helper_IntToBooleanConverter(rs.getInt("worked5600")));
checkForThis.setWorked10G(helper_IntToBooleanConverter(rs.getInt("worked10G"))); checkForThis.setWorked10G(helper_IntToBooleanConverter(rs.getInt("worked10G")));
System.out.println( /**
"[DBH, Info:] providing callsign wkd info, wkd, 144, 432, ... for UA5 new chatmember : " * v1.2 since here
+ checkForThis.toString()); */
checkForThis.setQrv144(!helper_IntToBooleanConverter(rs.getInt("notQRV144")));
checkForThis.setQrv432(!helper_IntToBooleanConverter(rs.getInt("notQRV432")));
checkForThis.setQrv1240(!helper_IntToBooleanConverter(rs.getInt("notQRV1240")));
checkForThis.setQrv2300(!helper_IntToBooleanConverter(rs.getInt("notQRV2300")));
checkForThis.setQrv3400(!helper_IntToBooleanConverter(rs.getInt("notQRV3400")));
checkForThis.setQrv5600(!helper_IntToBooleanConverter(rs.getInt("notQRV5600")));
checkForThis.setQrv10G(!helper_IntToBooleanConverter(rs.getInt("notQRV10G")));
// System.out.println(
// "[DBH, Info:] providing callsign wkd info, wkd, 144, 432, ....... for UA5 new chatmember : "
// + checkForThis.toString());
} }
// }
// rs.gets
rs.close(); rs.close();
stmt.close(); stmt.close();
@@ -338,7 +451,7 @@ public class DBController {
try { try {
connection.close(); connection.close();
} catch (SQLException e1) { } catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} }
} }
@@ -354,6 +467,8 @@ public class DBController {
* new contest period</b> <br/> * new contest period</b> <br/>
* <br/> * <br/>
* *
* modified for work with v1.2
*
* @return true if reset was successful * @return true if reset was successful
* *
* @throws SQLException * @throws SQLException
@@ -363,7 +478,8 @@ public class DBController {
try { try {
Statement stmt = connection.createStatement(); Statement stmt = connection.createStatement();
int affected = stmt.executeUpdate("update ChatMember set worked = 0, worked144 = 0, worked432 = 0, worked1240 = 0, worked2300 = 0, worked3400 = 0, worked5600 = 0, worked10G = 0;"); int affected = stmt.executeUpdate("update ChatMember set worked = 0, worked144 = 0, worked432 = 0, worked1240 = 0, worked2300 = 0, worked3400 = 0, worked5600 = 0, worked10G = 0" +
", notQrv144 = 0, notQrv432 = 0, notQrv1240 = 0, notQrv2300 = 0, notQrv3400 = 0, notQrv5600 = 0, notQrv10G = 0;");
stmt.close(); stmt.close();
@@ -503,6 +619,77 @@ public class DBController {
} }
} }
public boolean updateNotQRVInfoOnChatMember(ChatMember chatMemberToStore) throws SQLException {
try {
Statement stmt = connection.createStatement();
/**
* at first, mark the station as worked, always
*/
PreparedStatement ps = connection.prepareStatement("UPDATE ChatMember set notQrv144 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv144()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv432 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv432()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv1240 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv1240()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv2300 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv2300()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv3400 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv3400()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv5600 = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv5600()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
ps = connection.prepareStatement("UPDATE ChatMember set notQrv10G = ? WHERE CallSign = ?");
ps.setInt(1, helper_booleanIntConverter(!chatMemberToStore.isQrv10G()));
ps.setString(2, chatMemberToStore.getCallSign());
ps.addBatch();
ps.executeBatch();
connection.setAutoCommit(false);
connection.setAutoCommit(true);
stmt.close();
} catch (SQLException e) {
System.err.println("[DBH, ERROR:] Couldn't handle DB-Query");
e.printStackTrace();
connection.close();
return false;
}
return true;
}
private int helper_booleanIntConverter(boolean convertToInt) { private int helper_booleanIntConverter(boolean convertToInt) {
if (convertToInt) { if (convertToInt) {
@@ -514,9 +701,13 @@ public class DBController {
private boolean helper_IntToBooleanConverter(int valueFromDBField) { private boolean helper_IntToBooleanConverter(int valueFromDBField) {
// System.out.println(">>>>>>>>>>>>>>> DBC: " + valueFromDBField + " -> ");
if (valueFromDBField != 0) { if (valueFromDBField != 0) {
System.out.println("true");
return true; return true;
} else } else
System.out.println("false");
return false; return false;
} }
@@ -531,12 +722,17 @@ public class DBController {
dummy.setName("Team Test"); dummy.setName("Team Test");
dummy.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); dummy.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
dummy.setWorked5600(true); dummy.setWorked5600(true);
// dbc.versionUpdateOfDBCheckAndChangeV11ToV12();
// dbc.fetchChatMemberNOTQRVBandInfoForOnlyOneCallsignFromDB();
// dbc.updateNOTQRVBandInfoOnChatMember();
// dummy.setWorked432(true); // dummy.setWorked432(true);
// dbc.storeChatMember(dummy); // dbc.storeChatMember(dummy);
dbc.updateWkdInfoOnChatMember(dummy); // dbc.updateWkdInfoOnChatMember(dummy);
// dbc.handleDB(); // dbc.handleDB();
} }
} }

View File

@@ -0,0 +1,196 @@
//package kst4contest.controller;
//
//import kst4contest.model.ChatMember;
//import kst4contest.model.ChatMessage;
//
//import java.io.*;
//import java.net.ServerSocket;
//import java.net.Socket;
//import java.nio.channels.ServerSocketChannel;
//import java.nio.channels.SocketChannel;
//import java.time.Instant;
//
///**
// * This thread is responsible for providing DXCluster messages for a connected log program.
// *
// *
// */
////public class DXClusterController extends Thread {
// PrintWriter outTelnet;
// BufferedReader inTelnet;
// private Socket socket;
// private ChatController client;
//// private OutputStream output;
//// private InputStream input;
//
// private ChatMessage messageTextRaw;
//
// private static final int PORT = 23;
// private static final String USERNAME = "user";
// private static final String PASSWORD = "pass";
// private Socket clientSocket;
//
//
//
//
//// public DXClusterController(Socket clientSocket, ChatController client) throws InterruptedException {
////
//// this.client = client;
////
//// try {
//// outTelnet = new PrintWriter(clientSocket.getOutputStream(), true);
//// inTelnet = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//// } catch (IOException e) {
//// throw new RuntimeException(e);
//// }
//// System.out.println("defcons");
//// this.clientSocket = clientSocket;
////
//// }
//
// public DXClusterController(Socket clientSocket, ChatController chatController) {
//
// try {
// socket = clientSocket;
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// this.client = chatController;
//
// try {
// outTelnet = new PrintWriter(socket.getOutputStream(), true);
// inTelnet = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// System.out.println("[DXCCtrl, info:] DXCluster Controller created!");
// this.clientSocket = socket;
// }
//
// public DXClusterController(Socket clientSocket, ObjectOutputStream objectout, ChatController chatController) {
//
// try {
// socket = clientSocket;
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// this.client = chatController;
//
// try {
// outTelnet = new PrintWriter(socket.getOutputStream(), true);
// inTelnet = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// System.out.println("[DXCCtrl, info:] DXCluster Controller created!");
// this.clientSocket = socket;
// }
//
//// public DXClusterController(ServerSocket clientSocket, ChatController client) throws InterruptedException {
//// //TODO: GOT FROM https://stackoverflow.com/questions/15541804/creating-the-serversocket-in-a-separate-thread
//// try {
//// socket = clientSocket.accept(2);
//// } catch (IOException e) {
//// throw new RuntimeException(e);
//// }
//// this.client = client;
////
//// try {
//// outTelnet = new PrintWriter(socket.getOutputStream(), true);
//// inTelnet = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//// } catch (IOException e) {
//// throw new RuntimeException(e);
//// }
//// System.out.println("defcons");
//// this.clientSocket = socket;
////
//// }
//
//// public DXClusterController(ServerSocketChannel serverSocketChannel, ChatController client) throws InterruptedException {
////
//// this.client = client;
////
////// clientSocketChannel.ac
////
//// try {
////
//// serverSocketChannel.accept();
//// serverSocketChannel.rea
////
//// outTelnet = new PrintWriter(clientSocket.getOutputStream(), true);
//// inTelnet = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//// } catch (IOException e) {
//// throw new RuntimeException(e);
//// }
//// System.out.println("defcons");
//// this.clientSocket = clientSocket;
////
//// }
//
// public boolean terminateConnection() throws IOException {
//
//// this.output.close();
// this.socket.close();
//
// return true;
// }
//
// public void sendLocalClusterMessage() {
//
// }
//
// public void run() {
//// try (
//// PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
//// BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())))
//// {
//
//// out.println("Welcome to the Telnet Server");
// outTelnet.print("login: ");
// outTelnet.flush();
// try {
// String user = inTelnet.readLine();
// } catch (IOException ex) {
// throw new RuntimeException(ex);
// }
//// finally {
//// try {
//// clientSocket.close();
//// } catch (Exception e) {
//// System.out.println("Error closing client socket: " + e.getMessage());
//// }
//// }
//
//
//// for (int i = 0; i < 10; i++) {
////
//// outTelnet.println("DX de DM5M: 144222.0 DO5AMF JN49FL 2250Z\n");
//// }
//
//
//
// }
//
// /**
// * Sends a DX cluster message to the connected log programs via telnet, returns true if sent
// *
// * @param aChatMember
// * @return
// */
// public boolean propagateSingleDXClusterEntry(ChatMember aChatMember) {
//
// String singleDXClusterMessage = "DX de ";
//
// singleDXClusterMessage += client.getChatPreferences().getLoginCallSign() + " ";
// singleDXClusterMessage += aChatMember.getFrequency().getValue() + " ";
// singleDXClusterMessage += aChatMember.getCallSign().toUpperCase() + " ";
// singleDXClusterMessage += aChatMember.getQra().toUpperCase() + " ";
// singleDXClusterMessage += new Utils4KST().time_generateCurrenthhmmZTimeStringForClusterMessage() + "\n";
//
// outTelnet.println(singleDXClusterMessage);
// outTelnet.flush();
// return true;
// }
//}

View File

@@ -0,0 +1,215 @@
package kst4contest.controller;
import kst4contest.model.ChatMember;
import kst4contest.model.ChatPreferences;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DXClusterThreadPooledServer implements Runnable{
private List<Socket> clientSockets = Collections.synchronizedList(new ArrayList<>()); //list of all connected clients
ChatController chatController = null;
protected int serverPort = 8080;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread= null;
protected ExecutorService threadPool =
Executors.newFixedThreadPool(10);
Socket clientSocket;
public DXClusterThreadPooledServer(int port, ChatController chatController){
this.serverPort = port;
this.chatController = chatController;
}
public void run(){
synchronized(this){
this.runningThread = Thread.currentThread();
runningThread.setName("DXCluster-thread-pooled-server");
}
openServerSocket();
while(! isStopped()){
clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
synchronized(clientSockets) {
clientSockets.add(clientSocket); // add dx cluster client to the "clients list" for broadcasting
}
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped.") ;
break;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
DXClusterServerWorkerRunnable worker = new DXClusterServerWorkerRunnable(clientSocket, "Thread Pooled DXCluster Server ", chatController, clientSockets);
this.threadPool.execute(worker);
}
this.threadPool.shutdown();
System.out.println("Server Stopped.") ;
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
try {
this.serverSocket.close();
synchronized(clientSockets) {
for (Socket socket : clientSockets) {
socket.close(); // close all client connections
}
}
} catch (IOException e) {
throw new RuntimeException("DXCCSERVER Error closing server", e);
}
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("DXCCSERVER Cannot open port ", e);
}
}
/**
* Sends a DX cluster message to ALL connected log programs via telnet, returns true if sent
*
* @param aChatMember
* @return boolean true if message had been sent
*/
public boolean broadcastSingleDXClusterEntryToLoggers(ChatMember aChatMember) {
synchronized(clientSockets) {
System.out.println("DXClusterSrvr: broadcasting message to clients: " + clientSockets.size());
try {
System.out.println("-------------> ORIGINALEE VAL: " + aChatMember.getFrequency().getValue());
System.out.println("-------------> NORMALIZED VAL: " + Utils4KST.normalizeFrequencyString(aChatMember.getFrequency().getValue(), chatController.getChatPreferences().getNotify_optionalFrequencyPrefix()) + " ");
} catch (Exception e) {
System.out.println("DXCThPooledServer: Error accessing value in chatmember object: " + e.getMessage());
// e.printStackTrace();
}
for (Socket socket : clientSockets) {
try {
OutputStream output = socket.getOutputStream();
String singleDXClusterMessage = "DX de ";
// singleDXClusterMessage += chatController.getChatPreferences().getLoginCallSign() + ": ";
singleDXClusterMessage += this.chatController.getChatPreferences().getNotify_DXCSrv_SpottersCallSign().getValue() + ": ";
singleDXClusterMessage += Utils4KST.normalizeFrequencyString(aChatMember.getFrequency().getValue(), chatController.getChatPreferences().getNotify_optionalFrequencyPrefix()) + " ";
singleDXClusterMessage += aChatMember.getCallSign().toUpperCase() + " "; //we need such an amount of spaces for n1mm to work, otherwise bullshit happens
singleDXClusterMessage += aChatMember.getQra().toUpperCase() + " ";
singleDXClusterMessage += new Utils4KST().time_generateCurrenthhmmZTimeStringForClusterMessage() + ((char)7) + ((char)7) + "\r\n";
// singleDXClusterMessage += chatController.getChatPreferences().getLoginCallSign() + ": ";
// singleDXClusterMessage += Utils4KST.normalizeFrequencyString(aChatMember.getFrequency().getValue(), chatController.getChatPreferences().getNotify_optionalFrequencyPrefix()) + " ";
// singleDXClusterMessage += aChatMember.getCallSign().toUpperCase() + " ";
// singleDXClusterMessage += aChatMember.getQra().toUpperCase() + " ";
// singleDXClusterMessage += new Utils4KST().time_generateCurrenthhmmZTimeStringForClusterMessage() + ((char)7) + ((char)7) + "\r\n";
output.write((singleDXClusterMessage).getBytes());
} catch (IOException e) {
e.printStackTrace();
System.out.println("[DXClusterSrvr, Error:] broadcasting DXC-message to clients went wrong!");
return false;
}
}
}
return true; //if message had been sent, return true for "ok"
}
}
class DXClusterServerWorkerRunnable implements Runnable{
protected Socket clientSocket = null;
protected String serverText = null;
private ChatController client = null;
private List<Socket> dxClusterClientSocketsConnectedList;
public DXClusterServerWorkerRunnable(Socket clientSocket, String serverText, ChatController chatController, List<Socket> clientSockets) {
this.clientSocket = clientSocket;
this.serverText = serverText;
this.client = chatController;
this.dxClusterClientSocketsConnectedList = clientSockets;
}
public void run() {
try {
OutputStream output = clientSocket.getOutputStream();
dxClusterClientSocketsConnectedList.add(clientSocket);
Timer dXCkeepAliveTimer = new Timer();
dXCkeepAliveTimer.schedule(new TimerTask() {
@Override
public void run() {
for (Socket socket : dxClusterClientSocketsConnectedList) {
try {
OutputStream output = socket.getOutputStream();
output.write(("\r\n").getBytes());
} catch (IOException e) {
e.printStackTrace();
System.out.println("[DXClusterSrvr, Error:] broadcasting DXC-message to clients went wrong!");
dXCkeepAliveTimer.purge();
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
finally {
this.cancel();
}
dxClusterClientSocketsConnectedList.remove(socket); //if socket is closed by client, remove it from the broadcast list and close it
}
}
}
}, 30000, 30000);
output.write(("login: ").getBytes()); //say hello to the client, it will answer with a callsign
System.out.println("[DXClusterThreadPooledServer, Info:] New cluster client connected! "); //TODO: maybe integrate non blocking reader for client identification
} catch (IOException e) {
e.printStackTrace();
} finally {
synchronized(dxClusterClientSocketsConnectedList) {
dxClusterClientSocketsConnectedList.remove(clientSocket); // Entferne den Client nach Verarbeitung
}
}
}
}

View File

@@ -0,0 +1,44 @@
package kst4contest.controller;
import javafx.beans.property.SimpleStringProperty;
import kst4contest.model.ChatMember;
import kst4contest.model.ChatPreferences;
public class DXClusterThreadPooledServerTest {
public static void main(String[] args) {
ChatController client = new ChatController();
ChatPreferences testPreferences = new ChatPreferences();
testPreferences.setStn_loginCallSign("DM5M");
client.setChatPreferences(testPreferences);
DXClusterThreadPooledServer dxClusterServer = new DXClusterThreadPooledServer(8000, client);
new Thread(dxClusterServer).start();
try {
Thread.sleep(10 * 1000);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>ready.....go!");
} catch (InterruptedException e) {
e.printStackTrace();
}
ChatMember test = new ChatMember();
test.setCallSign("DL5ASG");
test.setQra("JO51HK");
test.setFrequency(new SimpleStringProperty("144776.0"));
dxClusterServer.broadcastSingleDXClusterEntryToLoggers(test);
// try {
// Thread.sleep(20 * 3333);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("Stopping Server");
// server.stop();
}
}

View File

@@ -43,7 +43,7 @@ public class InputReaderThread extends Thread {
e.printStackTrace(); e.printStackTrace();
} }
ownMSG.setMessageText("MSG|" + this.client.getCategory().getCategoryNumber() + "|0|" + sendThisMessage23001 + "|0|"); ownMSG.setMessageText("MSG|" + this.client.getChatCategoryMain().getCategoryNumber() + "|0|" + sendThisMessage23001 + "|0|");
// System.out.println("inreader " + ownMSG.getMessage() + client.getMessageTXBus().size()); // System.out.println("inreader " + ownMSG.getMessage() + client.getMessageTXBus().size());

View File

@@ -5,22 +5,23 @@ import java.io.PrintWriter;
import java.sql.SQLException; import java.sql.SQLException;
//import java.net.Socket; //import java.net.Socket;
//import java.util.ArrayList; //import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import kst4contest.model.AirPlaneReflectionInfo; import kst4contest.ApplicationConstants;
import kst4contest.model.ChatMember; import kst4contest.locatorUtils.DirectionUtils;
import kst4contest.model.ChatMessage; import kst4contest.locatorUtils.Location;
import kst4contest.model.ClusterMessage; import kst4contest.model.*;
/** /**
* *
* This thread is responsible for processing rx and tx messages, synchronize tx * This thread is responsible for processing received messages.
* and rx and saving the whole chat content in a textfile and write the text to * It checks all messages from server for their functional contest, such as commands to build or change the userlist
* the stdio. * or their settings, get clustermessages and sure the content of all chatmessages, which are delivered.
* *
*/ */
public class MessageBusManagementThread extends Thread { public class MessageBusManagementThread extends Thread {
@@ -38,6 +39,7 @@ public class MessageBusManagementThread extends Thread {
private Hashtable<String, ChatMember> chatMemberTable; private Hashtable<String, ChatMember> chatMemberTable;
private final String PTRN_USERLISTENTRY = "([a-zA-Z0-9]{2}/{1})?([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z]{0,3})(/p)? [a-zA-Z]{2}[0-9]{2}[a-zA-Z]{2} [ -~]{1,20}"; private final String PTRN_USERLISTENTRY = "([a-zA-Z0-9]{2}/{1})?([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z]{0,3})(/p)? [a-zA-Z]{2}[0-9]{2}[a-zA-Z]{2} [ -~]{1,20}";
private final String PTRN_QRG_CAT2 = "(([0-9]{3,4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)"; private final String PTRN_QRG_CAT2 = "(([0-9]{3,4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)";
private final String PTRN_QRG_CAT3 = "(([0-9]{3,5}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)";
// BufferedWriter bufwrtrDBGMSGOut; // BufferedWriter bufwrtrDBGMSGOut;
// private String text; // private String text;
@@ -68,7 +70,6 @@ public class MessageBusManagementThread extends Thread {
* check if a chatmessage is part of the userlist via telnet 23000 port<br/> * check if a chatmessage is part of the userlist via telnet 23000 port<br/>
* <b>Updates userlist!</b> * <b>Updates userlist!</b>
* *
* @param chatMessage
*/ */
private void checkIfItsUserListEntry(ChatMessage messageToProcess) { private void checkIfItsUserListEntry(ChatMessage messageToProcess) {
@@ -109,9 +110,7 @@ public class MessageBusManagementThread extends Thread {
/** /**
* check if a chatmessage is part of the userlist via telnet 23000 port<br/> * check if a chatmessage is part of the userlist via telnet 23000 port<br/>
* <b>Updates userlist!</b> * <b>This method updates the userlist!</b>
*
* @param chatMessage
*/ */
private void checkIfItsUserListEntry23001(ChatMessage messageToProcess) { private void checkIfItsUserListEntry23001(ChatMessage messageToProcess) {
@@ -154,38 +153,29 @@ public class MessageBusManagementThread extends Thread {
* check if a chatmessage or a name of a chatmember contains a frequency<br/> * check if a chatmessage or a name of a chatmember contains a frequency<br/>
* <b>returns String = "" if no frequency found</b> * <b>returns String = "" if no frequency found</b>
* *
* @param chatMessage
*/ */
private String checkIfMessageInhibitsFrequency(ChatMessage messageToProcess) { private String checkIfMessageInhibitsFrequency(ChatMessage messageToProcess) {
Pattern pattern = Pattern.compile(PTRN_QRG_CAT2); // TODO: PTRN should depend to category-selection of own stn Pattern pattern = Pattern.compile(PTRN_QRG_CAT2); // TODO: PTRN should depend to category-selection of own stn, it´s not the case now
Matcher matcher = pattern.matcher(messageToProcess.getMessageText()); Matcher matcher = pattern.matcher(messageToProcess.getMessageText());
String[] splittedQRGString; String[] splittedQRGString;
// splittedQRGString[0] = "0"; // splittedQRGString[0] = "0";
String stringAggregation = ""; String stringAggregation = "";
// if (matcher.) {
// stringAggregation = ""; //reset aggregated string
// }
while (matcher.find()) { while (matcher.find()) {
// System.out.println("QRG detected: "+ matcher.group() + " " + matcher.start());
// ChatMember member = new ChatMember();
String matchedString = matcher.group(); String matchedString = matcher.group();
// splittedQRGString = new String[0];
splittedQRGString = matchedString.split(" "); splittedQRGString = matchedString.split(" ");
for (int i = 0; i < splittedQRGString.length; i++) { for (String s : splittedQRGString) {
stringAggregation += splittedQRGString[i] + " "; stringAggregation += s + " ";
} }
System.out.println("[MSGBUSMGT:] Processed qrg info: " + stringAggregation); System.out.println("[MSGBUSMGT:] Processed qrg info: " + stringAggregation);
// if (member.getName().)
// System.out.println("Processed QRG Entry [" + this.client.getChatMemberTable().size() + "]: Call: " // System.out.println("Processed QRG Entry [" + this.client.getChatMemberTable().size() + "]: Call: "
// + member.getCallSign() + ", QRA: " + member.getQra() + ", Name: " + member.getName()); // + member.getCallSign() + ", QRA: " + member.getQra() + ", Name: " + member.getName());
} }
@@ -196,6 +186,7 @@ public class MessageBusManagementThread extends Thread {
* Builds UserList and gets meta informations out of the chat, as far as it is * Builds UserList and gets meta informations out of the chat, as far as it is
* possible. \n This is the only place where the Chatmember-List will be written * possible. \n This is the only place where the Chatmember-List will be written
* *
* Old Method for port 23000, raw text interface without any comfort, no longer used
* @param messageToProcess * @param messageToProcess
*/ */
private void processRXMessage23000(ChatMessage messageToProcess) { private void processRXMessage23000(ChatMessage messageToProcess) {
@@ -208,7 +199,7 @@ public class MessageBusManagementThread extends Thread {
messageToProcess.setMessageText(reduce); messageToProcess.setMessageText(reduce);
if (messageToProcess.getMessageText().isEmpty()) { if (messageToProcess.getMessageText().isEmpty()) {
System.out.println("[MSGBUSMGTT:] ######################no processable data"); // System.out.println("[MSGBUSMGTT:] ###################### no processable data");
} else { } else {
if (reduce.length() >= 14 && reduce.length() <= 40) { if (reduce.length() >= 14 && reduce.length() <= 40) {
@@ -269,26 +260,35 @@ public class MessageBusManagementThread extends Thread {
// System.out.println("[MsgBusMgr, ERROR:] ChecklistForChatMemberIndexByCallsign, not found: " // System.out.println("[MsgBusMgr, ERROR:] ChecklistForChatMemberIndexByCallsign, not found: "
// + lookForThis.getCallSign() + "\n "); // + lookForThis.getCallSign() + "\n ");
/*** /***
* Old mechanic for index search,new one implemented due concurrentmodificationexcm which works - end * /Old mechanic for index search,new one implemented due concurrentmodificationexc which works - end
* *
*/ */
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
if (list.get(i).getCallSign().equals(lookForThis.getCallSign())) { if (list.get(i).getCallSign().equals(lookForThis.getCallSign())) {
//TODO: New since 1.26! Check against category!
System.out.println("MSGBUSMGT, DEBUG: Checking Chatcategories of found list member " + list.get(i).getCallSign() + " / " + list.get(i).getChatCategory() + " against " + lookForThis.getCallSign() + " / " + lookForThis.getChatCategory());
// System.out // System.out
// .println("MSGBUSHELBER: Found " + chatMember.getCallSign() + " at " + list.indexOf(chatMember)); // .println("MSGBUSHELBER: Found " + chatMember.getCallSign() + " at " + list.indexOf(chatMember));
if (list.get(i).getChatCategory().equals(lookForThis.getChatCategory())) { //new 1.26
return list.indexOf(list.get(i)); return list.indexOf(list.get(i));
} } //new 1.26
else {
System.out.println("MSGBUSMGT, DEBUG: Category does not match");
} }
// for (Iterator iterator = list.iterator(); iterator.hasNext();) { // System.out.println("--------------------------- chatcategory of list.get(i) = " + list.get(i).getChatCategory().getCategoryNumber());
// ChatMember chatMember = (ChatMember) iterator.next(); System.out.println("--------------------------- chatcategory of lookforthisChatMember = " + lookForThis.getChatCategory().getCategoryNumber() );
// System.out.println(list.indexOf(lookForThis) + ": " + chatMember.getCallSign()); }
// } // return list.indexOf(list.get(i)); //if no category found, return entry //TODO: ERROR detected here! Should work now, needs some proof
// return -1; //if category dont match, return: member not found
}
return -1; // if it´s not found, the method will always end here and return -1 return -1; // if it´s not found, the method will always end here and return -1
} }
/** /**
@@ -326,6 +326,22 @@ public class MessageBusManagementThread extends Thread {
final String SRVR_LOGINWRONGCALLSYNTAX = "103"; final String SRVR_LOGINWRONGCALLSYNTAX = "103";
final String SRVR_LOGINWRONGCALLUNKNOWN = "101"; final String SRVR_LOGINWRONGCALLUNKNOWN = "101";
/**
* here we have a helper Set for identifying questions for my qrg which can be autoanswered later // TODO: move to an extra method
*/
final HashSet<String> qrgQuestionTexts = new HashSet<String>();
// final ArrayList<String> qrgQuestionTexts = new ArrayList<String>();
qrgQuestionTexts.add("ur qrg?");
qrgQuestionTexts.add("your qrg?");
qrgQuestionTexts.add("qrg?");
qrgQuestionTexts.add("freq?");
qrgQuestionTexts.add("pse QRG");
/**
* here we have a helper list for identifying questions for my qrg which can be autoanswered later
*/
if (messageToProcess.getMessageText().isEmpty()) { if (messageToProcess.getMessageText().isEmpty()) {
System.out.println("[MSGBUSMGTT:] ######################no processable data"); System.out.println("[MSGBUSMGTT:] ######################no processable data");
@@ -346,23 +362,35 @@ public class MessageBusManagementThread extends Thread {
/** /**
* Initializes the Userlist if entry fits UA0 * Initializes the Userlist if entry fits UA0
* UA0|3|DL6SAQ|walter not qrv|JN58CK|1| <- RXed
*
*/ */
if (splittedMessageLine[0].contains(INITIALUSERLISTENTRY)) { if (splittedMessageLine[0].contains(INITIALUSERLISTENTRY)) {
// System.out.println("MSGBUS: User detected"); // System.out.println("MSGBUS: User detected");
ChatMember newMember = new ChatMember(); ChatMember newMember = new ChatMember();
newMember.setAirPlaneReflectInfo(new AirPlaneReflectionInfo()); // TODO: Only bugfix, check newMember.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
newMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
newMember.setCallSign(splittedMessageLine[2]); newMember.setCallSign(splittedMessageLine[2]);
newMember.setName(splittedMessageLine[3]); newMember.setName(splittedMessageLine[3]);
newMember.setQra(splittedMessageLine[4]); newMember.setQra(splittedMessageLine[4]);
newMember.setState(Integer.parseInt(splittedMessageLine[5])); newMember.setState(Integer.parseInt(splittedMessageLine[5]));
newMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); // newMember.setQTFdirection(LocatorUtils);
newMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), newMember.getQra()));
newMember.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(newMember.getQra())));
newMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());//TODO evt obsolete!
newMember.setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
// this.client.getChatMemberTable().put(splittedMessageLine[2], newMember); //TODO: map -> List // this.client.getChatMemberTable().put(splittedMessageLine[2], newMember); //TODO: map -> List
//the own call will not be in the list
if (!client.getChatPreferences().getStn_loginCallSign().equals(newMember.getCallSign())) {
this.client.getLst_chatMemberList().add(newMember); this.client.getLst_chatMemberList().add(newMember);
}
this.client.getDbHandler().storeChatMember(newMember); this.client.getDbHandler().storeChatMember(newMember);
@@ -376,24 +404,39 @@ public class MessageBusManagementThread extends Thread {
/** /**
* Actualize Userlist, add new entry UA5 or UA2 * Actualize Userlist, add new entry UA5 or UA2
*
* UA5|2|IU4CHE|Giorgio 2-70-23|JN64GB|2|
* UA2|2|W5ADD|Parker|EM40WL|2|
*
*/ */
if (splittedMessageLine[0].contains(USERENTEREDCHAT) || splittedMessageLine[0].contains(USERENTEREDCHAT2)) { if (splittedMessageLine[0].contains(USERENTEREDCHAT) || splittedMessageLine[0].contains(USERENTEREDCHAT2)) {
// System.out.println("MSGBUS: User detected"); // System.out.println("MSGBUS: User detected");
if (!client.getChatPreferences().getStn_loginCallSign().equals(splittedMessageLine[2])) { //own call ignore
ChatMember newMember = new ChatMember(); ChatMember newMember = new ChatMember();
newMember.setAirPlaneReflectInfo(new AirPlaneReflectionInfo()); newMember.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
newMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
newMember.setCallSign(splittedMessageLine[2]); newMember.setCallSign(splittedMessageLine[2]);
newMember.setName(splittedMessageLine[3]); newMember.setName(splittedMessageLine[3]);
newMember.setQra(splittedMessageLine[4]); newMember.setQra(splittedMessageLine[4]);
newMember.setState(Integer.parseInt(splittedMessageLine[5])); newMember.setState(Integer.parseInt(splittedMessageLine[5]));
newMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); newMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
newMember.setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
newMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), newMember.getQra()));
newMember.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(newMember.getQra())));
newMember = this.client.getDbHandler().fetchChatMemberWkdDataForOnlyOneCallsignFromDB(newMember); newMember = this.client.getDbHandler().fetchChatMemberWkdDataForOnlyOneCallsignFromDB(newMember);
this.client.getLst_chatMemberList().add(newMember); this.client.getLst_chatMemberList().add(newMember);
this.client.getDbHandler().storeChatMember(newMember); this.client.getDbHandler().storeChatMember(newMember);
}
// this.client.getChatMemberTable().put(splittedMessageLine[2], newMember); // this.client.getChatMemberTable().put(splittedMessageLine[2], newMember);
@@ -409,9 +452,9 @@ public class MessageBusManagementThread extends Thread {
ChatMember newMember = new ChatMember(); ChatMember newMember = new ChatMember();
newMember.setCallSign(splittedMessageLine[2]); newMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
// this.client.getChatMemberTable().remove(newMember.getCallSign()); newMember.setCallSign(splittedMessageLine[2]);
System.out.println("[MSGBUSMGT, Info:] User left Chat and will be removed from list [" System.out.println("[MSGBUSMGT, Info:] User left Chat and will be removed from list ["
+ this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign()); + this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign());
@@ -419,6 +462,8 @@ public class MessageBusManagementThread extends Thread {
this.client.getLst_chatMemberList().remove( this.client.getLst_chatMemberList().remove(
checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), newMember)); checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), newMember));
//TODO: since 1.26 new method design to detect chatcategory, too!
} catch (Exception e) { } catch (Exception e) {
System.out.println("[MSGBUSMGT, EXC!, Error:] User sent left chat but had not been there ... [" System.out.println("[MSGBUSMGT, EXC!, Error:] User sent left chat but had not been there ... ["
+ this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign() + "\n" + this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign() + "\n"
@@ -448,93 +493,252 @@ public class MessageBusManagementThread extends Thread {
* CH|2|1663966535|DM5M|dm5m-team|0|kst4contest.test|0| * CH|2|1663966535|DM5M|dm5m-team|0|kst4contest.test|0|
*/ */
if (splittedMessageLine[0].contains(CHATCHANNELMESSAGE)) { if (splittedMessageLine[0].contains(CHATCHANNELMESSAGE)) {
// System.out.println("MSGBUS: User detected");
ChatMessage newMessage = new ChatMessage(); //experimental 1.26: multi channel messages
newMessage.setChatCategory(this.client.getCategory()); ChatMessage newMessageArrived = new ChatMessage();
newMessage.setMessageGeneratedTime(splittedMessageLine[2]); // TODO: insert readable time? ChatCategory chategoryForMessageAndMessageSender;
newMessageArrived.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
chategoryForMessageAndMessageSender = newMessageArrived.getChatCategory();
newMessageArrived.setMessageGeneratedTime(splittedMessageLine[2]);
if (splittedMessageLine[3].equals("SERVER")) { if (splittedMessageLine[3].equals("SERVER")) {
ChatMember dummy = new ChatMember(); ChatMember dummy = new ChatMember();
dummy.setCallSign("SERVER"); dummy.setCallSign("SERVER");
dummy.setName("Sysop"); dummy.setName("Sysop");
newMessage.setSender(dummy); newMessageArrived.setSender(dummy);
newMessageArrived.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
dummy.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
// System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> servers cat " + newMessageArrived.getChatCategory());
} else { } else {
ChatMember temp = new ChatMember(); ChatMember sender = new ChatMember();
temp.setCallSign(splittedMessageLine[3]); sender.setCallSign(splittedMessageLine[3]);
sender.setChatCategory(chategoryForMessageAndMessageSender);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), sender);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), temp);
if (index != -1) { if (index != -1) {
//user not found in the chatmember list
newMessage.setSender(this.client.getLst_chatMemberList().get(index)); // set sender to member of try {
newMessageArrived.setSender(this.client.getLst_chatMemberList().get(index)); // set sender to member of
this.client.getLst_chatMemberList().get(index).setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
} catch (Exception exc) {
ChatMember aSenderDummy = new ChatMember();
aSenderDummy.setCallSign(splittedMessageLine[3] + "[n/a]");
aSenderDummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
newMessageArrived.setSender(aSenderDummy);
System.out.println("MsgBusmgtT: Catched Error! " + exc.getMessage() + " // " + splittedMessageLine[3] + " is not in the list! Faking sender!");
exc.printStackTrace();
}
// b4 init list // b4 init list
} else { } else {
//user not found in chatmember list, mark it, sender can not be set
if (!temp.getCallSign().equals(this.client.getChatPreferences().getLoginCallSign().toUpperCase())) { if (!sender.getCallSign().equals(this.client.getChatPreferences().getStn_loginCallSign().toUpperCase())) {
temp.setCallSign("[n/a]" + temp.getCallSign()); sender.setCallSign("[n/a]" + sender.getCallSign());
} // if someone sent a message without being in the userlist (cause
// on4kst missed implementing....), callsign will be marked
newMessage.setSender(temp); // if someone sent a message without being in the userlist (cause } else {
// on4kst missed implementing....) //that means, message was by own station, broadcasted to all other
}
// newMessage.setSender(this.client.getChatMemberTable().get(splittedMessageLine[3]));
}
newMessage.setMessageSenderName(splittedMessageLine[4]);
newMessage.setMessageText(splittedMessageLine[6]);
if (splittedMessageLine[7].equals("0")) {
// message is not directed to anyone
ChatMember dummy = new ChatMember(); ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL"); dummy.setCallSign("ALL");
newMessage.setReceiver(dummy); newMessageArrived.setReceiver(dummy);
this.client.getLst_toAllMessageList().add(0, newMessage); // sdtout to all message-List AirPlaneReflectionInfo preventNullpointerExc = new AirPlaneReflectionInfo();
preventNullpointerExc.setAirPlanesReachableCntr(0);
} else { sender.setAirPlaneReflectInfo(preventNullpointerExc);
newMessageArrived.setSender(sender); //my own call is the sender
ChatMember temp2 = new ChatMember(); }
temp2.setCallSign(splittedMessageLine[7]);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), temp2);
if (index != -1) {
newMessage.setReceiver(this.client.getLst_chatMemberList().get(index));// -1: Member left Chat
// before...
} else {
temp2.setCallSign(temp2.getCallSign() + "(left)");
newMessage.setReceiver(temp2);
} }
System.out.println("message directed to: " + newMessage.getReceiver().getCallSign() + ". EQ?: " + this.client.getownChatMemberObject().getCallSign() + " sent by: " + newMessage.getSender().getCallSign().toUpperCase() + " -> EQ?: "+ this.client.getChatPreferences().getLoginCallSign().toUpperCase()); // newMessageArrived.setSender(this.client.getChatMemberTable().get(splittedMessageLine[3]));
}
if (newMessage.getReceiver().getCallSign() newMessageArrived.setMessageSenderName(splittedMessageLine[4]);
.equals(this.client.getChatPreferences().getLoginCallSign())) { newMessageArrived.setMessageText(splittedMessageLine[6]);
this.client.getLst_toMeMessageList().add(0, newMessage); if (splittedMessageLine[7].equals("0")) {
// message is not directed to anyone, move it to the cq messages!
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
newMessageArrived.setReceiver(dummy);
System.out.println("message directed to me: " + newMessage.getReceiver().getCallSign() + "."); this.client.getLst_globalChatMessageList().add(0, newMessageArrived); // sdtout to all message-List
} else if (newMessage.getSender().getCallSign().toUpperCase() // if you sent the message, it will be sorted in to
// the "to you message list"
.equals(this.client.getChatPreferences().getLoginCallSign().toUpperCase())) {
String originalMessage = newMessage.getMessageText();
newMessage
.setMessageText("(>" + newMessage.getReceiver().getCallSign() + ")" + originalMessage);
this.client.getLst_toMeMessageList().add(0, newMessage); // TODO:check
} else { } else {
this.client.getLst_toOtherMessageList().add(0, newMessage); //message is directed to another chatmember, process as such!
// System.out.println("MSGBS bgfx: tx call = " + newMessage.getSender().getCallSign() + " / rx call = " + newMessage.getReceiver().getCallSign()); ChatMember receiver = new ChatMember();
receiver.setChatCategory(chategoryForMessageAndMessageSender); //got out of message itself
receiver.setCallSign(splittedMessageLine[7]);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), receiver);
if (index != -1) {
newMessageArrived.setReceiver(this.client.getLst_chatMemberList().get(index));// -1: Member left Chat
// before...
} else { //found in active member list
if (receiver.getCallSign().equals(client.getChatPreferences().getStn_loginCallSign())) {
/**
* If mycallsign sent a message to the server, server will publish that message and
* send it to all chatmember including me.
* As mycall is not in the userlist, the message would not been displayed if I handle
* it in the next case (marking left user, just for information). But I want an echo.
*/
receiver.setCallSign(client.getChatPreferences().getStn_loginCallSign());
newMessageArrived.setReceiver(receiver);
} else {
//this are user which left chat but had been adressed by this message
receiver.setCallSign(receiver.getCallSign() + "(left)");
newMessageArrived.setReceiver(receiver);
}
}
// System.out.println("message directed to: " + newMessageArrived.getReceiver().getCallSign() + ". EQ?: " + this.client.getownChatMemberObject().getCallSign() + " sent by: " + newMessageArrived.getSender().getCallSign().toUpperCase() + " -> EQ?: "+ this.client.getChatPreferences().getLoginCallSign().toUpperCase());
try {
/**
* message is directed to me, will be put in the "to me" messagelist
*/
if (newMessageArrived.getReceiver().getCallSign()
.equals(this.client.getChatPreferences().getStn_loginCallSign())) {
// this.client.getLst_toMeMessageList().add(0, newMessageArrived); //TODO: change, moved to globalmessagelist, original
this.client.getLst_globalChatMessageList().add(0, newMessageArrived); //TODO: change, moved to globalmessagelist, original
if (this.client.getChatPreferences().isNotify_playSimpleSounds()) {
this.client.getPlayAudioUtils().playNoiseLauncher('P');
}
if (this.client.getChatPreferences().isNotify_playCWCallsignsOnRxedPMs()) {
this.client.getPlayAudioUtils().playCWLauncher(" " + " " + newMessageArrived.getSender().getCallSign().toUpperCase());
}
if (this.client.getChatPreferences().isNotify_playVoiceCallsignsOnRxedPMs()) {
this.client.getPlayAudioUtils().playVoiceLauncher( "?" + newMessageArrived.getSender().getCallSign().toUpperCase());
}
if (this.client.getChatPreferences().isNotify_playSimpleSounds()) {
if (newMessageArrived.getMessageText().toUpperCase().contains("//BELL")) {
this.client.getPlayAudioUtils().playVoiceLauncher("!");
}
}
if (this.client.getChatPreferences().isMsgHandling_autoAnswerEnabled()) {
ChatMessage automaticAnswer = new ChatMessage();
ChatMember itsMe = new ChatMember();
itsMe.setCallSign(this.client.getChatPreferences().getStn_loginCallSign());
automaticAnswer.setSender(itsMe);
automaticAnswer.setReceiver(newMessageArrived.getSender());
automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " " + this.client.getChatPreferences().getMessageHandling_autoAnswerTextMainCat());
this.client.getMessageTXBus().add(automaticAnswer);
}
/**
* auto reply/answer to QRG requests is here
*/
if (this.client.getChatPreferences().isMessageHandling_autoAnswerToQRGRequestEnabled()) {
for (String lookForQRGString : qrgQuestionTexts) {
if (newMessageArrived.getMessageText().contains(lookForQRGString)) {
ChatMessage automaticAnswer = new ChatMessage();
ChatMember itsMe = new ChatMember();
itsMe.setCallSign(this.client.getChatPreferences().getStn_loginCallSign());
automaticAnswer.setSender(itsMe);
automaticAnswer.setReceiver(newMessageArrived.getSender());
automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue());
if (this.client.getChatPreferences().isLoginToSecondChatEnabled()) {
automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRGs: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue() + " / " + this.client.getChatPreferences().getMYQRGSecondCat().getValue());
} else {
automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue());
}
this.client.getMessageTXBus().add(automaticAnswer);
}
}
}
System.out.println("message directed to me: " + newMessageArrived.getReceiver().getCallSign() + ".");
} else if (newMessageArrived.getSender().getCallSign().toUpperCase()
.equals(this.client.getChatPreferences().getStn_loginCallSign().toUpperCase())) {
/**
* message sent by me!
* message from me will appear in the PM window, too, with (>CALLSIGN) before
*/
String originalMessage = newMessageArrived.getMessageText();
newMessageArrived
.setMessageText("(>" + newMessageArrived.getReceiver().getCallSign() + ")" + originalMessage);
this.client.getLst_globalChatMessageList().add(0,newMessageArrived);
// if you sent the message to another station, it will be sorted in to
// the "to me message list" with modified messagetext, added rxers callsign
} else {
//message sent to other user
// this.client.getLst_toOtherMessageList().add(0, newMessageArrived); //TODO: change, moved to globalmessagelist, original
if (DirectionUtils.isInAngleAndRange(client.getChatPreferences().getStn_loginLocatorMainCat(),
newMessageArrived.getSender().getQra(),
newMessageArrived.getReceiver().getQra(),
client.getChatPreferences().getStn_maxQRBDefault(),
client.getChatPreferences().getStn_antennaBeamWidthDeg())) {
if (this.client.getChatPreferences().isNotify_playSimpleSounds()) {
//play only tick sound if the sender was not set directedtome before
if (!newMessageArrived.getSender().isInAngleAndRange()) {
this.client.getPlayAudioUtils().playNoiseLauncher('-');
}
}
newMessageArrived.getSender().setInAngleAndRange(true);
if (client.getChatPreferences().isNotify_dxClusterServerEnabled()) {
try {
if (newMessageArrived.getSender().getFrequency() != null) {
this.client.getDxClusterServer().broadcastSingleDXClusterEntryToLoggers(newMessageArrived.getSender()); //tells the DXCluster server to send a DXC message for this member to the logbook software
}
} catch (Exception exception) {
System.out.println("[MSGBUSMGT, ERROR:] DXCluster messageserver error while processing spot for 0" + newMessageArrived.getSender().getCallSign() + " // " + exception.getMessage());
exception.printStackTrace();
}
}
System.out.println(">>>>>>>>>> Anglewarning <<<<<<<<<< " + newMessageArrived.getSender().getCallSign() + ", " + newMessageArrived.getSender().getQra() + " -> " + newMessageArrived.getReceiver().getCallSign() + ", " + newMessageArrived.getReceiver().getQra() + " = " +
new Location(newMessageArrived.getSender().getQra()).getBearing(new Location(newMessageArrived.getReceiver().getQra())) +
" / sender bearing to me: " + new Location(newMessageArrived.getSender().getQra()).getBearing(new Location(client.getChatPreferences().getStn_loginLocatorMainCat())));
} else {
System.out.println("-notinangle- " + newMessageArrived.getSender().getCallSign() + ", " + newMessageArrived.getSender().getQra() + " -> " + newMessageArrived.getReceiver().getCallSign() + ", " + newMessageArrived.getReceiver().getQra() + " = " +
new Location(newMessageArrived.getSender().getQra()).getBearing(new Location(newMessageArrived.getReceiver().getQra())) +
" ; sender bearing to me: " + new Location(newMessageArrived.getSender().getQra()).getBearing(new Location(client.getChatPreferences().getStn_loginLocatorMainCat())));
newMessageArrived.getSender().setInAngleAndRange(false);
}
this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
}
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
System.out.println("MSGBS bgfx, <<<catched error>>>: referenced user left the chat during messageprocessing or message got before user entered chat message: " + referenceDeletedByUserLeftChatDuringMessageprocessing.getStackTrace());
// referenceDeletedByUserLeftChatDuringMessageprocessing.printStackTrace();
} }
// sdtout to me message-List // sdtout to me message-List
// newMessage.setReceiver(this.client.getChatMemberTable().get(splittedMessageLine[7])); // set sender // newMessageArrived.setReceiver(this.client.getChatMemberTable().get(splittedMessageLine[7])); // set sender
// to the // to the
// member of // member of
// before // before
@@ -542,11 +746,16 @@ public class MessageBusManagementThread extends Thread {
// list // list
} }
// System.out.println("[MSGBUSMGT:] processed message: " + newMessage.getChatCategory().getCategoryNumber() try {
// + " " + newMessage.getSender().getCallSign() + ", " + newMessage.getMessageSenderName() + " -> "
// + newMessage.getReceiver().getCallSign() + ": " + newMessage.getMessageText());
String locatedFrequencies = checkIfMessageInhibitsFrequency(newMessage); System.out.println("[MSGBUSMGT:] processed message: " + newMessageArrived.getChatCategory().getCategoryNumber()
+ " " + newMessageArrived.getSender().getCallSign() + ", " + newMessageArrived.getMessageSenderName() + " -> "
+ newMessageArrived.getReceiver().getCallSign() + ": " + newMessageArrived.getMessageText());
} catch (Exception exceptionOccured) {
System.out.println("[MSGMgtBus: ERROR CHATCHED ON MAYBE NULL ISSUE]: " + exceptionOccured.getMessage() + "\n" + exceptionOccured.getStackTrace());
}
String locatedFrequencies = checkIfMessageInhibitsFrequency(newMessageArrived);
SimpleStringProperty qrg = new SimpleStringProperty(locatedFrequencies); SimpleStringProperty qrg = new SimpleStringProperty(locatedFrequencies);
@@ -556,14 +765,10 @@ public class MessageBusManagementThread extends Thread {
// no qrg found, nothing to do // no qrg found, nothing to do
} else { } else {
// String stringAggregation = "";
//
// for (int i = 0; i < locatedFrequencies.length; i++) {
// stringAggregation += locatedFrequencies[i] + " ";
// }
ChatMember temp3 = new ChatMember(); ChatMember temp3 = new ChatMember();
temp3.setCallSign(splittedMessageLine[3]); temp3.setCallSign(splittedMessageLine[3]);
temp3.setChatCategory(chategoryForMessageAndMessageSender);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), temp3); int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), temp3);
if (index == -1) { // user is not in the userlist but sent message... if (index == -1) { // user is not in the userlist but sent message...
@@ -571,37 +776,28 @@ public class MessageBusManagementThread extends Thread {
/** /**
* CH|2|1664663240|IK7LMX|Gilberto QRO|0|pse ant to jn80|YT5W| Caused this line * CH|2|1664663240|IK7LMX|Gilberto QRO|0|pse ant to jn80|YT5W| Caused this line
*/ */
System.out.println("[MSGBUSMGT:] ERROR, Frequency for " + splittedMessageLine[3] System.out.println("[MSGBUSMGT <<<catched ERROR>>>]:, Frequency for " + splittedMessageLine[3]
+ " is not settable, Callsign is not in the Member-list!"); + " is not settable, Callsign is not in the Member-list!");
//create dummy user to display the message but it wont be hit an existing user object
ChatMember newMember = new ChatMember(); ChatMember newMember = new ChatMember();
newMember.setCallSign(splittedMessageLine[3]); newMember.setCallSign(splittedMessageLine[3]);
newMember.setName(splittedMessageLine[4]); newMember.setName(splittedMessageLine[4]);
newMember.setFrequency(qrg); newMember.setFrequency(qrg);
// newMember.setFrequency(locatedFrequencies);
// this.client.getLst_chatMemberList().add(newMember);
} else { } else {
/** /**
* User is in the list... * User is in the list...
*
*/ */
this.client.getLst_chatMemberList().get(index).setFrequency(qrg); this.client.getLst_chatMemberList().get(index).setFrequency(qrg);
System.out.println("[MSGBUSMGT:] Frequency for " + splittedMessageLine[3] + " setted: " System.out.println("[MSGBUSMGT:] Frequency for " + splittedMessageLine[3] + " setted: "
+ locatedFrequencies); + locatedFrequencies);
// this.client.getDxClusterServer().broadcastSingleDXClusterEntryToLoggers(this.client.getLst_chatMemberList().get(index)); //tells the DXCluster server to send a DXC message for this member to the logbook software
// this.client.getLst_chatMemberList().
// ChatMember dummy = new ChatMember();
//
// dummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo()); //TODO: check if this is neccessary
// this.client.getLst_chatMemberList().add(dummy); // TODO: Bugfix for UI actualization, maybe we dont need that any more
// this.client.getLst_chatMemberList().remove(dummy);
// this.client.getLst_chatMemberList().sorted();
//
} }
} }
} }
// TODO: Next: get frequency infos out of name? // TODO: Next: get frequency infos out of name?
@@ -615,6 +811,8 @@ public class MessageBusManagementThread extends Thread {
// System.out.println("MSGBUS: User detected"); // System.out.println("MSGBUS: User detected");
ChatMember temp4 = new ChatMember(); ChatMember temp4 = new ChatMember();
temp4.setChatCategory(this.client.getChatCategoryMain()); //not really detectable and not really neccessarry to detect
temp4.setCallSign(splittedMessageLine[2]); temp4.setCallSign(splittedMessageLine[2]);
temp4.setQra(splittedMessageLine[3]); temp4.setQra(splittedMessageLine[3]);
temp4.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); temp4.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
@@ -627,18 +825,20 @@ public class MessageBusManagementThread extends Thread {
+ this.client.getLst_chatMemberList().get(index).getQra() + " new is: " + this.client.getLst_chatMemberList().get(index).getQra() + " new is: "
+ splittedMessageLine[3])); + splittedMessageLine[3]));
this.client.getLst_chatMemberList().get(index).setQra(splittedMessageLine[3]); ChatMember foundThisInChatMemberList = this.client.getLst_chatMemberList().get(index); //make less list accesses
// this.client.getLst_chatMemberList().get(index).setQra(splittedMessageLine[3]);
// this.client.getLst_chatMemberList().get(index).setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getLoginLocator(), splittedMessageLine[3]));
// this.client.getLst_chatMemberList().get(index).setQTFdirection(new Location(client.getChatPreferences().getLoginLocator()).getBearing(new Location(splittedMessageLine[3])));
foundThisInChatMemberList.setQra(splittedMessageLine[3]);
foundThisInChatMemberList.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), splittedMessageLine[3]));
foundThisInChatMemberList.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(splittedMessageLine[3])));
} else { } else {
System.out.println("[MSGBUSMGT:] ERROR! Locator Change of [" System.out.println("[MSGBUSMGT:] ERROR! Locator Change of ["
+ (splittedMessageLine[2] + "] is not possible, user is not in the Table!")); + (splittedMessageLine[2] + "] is not possible, user is not in the Table!"));
// ChatMember newMember = new ChatMember();
// newMember.setCallSign(splittedMessageLine[2]);
// newMember.setQra(splittedMessageLine[3]);
// this.client.getChatMemberTable().put(newMember.getCallSign(), newMember);
// this.client.getLst_chatMemberList().add(temp4);
} }
this.client.getDbHandler().storeChatMember(temp4); // TODO thats a bit unclean, its less an insert but a this.client.getDbHandler().storeChatMember(temp4); // TODO thats a bit unclean, its less an insert but a
@@ -760,6 +960,8 @@ public class MessageBusManagementThread extends Thread {
// System.out.println("[MSGBUSMGT:] DXCluster Message detected "); // System.out.println("[MSGBUSMGT:] DXCluster Message detected ");
stateChangeMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(),
stateChangeMember); stateChangeMember);
@@ -779,11 +981,15 @@ public class MessageBusManagementThread extends Thread {
ChatMember stateChangeMember = new ChatMember(); ChatMember stateChangeMember = new ChatMember();
stateChangeMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
stateChangeMember.setCallSign(splittedMessageLine[2]); stateChangeMember.setCallSign(splittedMessageLine[2]);
stateChangeMember.setName(splittedMessageLine[3]); stateChangeMember.setName(splittedMessageLine[3]);
stateChangeMember.setQra(splittedMessageLine[4]); stateChangeMember.setQra(splittedMessageLine[4]);
stateChangeMember.setState(Integer.parseInt(splittedMessageLine[5])); stateChangeMember.setState(Integer.parseInt(splittedMessageLine[5]));
stateChangeMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); stateChangeMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
stateChangeMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), stateChangeMember.getQra()));
stateChangeMember.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(stateChangeMember.getQra())));
this.client.getDbHandler().storeChatMember(stateChangeMember); // TODO: not clean, it should be an this.client.getDbHandler().storeChatMember(stateChangeMember); // TODO: not clean, it should be an
// upodate // upodate
@@ -793,16 +999,12 @@ public class MessageBusManagementThread extends Thread {
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(),
stateChangeMember); stateChangeMember);
//-1 could be the case if mycall is processed
if (index != -1) {
this.client.getLst_chatMemberList().get(index).setName(stateChangeMember.getName()); this.client.getLst_chatMemberList().get(index).setName(stateChangeMember.getName());
this.client.getLst_chatMemberList().get(index).setQra(stateChangeMember.getQra()); this.client.getLst_chatMemberList().get(index).setQra(stateChangeMember.getQra());
this.client.getLst_chatMemberList().get(index).setState(stateChangeMember.getState()); this.client.getLst_chatMemberList().get(index).setState(stateChangeMember.getState());
}
// this.client.getChatMemberTable().get(stateChangeMember.getCallSign())
// .setName(stateChangeMember.getName());
// this.client.getChatMemberTable().get(stateChangeMember.getCallSign())
// .setQra(stateChangeMember.getQra());
// this.client.getChatMemberTable().get(stateChangeMember.getCallSign())
// .setState(stateChangeMember.getState());
} else } else
@@ -828,7 +1030,7 @@ public class MessageBusManagementThread extends Thread {
System.out.println("Passwort falsch!"); System.out.println("Passwort falsch!");
if (splittedMessageLine[2].contains("password")) { if (splittedMessageLine[2].contains("password")) {
splittedMessageLine[2] += "pse disc- and reconnect"; splittedMessageLine[2] += " pse disc- and reconnect";
} }
ChatMember server = new ChatMember(); ChatMember server = new ChatMember();
@@ -841,11 +1043,24 @@ public class MessageBusManagementThread extends Thread {
pwErrorMsg.setSender(server); pwErrorMsg.setSender(server);
pwErrorMsg.setMessageText(splittedMessageLine[2]); pwErrorMsg.setMessageText(splittedMessageLine[2]);
ChatMember receiverDummy = new ChatMember();
receiverDummy.setCallSign(client.getChatPreferences().getStn_loginCallSign());
receiverDummy.setQrb(0.);
receiverDummy.setQTFdirection(0.);
pwErrorMsg.setReceiver(receiverDummy);
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
client.getLst_toMeMessageList().add(pwErrorMsg); client.getLst_globalChatMessageList().add(pwErrorMsg);
client.getLst_toAllMessageList().add(pwErrorMsg); // client.getLst_toMeMessageList().add(pwErrorMsg);
// client.getLst_toAllMessageList().add(pwErrorMsg);
} }
// Kst4ContestApplication.alertWindowEvent("Password was wrong. Pse check!");
client.disconnect(ApplicationConstants.DISCSTRING_DISCONNECTONLY);
// this.client.disconnect(); // this.client.disconnect();
} }
@@ -876,6 +1091,28 @@ public class MessageBusManagementThread extends Thread {
} }
} }
/**
* Method gets a String with a messagecategory-number and returns out of which of the existing categories
* (chat channels) this message/user had written from
*
* @param categoryNumber
* @return used Chatcategory (instance of singletons)
*/
private ChatCategory util_getChatCategoryByCategoryNrString(String categoryNumber) {
// System.out.println("MSGBSMGT Debug: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> try to find out category for a member; category is " + categoryNumber + " // 1st is " + this.client.getChatCategoryMain().getCategoryNumber() + " // 2nd is " + this.client.getChatCategorySecondChat().getCategoryNumber());
if (categoryNumber.equals(this.client.getChatCategoryMain().getCategoryNumber() + "")) {
return this.client.getChatCategoryMain();
} else if (categoryNumber.equals(this.client.getChatCategorySecondChat().getCategoryNumber() + "")) {
return this.client.getChatCategorySecondChat();
} else {
System.out.println("Msgbusmgt: ERROR!!! -> category for this message does not exist!");
return this.client.getChatCategoryMain(); //Chatcategory default decision
}
}
@Override @Override
public void interrupt() { public void interrupt() {
super.interrupt(); super.interrupt();
@@ -938,8 +1175,6 @@ public class MessageBusManagementThread extends Thread {
while (true) { while (true) {
try { try {
messageTextRaw = client.getMessageRXBus().take(); messageTextRaw = client.getMessageRXBus().take();
@@ -988,18 +1223,19 @@ public class MessageBusManagementThread extends Thread {
try { try {
processRXMessage23001(messageTextRaw); processRXMessage23001(messageTextRaw);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block System.out.println("MsgBusMgt: process23001 went wrong / IO Error");
e.printStackTrace(); e.printStackTrace();
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block System.out.println("MsgBusMgt: process23001 went wrong / SQL Error");
e.printStackTrace(); e.printStackTrace();
} }
} }
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
this.interrupt(); this.interrupt();
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
break;// TODO Change at may24, avoid uncloadability. Check if this could lead to further errors on instable link!
// client.getMessageRXBus().clear(); // client.getMessageRXBus().clear();
} }
{ {

View File

@@ -2,6 +2,7 @@ package kst4contest.controller;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.charset.StandardCharsets;
import kst4contest.model.ChatMessage; import kst4contest.model.ChatMessage;
@@ -39,7 +40,7 @@ public class ReadThread extends Thread {
try { try {
input = socket.getInputStream(); input = socket.getInputStream();
reader = new BufferedReader(new InputStreamReader(input)); reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
} catch (IOException ex) { } catch (IOException ex) {
System.out.println("Error getting input stream: " + ex.getMessage()); System.out.println("Error getting input stream: " + ex.getMessage());
@@ -92,47 +93,6 @@ public class ReadThread extends Thread {
e.printStackTrace(); e.printStackTrace();
} }
// try {
// sleep(3000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// try {
// System.out.println("RDTH: try new socket");
// this.client.getSocket().close();
// this.client.getSocket().close();
// this.client.setSocket(new Socket(this.client.getHostname(), this.client.getPort()));
// socket.connect(new InetSocketAddress(this.client.getHostname(), this.client.getPort()));
// System.out.println("[Readthread, Warning:] new socket connected? -> " + socket.isConnected());
// input = socket.getInputStream();
// reader = new BufferedReader(new InputStreamReader(input));
//
// this.sleep(5000);
// } catch (IOException | InterruptedException e2) {
// // TODO Auto-generated catch block
// System.out.println("fucktah");
// e2.printStackTrace();
// }
// try {
// sleep(2000);
// } catch (InterruptedException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
// try {
// this.client.getSocket().close();
// this.client.setSocket(new Socket(this.client.getHostname(), this.client.getPort()));
// } catch (UnknownHostException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
} }
} }

View File

@@ -6,6 +6,7 @@ import java.util.Comparator;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import kst4contest.ApplicationConstants;
import kst4contest.model.AirPlane; import kst4contest.model.AirPlane;
import kst4contest.model.AirPlaneReflectionInfo; import kst4contest.model.AirPlaneReflectionInfo;
import kst4contest.model.ChatMember; import kst4contest.model.ChatMember;
@@ -30,6 +31,8 @@ public class ReadUDPbyAirScoutMessageThread extends Thread {
public ReadUDPbyAirScoutMessageThread(int localPort, ChatController client, String ASIdentificator, public ReadUDPbyAirScoutMessageThread(int localPort, ChatController client, String ASIdentificator,
String ChatClientIdentificator) { String ChatClientIdentificator) {
this.localPort = localPort; this.localPort = localPort;
this.client = client; this.client = client;
this.ASIdentificator = ASIdentificator; this.ASIdentificator = ASIdentificator;
@@ -38,6 +41,7 @@ public class ReadUDPbyAirScoutMessageThread extends Thread {
@Override @Override
public void interrupt() { public void interrupt() {
System.out.println("ReadUDP");
super.interrupt(); super.interrupt();
try { try {
if (this.socket != null) { if (this.socket != null) {
@@ -89,6 +93,12 @@ public class ReadUDPbyAirScoutMessageThread extends Thread {
} }
socket.receive(packet); socket.receive(packet);
} catch (SocketTimeoutException e2) { } catch (SocketTimeoutException e2) {
// this will catch the repeating Sockettimeoutexception...nothing to do // this will catch the repeating Sockettimeoutexception...nothing to do
// e2.printStackTrace(); // e2.printStackTrace();
@@ -104,10 +114,22 @@ public class ReadUDPbyAirScoutMessageThread extends Thread {
String received = new String(packet.getData(), packet.getOffset(), packet.getLength()); String received = new String(packet.getData(), packet.getOffset(), packet.getLength());
received = received.trim(); received = received.trim();
if (received.contains(ApplicationConstants.DISCONNECT_RDR_POISONPILL)) {
System.out.println("ReadUdpByASMsgTh, Info: got poison, now dieing....");
try {
terminateConnection();
} catch (Exception e) {
System.out.println("ASUDPRDR: catched error " + e.getMessage());
}
break;
}
if (received.contains("ASSETPATH") || received.contains("ASWATCHLIST")) { if (received.contains("ASSETPATH") || received.contains("ASWATCHLIST")) {
// do nothing, that is your own message // do nothing, that is your own message
} else if (received.contains("ASNEAREST:")) { } else if (received.contains("ASNEAREST:")) { //answer by airscout
processASUDPMessage(received); processASUDPMessage(received);
// System.out.println("[ReadUSPASTh, info:] received AS String " + received); // System.out.println("[ReadUSPASTh, info:] received AS String " + received);
AirPlaneReflectionInfo apReflectInfoForChatMember; AirPlaneReflectionInfo apReflectInfoForChatMember;
@@ -260,9 +282,13 @@ public class ReadUDPbyAirScoutMessageThread extends Thread {
return apInfo; return apInfo;
} }
public boolean terminateConnection() throws IOException { public boolean terminateConnection() {
try {
this.socket.close(); this.socket.close();
} catch (Exception e) {
System.out.println("udpbyas: catched " + e.getMessage());
}
return true; return true;
} }

View File

@@ -3,12 +3,15 @@ package kst4contest.controller;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import kst4contest.ApplicationConstants;
import kst4contest.view.GuiUtils;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
@@ -43,17 +46,19 @@ public class ReadUDPbyUCXMessageThread extends Thread {
super.interrupt(); super.interrupt();
try { try {
if (this.socket != null) { if (this.socket != null) {
System.out.println(">>>>>>>>>>>>>>ReadUdpbyUCS: closing socket");
this.socket.close(); terminateConnection();
} }
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); System.out.println("UCXUDPRDR: catched error " + e.getMessage());
} }
} }
public void run() { public void run() {
Thread.currentThread().setName("ReadUDPByUCXLogThread"); Thread.currentThread().setName("ReadUDPByUCXLogThread");
DatagramSocket socket = null; DatagramSocket socket = null;
@@ -63,7 +68,7 @@ public class ReadUDPbyUCXMessageThread extends Thread {
try { try {
socket = new DatagramSocket(12060); socket = new DatagramSocket(12060);
socket.setSoTimeout(11000); //TODO try for end properly socket.setSoTimeout(2000); //TODO try for end properly
} }
catch (SocketException e) { catch (SocketException e) {
@@ -75,13 +80,11 @@ public class ReadUDPbyUCXMessageThread extends Thread {
boolean timeOutIndicator = false; boolean timeOutIndicator = false;
if (this.client.isDisconnectionPerformedByUser()) {
break;//TODO: what if it´s not the finally closage but a band channel change?
}
// packet = new DatagramPacket(buf, buf.length); //TODO: Changed that due to memory leak, check if all works (seems like that) // packet = new DatagramPacket(buf, buf.length); //TODO: Changed that due to memory leak, check if all works (seems like that)
// DatagramPacket packet = new DatagramPacket(SRPDefinitions.BYTE_BUFFER_MAX_LENGTH); //TODO: Changed that due to memory leak, check if all works (seems like that) // DatagramPacket packet = new DatagramPacket(SRPDefinitions.BYTE_BUFFER_MAX_LENGTH); //TODO: Changed that due to memory leak, check if all works (seems like that)
try { try {
socket.receive(packet); socket.receive(packet);
} catch (SocketTimeoutException e2) { } catch (SocketTimeoutException e2) {
timeOutIndicator = true; timeOutIndicator = true;
@@ -91,6 +94,33 @@ public class ReadUDPbyUCXMessageThread extends Thread {
catch (IOException e) { catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} catch (NullPointerException nE) {
// TODO Auto-generated catch block
nE.printStackTrace();
System.out.println("ReadUdpByUCXTH: Socket not ready");
try {
socket = new DatagramSocket(client.getChatPreferences().getLogsynch_ucxUDPWkdCallListenerPort());
socket.setSoTimeout(2000);
} catch (SocketException e) {
System.out.println("[ReadUDPByUCSMsgTH, Error]: socket in use or something:");
e.printStackTrace();
try {
socket = new DatagramSocket(null);
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(client.getChatPreferences().getLogsynch_ucxUDPWkdCallListenerPort()));
socket.receive(packet);
socket.setSoTimeout(3000);
} catch (Exception ex) {
System.out.println("ReadUDPByUCXMsgTh: Could not solve that. Program Restart needed.");
throw new RuntimeException(ex);
}
}
} }
InetAddress address = packet.getAddress(); InetAddress address = packet.getAddress();
@@ -99,8 +129,19 @@ public class ReadUDPbyUCXMessageThread extends Thread {
String received = new String(packet.getData(), packet.getOffset(), packet.getLength()); String received = new String(packet.getData(), packet.getOffset(), packet.getLength());
received = received.trim(); received = received.trim();
// System.out.println("recvudpucx");
// System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<recv " + received);
if (received.contains(ApplicationConstants.DISCONNECT_RDR_POISONPILL)) {
System.out.println("ReadUdpByUCX, Info: got poison, now dieing....");
socket.close();
timeOutIndicator = true;
break;
}
if (this.client.isDisconnectionPerformedByUser()) {
break;//TODO: what if it´s not the finally closage but a band channel change?
}
if (!timeOutIndicator) { if (!timeOutIndicator) {
processUCXUDPMessage(received); processUCXUDPMessage(received);
@@ -155,8 +196,12 @@ public class ReadUDPbyUCXMessageThread extends Thread {
// call = call.toLowerCase(); // call = call.toLowerCase();
String band = element.getElementsByTagName("band").item(0).getTextContent(); String band = element.getElementsByTagName("band").item(0).getTextContent();
String points = element.getElementsByTagName("points").item(0).getTextContent();
System.out.println("[Readudp, info ]: received Current Element :" + node.getNodeName() System.out.println("[Readudp, info ]: received Current Element :" + node.getNodeName()
+ "call: " + call + " / " + band); + "call: " + call + " / " + band + " ----> " + points + " POINTS");
// client.getChatPreferences().setBcn_contestScoreSum(Long.parseLong(points));
ChatMember workedCall = new ChatMember(); ChatMember workedCall = new ChatMember();
workedCall.setCallSign(call); workedCall.setCallSign(call);
@@ -198,6 +243,44 @@ public class ReadUDPbyUCXMessageThread extends Thread {
} }
/**
* cases hotfix for MINOS logger, which tells band like "2m", not "144"
*/
case "2m": {
workedCall.setWorked144(true);
break;
}
case "70cm": {
workedCall.setWorked432(true);
break;
}
case "23cm": {
workedCall.setWorked1240(true);
break;
}
case "13cm": {
workedCall.setWorked2300(true);
break;
}
case "9cm": {
workedCall.setWorked3400(true);
break;
}
case "6cm": {
workedCall.setWorked5600(true);
break;
}
case "3cm": {
workedCall.setWorked10G(true);
}
default: default:
System.out.println("[ReadUDPFromUCX, Error:] unexpected band value: \"" + band + "\""); System.out.println("[ReadUDPFromUCX, Error:] unexpected band value: \"" + band + "\"");
break; break;
@@ -216,68 +299,150 @@ public class ReadUDPbyUCXMessageThread extends Thread {
// modifyThat = (ChatMember) client.getMap_ucxLogInfoWorkedCalls().get(call); // modifyThat = (ChatMember) client.getMap_ucxLogInfoWorkedCalls().get(call);
int indexOfChatMemberInTable = -1; // asd //TODO: Check if callsign and callsignraw is similar, then mark first and further via new checklistforchatmembermultiplemethod with array of indize
indexOfChatMemberInTable = client.checkListForChatMemberIndexByCallSign(workedCall);
if (indexOfChatMemberInTable == -1) { ArrayList<Integer> markTheseChattersAsWorked = client.checkListForChatMemberIndexesByCallSign(workedCall);
// do nothing
if (markTheseChattersAsWorked.isEmpty()) {
//Worked call is not part of the chatmember list
} else { } else {
modifyThat = client.getLst_chatMemberList().get(indexOfChatMemberInTable); for (int index : markTheseChattersAsWorked) {
// modifyThat.setWorked(true); modifyThat = client.getLst_chatMemberList().get(index);
client.getLst_chatMemberList() modifyThat.setWorked(true);
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)).setWorked(true); // client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat)).setWorked(true);
if (workedCall.isWorked144()) { if (workedCall.isWorked144()) {
modifyThat.setWorked144(true); modifyThat.setWorked144(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked144(true); // .setWorked144(true);
} else if (workedCall.isWorked432()) { } else if (workedCall.isWorked432()) {
modifyThat.setWorked432(true); modifyThat.setWorked432(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked432(true); // .setWorked432(true);
} else if (workedCall.isWorked1240()) { } else if (workedCall.isWorked1240()) {
modifyThat.setWorked1240(true); modifyThat.setWorked1240(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked1240(true); // .setWorked1240(true);
} else if (workedCall.isWorked2300()) { } else if (workedCall.isWorked2300()) {
modifyThat.setWorked2300(true); modifyThat.setWorked2300(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked2300(true); // .setWorked2300(true);
} else if (workedCall.isWorked3400()) { } else if (workedCall.isWorked3400()) {
modifyThat.setWorked3400(true); modifyThat.setWorked3400(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked3400(true); // .setWorked3400(true);
} else if (workedCall.isWorked5600()) { } else if (workedCall.isWorked5600()) {
modifyThat.setWorked5600(true); modifyThat.setWorked5600(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked5600(true); // .setWorked5600(true);
} else if (workedCall.isWorked10G()) { } else if (workedCall.isWorked10G()) {
modifyThat.setWorked10G(true); modifyThat.setWorked10G(true);
client.getLst_chatMemberList() // client.getLst_chatMemberList()
.get(client.checkListForChatMemberIndexByCallSign(modifyThat)) // .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
.setWorked10G(true); // .setWorked10G(true);
}
} }
try {
GuiUtils.triggerGUIFilteredChatMemberListChange(client); //not clean at all
} catch (Exception IllegalStateException) {
//do nothing, as it works...
} }
} }
/**
* old mechanic to markup worked stations in the chatmember table
*/
// int indexOfChatMemberInTable = -1; //chatmember not in table
// indexOfChatMemberInTable = client.checkListForChatMemberIndexByCallSign(workedCall);
//
// if (indexOfChatMemberInTable == -1) {
// // do nothing
// } else {
// modifyThat = client.getLst_chatMemberList().get(indexOfChatMemberInTable);
//
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat)).setWorked(true);
//
// if (workedCall.isWorked144()) {
// modifyThat.setWorked144(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked144(true);
//
// } else if (workedCall.isWorked432()) {
// modifyThat.setWorked432(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked432(true);
//
// } else if (workedCall.isWorked1240()) {
// modifyThat.setWorked1240(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked1240(true);
//
// } else if (workedCall.isWorked2300()) {
// modifyThat.setWorked2300(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked2300(true);
//
// } else if (workedCall.isWorked3400()) {
// modifyThat.setWorked3400(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked3400(true);
//
// } else if (workedCall.isWorked5600()) {
// modifyThat.setWorked5600(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked5600(true);
//
// } else if (workedCall.isWorked10G()) {
// modifyThat.setWorked10G(true);
// client.getLst_chatMemberList()
// .get(client.checkListForChatMemberIndexByCallSign(modifyThat))
// .setWorked10G(true);
// }
/**
* //TODO: following line is a quick fix to making disappear worked chatmembers of the list
* Thats uncomfortable due to this also causes selection changes,
* Better way is to change all worked and qrv values to observables and then trigger the underlying
* list to fire an invalidationevent. Really Todo!
*/
// try{
//
// GuiUtils.triggerGUIFilteredChatMemberListChange(client); //not clean at all
// } catch (Exception IllegalStateException) {
// //do nothing, as it works...
// }
// }
/**
* end -> old mechanic to markup worked stations in the chatmember table
*/
}
boolean isInChat = this.client.getDbHandler().updateWkdInfoOnChatMember(workedCall); boolean isInChat = this.client.getDbHandler().updateWkdInfoOnChatMember(workedCall);
// This will update the worked info on a worked chatmember. DBHandler will // This will update the worked info on a worked chatmember. DBHandler will
// check, if an entry at the db had been modified. If not, then the worked // check, if an entry at the db had been modified. If not, then the worked
// station had not been stored. DBHandler will store the informations then. // station had not been stored. DBHandler will store the information then.
if (!isInChat) { if (!isInChat) {
workedCall.setName("unknown"); workedCall.setName("unknown");
@@ -297,7 +462,6 @@ public class ReadUDPbyUCXMessageThread extends Thread {
fileWriterPersistUDPToFile = new FileWriter(logUDPMessageToThisFile, true); fileWriterPersistUDPToFile = new FileWriter(logUDPMessageToThisFile, true);
} catch (IOException e1) { } catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} }
@@ -373,7 +537,7 @@ public class ReadUDPbyUCXMessageThread extends Thread {
// System.out.println("Radio Mode: " + mode); // System.out.println("Radio Mode: " + mode);
// System.out.println("[ReadUDPFromUCX, Info:] Setted QRG pref to: \"" + qrg + "\"" ); // System.out.println("[ReadUDPFromUCX, Info:] Setted QRG pref to: \"" + qrg + "\"" );
this.client.getChatPreferences().getMYQRG().set(formattedQRG); this.client.getChatPreferences().getMYQRGFirstCat().set(formattedQRG);
System.out.println("[ReadUDPbyUCXTh: ] Radioinfo processed: " + formattedQRG); System.out.println("[ReadUDPbyUCXTh: ] Radioinfo processed: " + formattedQRG);
} }

View File

@@ -0,0 +1,65 @@
package kst4contest.controller;
import kst4contest.model.ChatMessage;
import java.util.TimerTask;
/**
* This class is updateing the scoreboard at https://slovhf.net/claimed/. Gets scores of all bands out of the
* preferences which is updated via ReadUdpByUCXLog Thread.
*
* api description: https://slovhf.net/claimed-score-api/
*
* <br/><br/>
* The task will be runned out of the singleton ChatController instance in an
* intervall as specified by the Chatpreferences-instance (typically as
* configured in the xml file.
*
*
* @author prakt
*
*/
public class ScoreboardUpdateTask extends TimerTask {
private ChatController chatController;
public ScoreboardUpdateTask(ChatController client) {
this.chatController = client;
}
@Override
public void run() {
Thread.currentThread().setName("BeaconTask");
ChatMessage beaconMSG = new ChatMessage();
String replaceVariables = this.chatController.getChatPreferences().getBcn_beaconTextMainCat();
// replaceVariables = bcn_beaconText;
replaceVariables = replaceVariables.replaceAll("MYQRG", this.chatController.getChatPreferences().getMYQRGFirstCat().getValue());
replaceVariables = replaceVariables.replaceAll("MYCALL", this.chatController.getChatPreferences().getStn_loginCallSign());
replaceVariables = replaceVariables.replaceAll("MYLOCATOR", this.chatController.getChatPreferences().getStn_loginLocatorMainCat());
replaceVariables = replaceVariables.replaceAll("MYQTF", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
beaconMSG.setMessageText(
"MSG|" + this.chatController.getChatPreferences().getLoginChatCategoryMain().getCategoryNumber() + "|0|" + replaceVariables + "|0|");
beaconMSG.setMessageDirectedToServer(true);
// System.out.println("########### " + replaceVariables);
if (this.chatController.getChatPreferences().isBcn_beaconsEnabledMainCat() ) {
System.out.println(new Utils4KST().time_generateCurrentMMDDhhmmTimeString()
+ " [BeaconTask, Info]: Sending CQ: " + beaconMSG.getMessageText());
this.chatController.getMessageTXBus().add(beaconMSG);
} else {
//do nothing, CQ is disabled
}
}
}

View File

@@ -3,6 +3,9 @@
*/ */
package kst4contest.controller; package kst4contest.controller;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableStringValue;
import java.io.IOException; import java.io.IOException;
/** /**
@@ -20,6 +23,8 @@ public class StartChat {
System.out.println("[Startchat:] Starting new Chat instance"); System.out.println("[Startchat:] Starting new Chat instance");
// ObservableStringValue messageBus = new SimpleStringProperty("");
ChatController client = new ChatController(); ChatController client = new ChatController();
client.execute(); client.execute();

View File

@@ -37,7 +37,7 @@ public class UCXLogFileToHashsetParser {
*/ */
private ChatMember checkIfLineInhibitsCallSign(String line) { private ChatMember checkIfLineInhibitsCallSign(String line) {
Pattern pattern = Pattern.compile(PTRN_CallSign); // TODO: PTRN should depend to category-selection of own stn Pattern pattern = Pattern.compile(PTRN_CallSign);
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
String matchedString = ""; String matchedString = "";

View File

@@ -0,0 +1,237 @@
package kst4contest.controller;
import java.io.InputStream;
import kst4contest.ApplicationConstants;
import kst4contest.model.UpdateInformation;
import kst4contest.utils.ApplicationFileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
public class UpdateChecker {
public static void main(String[] args) {
// new UpdateChecker(null).parseUpdateXMLFile();
if (new UpdateChecker(null).downloadLatestVersionInfoXML()) {
// ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME,ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE,ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE);
}
new UpdateChecker(null).parseUpdateXMLFile();
}
public UpdateChecker(ChatController chatController) {
System.out.println("[Updatechecker: checking for updates...]");
// double currentVersionNumber = ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER;
}
String versionInfoDownloadedFromServerFileName = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE);
String versionInfoXMLURLAtServer = ApplicationConstants.VERSIONINFOURLFORUPDATES_KST4CONTEST;
// double currentVersion = ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER;
//DOWNLOAD from URL, then parse, then do anything with it...
/**
* Downloads the versioninfo-xml-file from a webserver to local. Returns true if download was successful, else false
*
* @return true if successful
*/
public boolean downloadLatestVersionInfoXML() {
try {
InputStream in = new URL(versionInfoXMLURLAtServer).openStream();
Files.copy(in, Paths.get(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/"+ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE)), StandardCopyOption.REPLACE_EXISTING);
in.close();
// System.out.println(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/"+ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE));
// ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME,ApplicationFileUtils.get,ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE);
} catch (Exception e) {
System.out.println("ERROR DOWNLOADING!" + e);
return false;
}
return true;
}
public UpdateInformation parseUpdateXMLFile() {
UpdateInformation updateInfos = new UpdateInformation();
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME,"/"+ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE,ApplicationConstants.VERSIONINFDOWNLOADEDLOCALFILE);
// System.out.println("[Updatecker, Info]: restoring prefs from file " + versionInfoDownloadedFromServerFileName);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
File xmlConfigFile = new File(versionInfoDownloadedFromServerFileName);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlConfigFile);
/**
* latestVersion on server
*/
NodeList list = doc.getElementsByTagName("latestVersion");
if (list.getLength() != 0) {
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
updateInfos.setLatestVersionNumberOnServer(Double.parseDouble(element.getElementsByTagName("versionNumber").item(0).getTextContent()));
updateInfos.setAdminMessage(element.getElementsByTagName("adminMessage").item(0).getTextContent());
updateInfos.setMajorChanges(element.getElementsByTagName("majorChanges").item(0)
.getTextContent());
updateInfos.setLatestVersionPathOnWebserver(element.getElementsByTagName("latestVersionPathOnWebserver").item(0).getTextContent());
// System.out.println(updateInfos.toString());
}
}
}
/**
* Section changeLog
*/
list = doc.getElementsByTagName("changeLog");
ArrayList<String[]> changeLogArrayList = new ArrayList<String[]>();
if (list.getLength() != 0) {
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
Element element = (Element) node;
int childNodeCounter = 0; //need an extra counter due to childnodes are counted...no idea, how
String[] aChangeLogEntry = new String[7];
aChangeLogEntry[0] = "";
aChangeLogEntry[1] = "Date: ";
aChangeLogEntry[2] = "Desc: ";
aChangeLogEntry[3] = "Added: ";
aChangeLogEntry[4] = "Changed: ";
aChangeLogEntry[5] = "Fixed: ";
aChangeLogEntry[6] = "Removed: ";
for (int i = 0; i < element.getChildNodes().getLength(); i++) {
if (element.getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE) {
// System.out.println(element.getChildNodes().item(i).getTextContent() + " <<<<<<<<<<<<<<<<<< " + i + " / " + childNodeCounter);
// System.out.println(element.getChildNodes().item(i).getNodeName());
aChangeLogEntry[childNodeCounter] = aChangeLogEntry[childNodeCounter] + element.getChildNodes().item(i).getTextContent();
childNodeCounter++;
}
}
changeLogArrayList.add(aChangeLogEntry);
}
updateInfos.setChangeLog(changeLogArrayList);
}
/**
* Section Buglist
*/
list = doc.getElementsByTagName("bug");
ArrayList<String[]> bugFixArrayList = new ArrayList<String[]>();
if (list.getLength() != 0) {
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
Element element = (Element) node;
int childNodeCounter = 0; //need an extra counter due to childnodes are counted...no idea, how
String[] aChangeLogEntry = new String[3];
aChangeLogEntry[0] = "";
aChangeLogEntry[1] = "State: ";
for (int i = 0; i < element.getChildNodes().getLength(); i++) {
if (element.getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE) {
// System.out.println(element.getChildNodes().item(i).getTextContent() + " <<<<<<<<<<<<<<<<<< " + i + " / " + childNodeCounter);
// System.out.println(element.getChildNodes().item(i).getNodeName());
aChangeLogEntry[childNodeCounter] = aChangeLogEntry[childNodeCounter] + element.getChildNodes().item(i).getTextContent();
childNodeCounter++;
}
}
bugFixArrayList.add(aChangeLogEntry);
}
updateInfos.setBugList(bugFixArrayList);
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
String[] testEntry = new String[7];
testEntry[0] = "0.99";
testEntry[1] = "2022-09";
testEntry[2] = "researched the Chatprotocol";
testEntry[3] = "addednothing";
testEntry[4] = "changedsome";
testEntry[5] = "fixedxed";
testEntry[6] = "removedYourMom";
String[] testEntry2 = new String[7];
testEntry2[0] = "0.29";
testEntry2[1] = "2033-09";
testEntry2[2] = "tested";
testEntry2[3] = "addednotashing";
testEntry2[4] = "changeasdsome";
testEntry2[5] = "fixedxeds";
testEntry2[6] = "removedYosssurMom";
// changeLogArrayList.add(testEntry);
// changeLogArrayList.add(testEntry2);
return updateInfos;
}
@Override
public String toString() {
String toString = "";
// toString += this.currentVersion;
return toString;
}
}

View File

@@ -9,6 +9,7 @@ import java.util.TimerTask;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import kst4contest.model.ChatMember; import kst4contest.model.ChatMember;
import kst4contest.model.ClusterMessage; import kst4contest.model.ClusterMessage;
import kst4contest.view.GuiUtils;
public class UserActualizationTask extends TimerTask { public class UserActualizationTask extends TimerTask {
@@ -89,6 +90,7 @@ public class UserActualizationTask extends TimerTask {
// chatMember.setWorked(true); // chatMember.setWorked(true);
// System.out.println("[USERACT, info:] marking Chatuser " + chatMember.getCallSign() + " as worked, based on UDPLsnBackup-Logfile."); // System.out.println("[USERACT, info:] marking Chatuser " + chatMember.getCallSign() + " as worked, based on UDPLsnBackup-Logfile.");
// } // }
// GuiUtils.triggerGUIFilteredChatMemberListChange(this.client); //todo: quick and dirty gui fix
} }
ObservableList<ClusterMessage> praktiKSTClusterList = this.client.getLst_clusterMemberList(); ObservableList<ClusterMessage> praktiKSTClusterList = this.client.getLst_clusterMemberList();

View File

@@ -1,5 +1,7 @@
package kst4contest.controller; package kst4contest.controller;
import javafx.beans.property.SimpleStringProperty;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
@@ -7,6 +9,8 @@ import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.Date;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utils4KST { public class Utils4KST {
@@ -20,6 +24,14 @@ public class Utils4KST {
return millisecondsSinceEpoch; return millisecondsSinceEpoch;
} }
public String time_generateCurrenthhmmZTimeStringForClusterMessage() {
OffsetDateTime currentTimeInUtc = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println("Utils generated current time " + currentTimeInUtc + " --> " + currentTimeInUtc.format(DateTimeFormatter.ofPattern("HHmm"))+"Z");
return currentTimeInUtc.format(DateTimeFormatter.ofPattern("HHmm"))+"Z";
}
public String time_generateCurrentMMDDhhmmTimeString() { public String time_generateCurrentMMDDhhmmTimeString() {
OffsetDateTime currentTimeInUtc = OffsetDateTime.now(ZoneOffset.UTC); OffsetDateTime currentTimeInUtc = OffsetDateTime.now(ZoneOffset.UTC);
@@ -50,10 +62,140 @@ public class Utils4KST {
} }
public static long time_getSecondsBetweenEpochAndNow(String epoch1) {
long epoch1Long = Long.parseLong(epoch1);
long epoch2Long = new Utils4KST().time_generateCurrentEpochTime();
// Instant instant = Instant.ofEpochSecond(epoch);
Date date = new Date(epoch1Long * 1000L);
Date date2 = new Date(epoch2Long * 1000L);
long seconds = Math.abs(date.getTime()-date2.getTime())/1000;
return seconds;
}
public Date time_generateActualTimeInDateFormat() { public Date time_generateActualTimeInDateFormat() {
Date date = new Date(time_generateCurrentEpochTime() * 1000L); Date date = new Date(time_generateCurrentEpochTime() * 1000L);
return date; return date;
} }
/**
* This method tests a regexp-pattern against a given string
*
* @param testString: check if this string matches a given pattern
* @param regExPattern: pattern which should be checked
* @return true if match, else false
*/
private static boolean testPattern(String testString, String regExPattern) {
Pattern pattern = Pattern.compile(regExPattern);
Matcher matcher = pattern.matcher(testString);
return matcher.find();
}
/**
* Normalizes a chatmembers frequency-string for cluster usage<br/>
* <b>returns a frequency String in KHz like = "144300" or "144300.0" to match DXC protocol needs</b>
*
* @param optionalPrefix: if there is a value like ".300", it have to be decided, wich ".300": 144.300, 432.300, 1296.300 .... prefix means for example "144."
*/
public static String normalizeFrequencyString(String qrgString, SimpleStringProperty optionalPrefix) {
// final String PTRN_QRG_CAT2 = "(([0-9]{3,4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)";
try {
qrgString = qrgString.replace(" ","");
} catch (Exception e) {
System.out.println("UTILS: QRG NULL, nothing to convert");
// e.printStackTrace();
}
final String PTRN_QRG_CAT2_wholeQRGMHz4Digits = "(([0-9]{4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)"; //1296.300.3 etc
final String PTRN_QRG_CAT2_wholeQRGMHz3Digits = "(([0-9]{3}[\\.|,| ]?[0-9]{3})([\\.][\\d]{1,2})?)"; //144.300.3 etc
final String PTRN_QRG_CAT2_QRGwithoutPrefix = "((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)"; //144.300.3 etc
String stringAggregation = "";
if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz4Digits)) {//case 1296.200 or 1296.200.2 etc.
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".","");
stringAggregation = stringAggregation.replace(",","");
stringAggregation = stringAggregation.replace(" ", "");
if (stringAggregation.length() == 8) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length());
stringAggregation = stringAggregationNew + ".0";
return stringAggregation;
} else if (stringAggregation.length() == 9) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
}
} else
if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz3Digits)) { //case 144.300 or 144.300.2
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".","");
stringAggregation = stringAggregation.replace(",","");
stringAggregation = stringAggregation.replace(" ", "");
if (stringAggregation.length() == 6) {
stringAggregation = stringAggregation + ".0";
return stringAggregation;
}
if (stringAggregation.length() == 7) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length());
stringAggregation = stringAggregationNew + ".0";
return stringAggregation;
} else if (stringAggregation.length() == 8) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
}
}
else
if (testPattern(qrgString, PTRN_QRG_CAT2_QRGwithoutPrefix)) { //case ".050 or .300 or something like that"
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".", "");
stringAggregation = stringAggregation.replace(",", "");
stringAggregation = stringAggregation.replace(" ", "");
if (stringAggregation.length() == 3) { // like 050 or 300
String stringAggregationNew = optionalPrefix.getValue() + stringAggregation;
stringAggregation = stringAggregationNew + ".0";
return stringAggregation;
} else if (stringAggregation.length() == 4) { //like 050.2 --> 0502
stringAggregation = optionalPrefix.getValue() + stringAggregation;
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 1) + "." + stringAggregation.substring(stringAggregation.length() - 1, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
} else if (stringAggregation.length() == 5) { //like 050.20 --> 05020
stringAggregation = optionalPrefix.getValue() + stringAggregation;
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 2) + "." + stringAggregation.substring(stringAggregation.length() - 2, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
}
}
return stringAggregation; //if nothing else helps
}
} }

View File

@@ -2,6 +2,8 @@ package kst4contest.controller;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import kst4contest.model.ChatMessage; import kst4contest.model.ChatMessage;
@@ -17,7 +19,7 @@ public class WriteThread extends Thread {
private ChatController client; private ChatController client;
private OutputStream output; private OutputStream output;
private ChatMessage messageTextRaw; private ChatMessage messageToBeSend;
public WriteThread(Socket socket, ChatController client) throws InterruptedException { public WriteThread(Socket socket, ChatController client) throws InterruptedException {
this.socket = socket; this.socket = socket;
@@ -25,7 +27,9 @@ public class WriteThread extends Thread {
try { try {
output = socket.getOutputStream(); output = socket.getOutputStream();
writer = new PrintWriter(output, true);
writer = new PrintWriter(output, true, StandardCharsets.UTF_8);
} catch (IOException ex) { } catch (IOException ex) {
System.out.println("Error getting output stream: " + ex.getMessage()); System.out.println("Error getting output stream: " + ex.getMessage());
ex.printStackTrace(); ex.printStackTrace();
@@ -34,7 +38,8 @@ public class WriteThread extends Thread {
/** /**
* This method is used to send a message to the server, raw formatted. E.g. for * This method is used to send a message to the server, raw formatted. E.g. for
* the keepalive message. * the keepalive message. This method sends only in the main message-Category. To send it in a category
* "defined by Chatmessage", use txByRxmsgCatOrigin(Chatmessage "toBeSend")
* *
* @param messageToServer * @param messageToServer
* @throws InterruptedException * @throws InterruptedException
@@ -48,6 +53,33 @@ public class WriteThread extends Thread {
} }
/**
* This method is used to send a message directly to a receiver in a special chatcategory. The receivers category
* will be read out of the Chatmessage.getChatCategory method. <b> The message text will be modified to fit kst
* messageformat</b>
*
* @param messageToServer
* @throws InterruptedException
*/
public void txByRxmsgCatOrigin(ChatMessage messageToServer) throws InterruptedException {
// writer.println(messageToServer.getMessage()); //kst4contest.test 4 23001
// writer.flush(); //kst4contest.test 4 23001
String originalMessageText = messageToServer.getMessageText() + "";
String newMessageText = "";
newMessageText = ("MSG|" + messageToServer.getChatCategory().getCategoryNumber()
+ "|0|" + originalMessageText + "|0|"); //original before 1.26
System.out.println(newMessageText + "< sended to the writer (DIRECTED REPLY)");
writer.println(newMessageText);
}
/** /**
* This method gets a textmessage to the chat and adds some characters to hit * This method gets a textmessage to the chat and adds some characters to hit
* the neccessarry format to send a message in the on4kst chat either to another * the neccessarry format to send a message in the on4kst chat either to another
@@ -59,29 +91,28 @@ public class WriteThread extends Thread {
public void txKSTFormatted(ChatMessage messageToServer) throws InterruptedException { public void txKSTFormatted(ChatMessage messageToServer) throws InterruptedException {
// writer.println(messageToServer.getMessageText()); // writer.println(messageToServer.getMessageText());
messageTextRaw = messageToServer; messageToBeSend = messageToServer;
try { try {
messageTextRaw = client.getMessageTXBus().take(); messageToBeSend = client.getMessageTXBus().take();
// this.client.getmesetChatsetServerready(true); // this.client.getmesetChatsetServerready(true);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
String messageLine = messageTextRaw.getMessageText(); String messageLine = messageToBeSend.getMessageText();
if (messageTextRaw.isMessageDirectedToServer()) { if (messageToBeSend.isMessageDirectedToServer()) {
/** /**
* We have to check if we only commands the server (keepalive) or want do talk * We have to check if we only commands the server (keepalive) or want do talk
* to the community * to the community
*/ */
try { try {
tx(messageTextRaw); tx(messageToBeSend);
System.out.println("BUS: tx: " + messageTextRaw.getMessageText()); System.out.println("BUS: tx: " + messageToBeSend.getMessageText());
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
@@ -95,8 +126,8 @@ public class WriteThread extends Thread {
// ownMSG.setMessageText( // ownMSG.setMessageText(
// "MSG|" + this.client.getCategory().getCategoryNumber() + "|0|" + messageLine + "|0|"); // "MSG|" + this.client.getCategory().getCategoryNumber() + "|0|" + messageLine + "|0|");
ownMSG.setMessageText("MSG|" + this.client.getChatPreferences().getLoginChatCategory().getCategoryNumber() ownMSG.setMessageText("MSG|" + this.client.getChatPreferences().getLoginChatCategoryMain().getCategoryNumber()
+ "|0|" + messageLine + "|0|"); + "|0|" + messageLine + "|0|"); //original before 1.26
try { try {
tx(ownMSG); tx(ownMSG);
@@ -108,7 +139,7 @@ public class WriteThread extends Thread {
} }
} }
if (messageTextRaw.equals("/QUIT")) { if (messageToBeSend.equals("/QUIT")) {
try { try {
this.client.getReadThread().terminateConnection(); this.client.getReadThread().terminateConnection();
this.client.getReadThread().interrupt(); this.client.getReadThread().interrupt();
@@ -117,7 +148,6 @@ public class WriteThread extends Thread {
this.interrupt(); this.interrupt();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -137,59 +167,62 @@ public class WriteThread extends Thread {
while (true) { while (true) {
try { try {
messageTextRaw = client.getMessageTXBus().take(); messageToBeSend = client.getMessageTXBus().take();
if (messageTextRaw.getMessageText().equals("POISONPILL_KILLTHREAD") if (messageToBeSend.getMessageText().equals("POISONPILL_KILLTHREAD")
&& messageTextRaw.getMessageSenderName().equals("POISONPILL_KILLTHREAD")) { && messageToBeSend.getMessageSenderName().equals("POISONPILL_KILLTHREAD")) {
client.getMessageRXBus().clear(); client.getMessageRXBus().clear();
this.interrupt(); this.interrupt();
break; break;
} else { } else {
String messageLine = messageTextRaw.getMessageText(); String messageLine = messageToBeSend.getMessageText();
if (messageTextRaw.isMessageDirectedToServer()) { if (messageToBeSend.isMessageDirectedToServer()) {
/** /**
* We have to check if we only commands the server (keepalive) or want do talk * We have to check if we only commands the server (keepalive) or want do talk
* to the community * to the community
*/ */
try { try {
tx(messageTextRaw); tx(messageToBeSend);
System.out.println("BUS: tx: " + messageTextRaw.getMessageText()); System.out.println("BUS: tx: " + messageToBeSend.getMessageText());
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} else { } else { //message is not directed to the server, it´s directed to all or to a station
if (messageToBeSend.getChatCategory() == this.client.getChatCategoryMain() || messageToBeSend.getChatCategory() == this.client.getChatCategorySecondChat()) {
txByRxmsgCatOrigin(messageToBeSend);
} else { //default bhv if destination cat is not detectable
ChatMessage ownMSG = new ChatMessage(); ChatMessage ownMSG = new ChatMessage();
// ownMSG.setMessageText(
// "MSG|" + this.client.getCategory().getCategoryNumber() + "|0|" + messageLine + "|0|");
ownMSG.setMessageText( ownMSG.setMessageText(
"MSG|" + this.client.getChatPreferences().getLoginChatCategory().getCategoryNumber() + "|0|" "MSG|" + this.client.getChatPreferences().getLoginChatCategoryMain().getCategoryNumber() + "|0|"
+ messageLine + "|0|"); + messageLine + "|0|");
try { try {
tx(ownMSG); tx(ownMSG);
System.out.println("BUS: tx: " + ownMSG.getMessageText()); System.out.println("WT: tx (raw): " + ownMSG.getMessageText());
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
}
System.out.println("WritheTh: got message out of the queue: " + messageTextRaw.getMessageText()); System.out.println("WritheTh: got message out of the queue: " + messageToBeSend.getMessageText());
// this.client.getmesetChatsetServerready(true); // this.client.getmesetChatsetServerready(true);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
client.getMessageTXBus().clear(); client.getMessageTXBus().clear();
} }

View File

@@ -0,0 +1,110 @@
package kst4contest.locatorUtils;
public class DirectionUtils {
/**
* Checks wheter a sked-sender writes to a sked-receiver and is in my direction due he beams to this receiver
*
* @param myLocator
* @param locatorOfSkedSender
* @param locatorOfSekdReceiver
* @param maxRangeKm
* @param hisAntennaBeamWidth
* @return
*/
public static boolean isInAngleAndRange(String myLocator, String locatorOfSkedSender, String locatorOfSekdReceiver, double maxRangeKm, double hisAntennaBeamWidth) {
Location myLocation = new Location(myLocator);
Location skedSenderLocation = new Location(locatorOfSkedSender);
Location skedReceiverLocation = new Location(locatorOfSekdReceiver);
double distanceFromMeToLocSender = new Location(myLocator).getDistanceKm(new Location(locatorOfSkedSender));
// Check if distance exceeds my setted maximum range
if (distanceFromMeToLocSender > maxRangeKm) {
System.out.println("too far, " + distanceFromMeToLocSender + " km");
return false;
}
//check bearing of sender to receiver
double bearingOfSekdSenderToSkedReceiver = skedSenderLocation.getBearing(skedReceiverLocation);
// System.out.println("skedTX -> skedTX deg: " + bearingOfSekdSenderToSkedReceiver);
double bearingOfSekdSenderToMe = skedSenderLocation.getBearing(myLocation);
// System.out.println("skedTX -> me deg: " + bearingOfSekdSenderToMe);
/**
* simple mech works
*/
// if (bearingOfSekdSenderToMe >= bearingOfSekdSenderToSkedReceiver) {
// if (bearingOfSekdSenderToMe-bearingOfSekdSenderToSkedReceiver <= hisAntennaBeamWidth/2){
// System.out.println(bearingOfSekdSenderToMe-bearingOfSekdSenderToSkedReceiver + " <= " + hisAntennaBeamWidth);
// return true;
// }
// } else if ((bearingOfSekdSenderToMe <= bearingOfSekdSenderToSkedReceiver)) {
// if (bearingOfSekdSenderToSkedReceiver-bearingOfSekdSenderToMe <= hisAntennaBeamWidth/2){
// return true;
// }
// } else return false;
/**
* simple mech end
*/
if (DirectionUtils.isAngleInRange(bearingOfSekdSenderToSkedReceiver, bearingOfSekdSenderToMe, hisAntennaBeamWidth)) {
//I may should get "/2" because of 50% of the 3dB opening angle if txer is directed to sender exactly
// System.out.println("------------> isinangleandrange!");
return true;
} else {
// System.out.println("not in angle and reach");
return false;
}
}
/**
* Tests, if the angle (from me to) other station is in the range of the
* angle (qtf) in degrees where my antenna points to.
*
* @param toForeignAngle [degrees]
* @param mySelectedQTFAngle [degrees]
* @param antennaBeamwidth [degrees]
* @return
*/
public static boolean isAngleInRange(double toForeignAngle,
double mySelectedQTFAngle, double antennaBeamwidth) {
double beamwidth = antennaBeamwidth / 2; // half left, half right
double startAngle = mySelectedQTFAngle - beamwidth;
double endAngle = mySelectedQTFAngle + beamwidth;
// Normalize angles to be between 0 and 360 degrees
toForeignAngle = normalizeAngle(toForeignAngle);
startAngle = normalizeAngle(startAngle);
endAngle = normalizeAngle(endAngle);
// Check if the range wraps around 360 degrees
if (startAngle <= endAngle) {
return toForeignAngle >= startAngle && toForeignAngle <= endAngle;
} else {
// Range wraps around 360 degrees, so check if angle is within the
// range or outside the range
return toForeignAngle >= startAngle || toForeignAngle <= endAngle;
}
}
private static double normalizeAngle(double angle) {
if (angle < 0) {
angle += 360;
}
if (angle >= 360) {
angle -= 360;
}
return angle;
}
}

View File

@@ -1,5 +1,10 @@
package kst4contest.locatorUtils; package kst4contest.locatorUtils;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
/** /**
* Location class with methods allowing conversion to and from Maidenhead * Location class with methods allowing conversion to and from Maidenhead
* locator (grid squares) based off of * locator (grid squares) based off of
@@ -203,6 +208,27 @@ public class Location {
return getDistanceKm(this, loc2); return getDistanceKm(this, loc2);
} }
/**
* @param locator1 6 letter location string
* @param locator2 6 letter location string
* @return great circle distance in kilometers
*/
public double getDistanceKmByTwoLocatorStrings(String locator1,String locator2 ) {
Location loc1 = new Location(locator1);
Location loc2 = new Location(locator2);
Locale locale = new Locale("en", "UK");
String pattern = "###.##";
DecimalFormat decimalFormat = (DecimalFormat)
NumberFormat.getNumberInstance(locale);
decimalFormat.applyPattern(pattern);
String format = decimalFormat.format(loc1.getDistanceKm(loc2));
return Double.parseDouble(format);
}
/** /**
* @param loc2 * @param loc2
* second location * second location
@@ -278,6 +304,19 @@ public class Location {
return getBearing(this, loc2); return getBearing(this, loc2);
} }
/**
*
* @return bearing in degrees
*/
public double getBearingOfTwoLocatorStrings(String locator1, String locator2) {
Location loc1 = new Location(locator1);
Location loc2 = new Location(locator2);
return getBearing(loc1, loc2);
}
/** /**
* @param loc1 * @param loc1
* source location * source location
@@ -300,6 +339,21 @@ public class Location {
- Math.sin(loc1.getLatitude().getRadians()) - Math.sin(loc1.getLatitude().getRadians())
* Math.cos(loc2.getLatitude().getRadians()) * Math.cos(loc2.getLatitude().getRadians())
* Math.cos(dLon); * Math.cos(dLon);
return (Angle.radiansToDegrees(Math.atan2(y, x)) + 360) % 360;
double bearing = (Angle.radiansToDegrees(Math.atan2(y, x)) + 360) % 360;
// return bearing;
Locale locale = new Locale("en", "UK");
String pattern = "###.##";
DecimalFormat decimalFormat = (DecimalFormat)
NumberFormat.getNumberInstance(locale);
decimalFormat.applyPattern(pattern);
String format = decimalFormat.format(bearing);
return Double.parseDouble(format);
} }
} }

View File

@@ -0,0 +1,43 @@
package kst4contest.locatorUtils;
public class TestLocatorUtils {
public static void main(String[] args) {
// isInAngle(myLocation, location1, location2);
System.out.println(isInAngleAndRange("JN49FL", "jo43xm", "jo30sa", 900, 50));
System.out.println(isInAngleAndRange("JN49FL", "jo51ij", "jn39oc", 900, 50));
System.out.println(isInAngleAndRange("JN49FL", "jn39oc", "jo51ij", 1100, 50));
}
public static boolean isInAngleAndRange(String myLocator, String locatorOfSkedSender, String locatorOfSekdReceiver, double maxRangeKm, double hisAntennaBeamWidth) {
Location myLocation = new Location(myLocator);
Location skedSenderLocation = new Location(locatorOfSkedSender);
Location skedReceiverLocation = new Location(locatorOfSekdReceiver);
double distanceFromMeToLocSender = new Location(myLocator).getDistanceKm(new Location(locatorOfSkedSender));
// Check if distance exceeds my setted maximum range
if (distanceFromMeToLocSender > maxRangeKm) {
System.out.println("too far, " + distanceFromMeToLocSender + " km");
return false;
}
//check bearing of sender to receiver
double bearingOfSekdSenderToSkedReceiver = skedSenderLocation.getBearing(skedReceiverLocation);
System.out.println("skedTX -> skedRX deg: " + bearingOfSekdSenderToSkedReceiver);
double bearingOfSekdSenderToMe = skedSenderLocation.getBearing(myLocation);
System.out.println("skedTX -> me deg: " + bearingOfSekdSenderToMe);
if (DirectionUtils.isAngleInRange(bearingOfSekdSenderToSkedReceiver, bearingOfSekdSenderToMe, hisAntennaBeamWidth)) {
//may I should get "/2" because of 50% of the 3dB opening angle if txer is directed to sender exactly
return true;
} else return false;
}
}

View File

@@ -3,6 +3,25 @@ package kst4contest.model;
public class AirPlane { public class AirPlane {
String apCallSign, apSizeCategory; String apCallSign, apSizeCategory;
String potencialDescriptionAsWord;
public String getPotencialDescriptionAsWord() {
if (this.getPotential() <=50) {
return "small AP";
} else if (this.getPotential() <=75 && this.getPotential() > 50) {
return "big AP";
} else if (this.getPotential() > 75) {
return "very big AP";
}
return potencialDescriptionAsWord;
}
public void setPotencialDescriptionAsWord(String potencialDescriptionAsWord) {
this.potencialDescriptionAsWord = potencialDescriptionAsWord;
}
int distanceKm, potential, arrivingDurationMinutes; int distanceKm, potential, arrivingDurationMinutes;
public String getApCallSign() { public String getApCallSign() {
return apCallSign; return apCallSign;

View File

@@ -53,28 +53,17 @@ public class ChatCategory {
public ChatCategory(int setThiscategoryNumber) { public ChatCategory(int setThiscategoryNumber) {
this.categoryNumber = setThiscategoryNumber; this.categoryNumber = setThiscategoryNumber;
setCategoryNumber(setThiscategoryNumber);
} }
public int getCategoryNumber() { public int getCategoryNumber() {
return categoryNumber; return categoryNumber;
} }
public void setCategoryNumber(int categoryNumber) { public void setCategoryNumber(int categoryNumber) {
this.categoryNumber = categoryNumber; this.categoryNumber = categoryNumber;
} }
/** /**
* Returns an Array of int with possible frequency prefixes, due to in the chat * Returns an Array of int with possible frequency prefixes, due to in the chat
* normally the following format is used (not ever): <br/> * normally the following format is used (not ever): <br/>

View File

@@ -2,30 +2,39 @@ package kst4contest.model;
import java.util.Date; import java.util.Date;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
public class ChatMember { public class ChatMember {
// private final BooleanProperty workedInfoChangeFireListEventTrigger = new SimpleBooleanProperty();
AirPlaneReflectionInfo airPlaneReflectInfo; AirPlaneReflectionInfo airPlaneReflectInfo;
String callSign; String callSign;
String qra; String qra;
String name; String name;
String callSignRaw; //without -2 or -70 etc.
boolean isInAngleAndRange; //if he tries a sked in my dir, he is in range, will process that in the messages
// String frequency; // last known qrg of the station // String frequency; // last known qrg of the station
StringProperty frequency = new SimpleStringProperty(); StringProperty frequency = new SimpleStringProperty();
String password; // only used by own instance of the chatmember instance to login to the chat String password; // only used by own instance of the chatmember instance to login to the chat
ChatCategory chatCategory; // only used by own instance of the chatmember instance to login to the chat ChatCategory chatCategory; //Source category
// ChatCategory chatCategory;//only used by own instance of the chatmember instance to login to the chat // ChatCategory chatCategory;//only used by own instance of the chatmember instance to login to the chat
long activityCounter; // time of last activity in epochtimesec long activityTimeLastInEpoch; // time of last activity in epochtimesec
Date lastActivity; // time of last activity in epochtimesec Date lastActivity; // time of last activity in epochtimesec
Date lastActualizationTimeOfThisMember; // time of last state change if that member Date lastActualizationTimeOfThisMember; // time of last state change if that member
int qrb; Double qrb;
int state; int state;
int QTFdirection; // antenna direction in deg Double QTFdirection; // antenna direction in deg
int[] workedCategories; // Chatcategory where the station is in the log, see kst4contest.model.ChatCategory int[] workedCategories; // Chatcategory where the station is in the log, see kst4contest.model.ChatCategory
boolean worked; // true if the callsign is logged already - for temporary worked processing boolean worked; // true if the callsign is logged already - for temporary worked processing
@@ -37,6 +46,30 @@ public class ChatMember {
boolean worked5600; boolean worked5600;
boolean worked10G; boolean worked10G;
/**
* Chatmember is qrv at all band except we initialize anything other, depending to user entry
*/
boolean qrv144 = true;
boolean qrv432 = true;
boolean qrv1240 = true;
boolean qrv2300 = true;
boolean qrv3400 = true;
boolean qrv5600 = true;
boolean qrv10G = true;
boolean qrvAny = true;
public boolean isInAngleAndRange() {
return isInAngleAndRange;
}
public void setInAngleAndRange(boolean inAngleAndRange) {
isInAngleAndRange = inAngleAndRange;
}
public AirPlaneReflectionInfo getAirPlaneReflectInfo() { public AirPlaneReflectionInfo getAirPlaneReflectInfo() {
return airPlaneReflectInfo; return airPlaneReflectInfo;
} }
@@ -117,6 +150,70 @@ public class ChatMember {
worked10G = worked10g; worked10G = worked10g;
} }
public boolean isQrv144() {
return qrv144;
}
public void setQrv144(boolean qrv144) {
this.qrv144 = qrv144;
}
public boolean isQrv432() {
return qrv432;
}
public void setQrv432(boolean qrv432) {
this.qrv432 = qrv432;
}
public boolean isQrv1240() {
return qrv1240;
}
public void setQrv1240(boolean qrv1240) {
this.qrv1240 = qrv1240;
}
public boolean isQrv2300() {
return qrv2300;
}
public void setQrv2300(boolean qrv2300) {
this.qrv2300 = qrv2300;
}
public boolean isQrv3400() {
return qrv3400;
}
public void setQrv3400(boolean qrv3400) {
this.qrv3400 = qrv3400;
}
public boolean isQrv5600() {
return qrv5600;
}
public void setQrv5600(boolean qrv5600) {
this.qrv5600 = qrv5600;
}
public boolean isQrv10G() {
return qrv10G;
}
public void setQrv10G(boolean qrv10G) {
this.qrv10G = qrv10G;
}
public boolean isQrvAny() {
return qrvAny;
}
public void setQrvAny(boolean qrvAny) {
this.qrvAny = qrvAny;
}
public int[] getWorkedCategories() { public int[] getWorkedCategories() {
return workedCategories; return workedCategories;
} }
@@ -125,8 +222,8 @@ public class ChatMember {
this.workedCategories = workedCategories; this.workedCategories = workedCategories;
} }
public void setActivityCounter(long activityCounter) { public void setActivityTimeLastInEpoch(long activityTimeLastInEpoch) {
this.activityCounter = activityCounter; this.activityTimeLastInEpoch = activityTimeLastInEpoch;
} }
public int getState() { public int getState() {
@@ -153,28 +250,22 @@ public class ChatMember {
this.lastActualizationTimeOfThisMember = lastActualizationTimeOfThisMember; this.lastActualizationTimeOfThisMember = lastActualizationTimeOfThisMember;
} }
public int getQrb() { public Double getQrb() {
return qrb; return qrb;
} }
public void setQrb(int qrb) { public void setQrb(Double qrb) {
this.qrb = qrb; this.qrb = qrb;
} }
public int getQTFdirection() { public Double getQTFdirection() {
return QTFdirection; return QTFdirection;
} }
public void setQTFdirection(int qTFdirection) { public void setQTFdirection(Double qTFdirection) {
QTFdirection = qTFdirection; QTFdirection = qTFdirection;
} }
// public int getWorkedCategory() {
// return workedCategory;
// }
// public void setWorkedCategory(int workedCategory) {
// this.workedCategory = workedCategory;
// }
public String getCallSign() { public String getCallSign() {
return callSign; return callSign;
} }
@@ -210,12 +301,12 @@ public class ChatMember {
this.frequency = frequency; this.frequency = frequency;
} }
public long getActivityCounter() { public long getActivityTimeLastInEpoch() {
return activityCounter; return activityTimeLastInEpoch;
} }
public void setActivityCounter(int activityCounter) { public void setActivityCounter(int activityCounter) {
this.activityCounter = activityCounter; this.activityTimeLastInEpoch = activityCounter;
} }
public boolean isWorked() { public boolean isWorked() {
@@ -224,8 +315,25 @@ public class ChatMember {
public void setWorked(boolean worked) { public void setWorked(boolean worked) {
this.worked = worked; this.worked = worked;
} }
/**
*
* @return String (callsign) without -2 or -70 etc.
*/
public String getCallSignRaw() {
String raw = "";
try {
return this.getCallSign().split("-")[0]; //e.g. OK2M-70, returns only ok2m
} catch (Exception e) {
return getCallSign();
}
}
/** /**
* Sets all worked information of this object to false. Scope: GUI, Reset Button * Sets all worked information of this object to false. Scope: GUI, Reset Button
* for worked info, called by appcontroller * for worked info, called by appcontroller
@@ -242,13 +350,29 @@ public class ChatMember {
this.setWorked10G(false); this.setWorked10G(false);
} }
/**
* Sets all worked information of this object to false. Scope: GUI, Reset Button
* for worked info, called by appcontroller
*/
public void resetQRVInformationAtAllBands() {
this.setQrvAny(true);
this.setQrv144(true);
this.setQrv432(true);
this.setQrv1240(true);
this.setQrv2300(true);
this.setQrv3400(true);
this.setQrv5600(true);
this.setQrv10G(true);
}
@Override @Override
public String toString() { public String toString() {
String chatMemberSerialization = ""; String chatMemberSerialization = "";
chatMemberSerialization += callSign + ";" + name + ";" + qra + ";" + frequency + ";" + worked + ";" + worked144 chatMemberSerialization += callSign + ";" + name + ";" + qra + ";" + frequency + "; wkd " + worked + "; wkd144 " + worked144
+ ";" + worked432 + ";" + worked1240 + ";" + worked2300 + ";" + worked3400 + ";" + worked5600 + ";" + "; wkd432" + worked432 + "; wkd1240" + worked1240 + "; wkd2300" + worked2300 + "; wkd3400" + worked3400 + "; wkd5600" + worked5600 + "; wkd10G"
+ worked10G; + worked10G + " ; " + chatCategory;
return chatMemberSerialization; return chatMemberSerialization;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
package kst4contest.model;
import java.util.ArrayList;
public class UpdateInformation {
double latestVersionNumberOnServer = 1.26; //dummy value to prevent nullpointerexc
String adminMessage ="";
String majorChanges ="";
String latestVersionPathOnWebserver="";
ArrayList<String> needUpdateResourcesSinceLastVersion = new ArrayList<String>();
ArrayList<String[]> featureRequest = new ArrayList<String[]>();
ArrayList<String[]> bugRequests = new ArrayList<String[]>();
ArrayList<String[]> changeLog = new ArrayList<String[]>();
ArrayList<String[]> bugList = new ArrayList<String[]>();
public ArrayList<String[]> getBugList() {
return bugList;
}
public void setBugList(ArrayList<String[]> bugList) {
this.bugList = bugList;
}
public ArrayList<String[]> getChangeLog() {
return changeLog;
}
public void setChangeLog(ArrayList<String[]> changeLog) {
this.changeLog = changeLog;
}
public double getLatestVersionNumberOnServer() {
return latestVersionNumberOnServer;
}
public void setLatestVersionNumberOnServer(double latestVersionNumberOnServer) {
this.latestVersionNumberOnServer = latestVersionNumberOnServer;
}
public String getAdminMessage() {
return adminMessage;
}
public void setAdminMessage(String adminMessage) {
this.adminMessage = adminMessage;
}
public String getMajorChanges() {
return majorChanges;
}
public void setMajorChanges(String majorChanges) {
this.majorChanges = majorChanges;
}
public String getLatestVersionPathOnWebserver() {
return latestVersionPathOnWebserver;
}
public void setLatestVersionPathOnWebserver(String latestVersionPathOnWebserver) {
this.latestVersionPathOnWebserver = latestVersionPathOnWebserver;
}
public ArrayList<String> getNeedUpdateResourcesSinceLastVersion() {
return needUpdateResourcesSinceLastVersion;
}
public void setNeedUpdateResourcesSinceLastVersion(ArrayList<String> needUpdateResourcesSinceLastVersion) {
this.needUpdateResourcesSinceLastVersion = needUpdateResourcesSinceLastVersion;
}
public ArrayList<String[]> getFeatureRequest() {
return featureRequest;
}
public void setFeatureRequest(ArrayList<String[]> featureRequest) {
this.featureRequest = featureRequest;
}
public ArrayList<String[]> getBugRequests() {
return bugRequests;
}
public void setBugRequests(ArrayList<String[]> bugRequests) {
this.bugRequests = bugRequests;
}
}

View File

@@ -0,0 +1,131 @@
package kst4contest.test;
import javafx.beans.property.SimpleStringProperty;
import kst4contest.controller.Utils4KST;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternMatcherTest {
/**
* Tests if pattern matches with the given String.
*
* @param testString
* @param regExPattern
* @return true if match, else false
*/
private static boolean testPattern(String testString, String regExPattern) {
Pattern pattern = Pattern.compile(regExPattern);
Matcher matcher = pattern.matcher(testString);
return matcher.find();
}
/**
* Normalizes a chatmembers frequency-string for cluster usage<br/>
* <b>returns a frequency String in KHz like = "144300" or "144300.0" to match DXC protocol needs</b>
*
* @param optionalPrefix: if there is a value like ".300", it have to be decided, wich ".300": 144.300, 432.300, 1296.300 .... prefix means for example "144."
*/
private static String normalizeFrequencyString(String qrgString, String optionalPrefix) {
// final String PTRN_QRG_CAT2 = "(([0-9]{3,4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)";
final String PTRN_QRG_CAT2_wholeQRGMHz4Digits = "(([0-9]{4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)"; //1296.300.3 etc
final String PTRN_QRG_CAT2_wholeQRGMHz3Digits = "(([0-9]{3}[\\.|,| ]?[0-9]{3})([\\.][\\d]{1,2})?)"; //144.300.3 etc
final String PTRN_QRG_CAT2_QRGwithoutPrefix = "((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)"; //144.300.3 etc
String predefinedPrefixInMHz = optionalPrefix;
String stringAggregation = "";
if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz4Digits)) {
System.out.print("yep: ");
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".","");
stringAggregation = stringAggregation.replace(",","");
if (stringAggregation.length() == 8) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length());
stringAggregation = stringAggregationNew;
} else if (stringAggregation.length() == 9) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length());
stringAggregation = stringAggregationNew;
}
} else
if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz3Digits)) {
System.out.print("yep: ");
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".","");
stringAggregation = stringAggregation.replace(",","");
if (stringAggregation.length() == 7) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length());
stringAggregation = stringAggregationNew;
} else if (stringAggregation.length() == 8) {
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length());
stringAggregation = stringAggregationNew;
}
}
else
if (testPattern(qrgString, PTRN_QRG_CAT2_QRGwithoutPrefix)) { //case ".050 or .300 or something like that"
System.out.print("yep: ");
stringAggregation = qrgString;
stringAggregation = stringAggregation.replace(".", "");
stringAggregation = stringAggregation.replace(",", "");
if (stringAggregation.length() == 3) { // like 050 or 300
String stringAggregationNew = optionalPrefix + stringAggregation;
stringAggregation = stringAggregationNew;
return stringAggregation;
} else if (stringAggregation.length() == 4) { //like 050.2 --> 0502
stringAggregation = optionalPrefix + stringAggregation;
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 1) + "." + stringAggregation.substring(stringAggregation.length() - 1, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
} else if (stringAggregation.length() == 5) { //like 050.20 --> 05020
stringAggregation = optionalPrefix + stringAggregation;
String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 2) + "." + stringAggregation.substring(stringAggregation.length() - 2, stringAggregation.length());
stringAggregation = stringAggregationNew;
return stringAggregation;
}
}
return qrgString;
}
public static void main(String[] args) {
int i = 0;
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.775", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144,300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300,2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.20", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("300", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.20", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.20", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,20", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300,2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300.2", new SimpleStringProperty("144")));
System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("q305", new SimpleStringProperty("144")));
}
}

View File

@@ -0,0 +1,484 @@
package kst4contest.utils;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import kst4contest.ApplicationConstants;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
/**
* This part of the client drives the sounds. Its a singleton instance. All audio outs are directed to this instance.<br>
* <br>
* */
public class PlayAudioUtils {
/**
* Default constructor initializes the sound files and copies it to the project home folder
*/
public PlayAudioUtils() {
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/NOISESTARTUP.mp3", "NOISESTARTUP.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/NOISECQWINDOW.mp3", "NOISECQWINDOW.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/NOISEPMWINDOW.mp3", "NOISEPMWINDOW.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/NOISEERROR.mp3", "NOISEERROR.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/NOISENOTIFY.mp3", "NOISENOTIFY.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/tick.mp3", "tick.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRA.mp3", "LTTRA.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRB.mp3", "LTTRB.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRC.mp3", "LTTRC.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRD.mp3", "LTTRD.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRE.mp3", "LTTRE.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRF.mp3", "LTTRF.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRG.mp3", "LTTRG.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRH.mp3", "LTTRH.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRI.mp3", "LTTRI.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRJ.mp3", "LTTRJ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRK.mp3", "LTTRK.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRL.mp3", "LTTRL.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRM.mp3", "LTTRM.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRN.mp3", "LTTRN.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRO.mp3", "LTTRO.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRP.mp3", "LTTRP.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRQ.mp3", "LTTRQ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRR.mp3", "LTTRR.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRS.mp3", "LTTRS.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRT.mp3", "LTTRT.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRU.mp3", "LTTRU.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRV.mp3", "LTTRV.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRW.mp3", "LTTRW.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRX.mp3", "LTTRX.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRY.mp3", "LTTRY.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRZ.mp3", "LTTRZ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR0.mp3", "LTTR0.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR1.mp3", "LTTR1.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR2.mp3", "LTTR2.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR3.mp3", "LTTR3.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR4.mp3", "LTTR4.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR5.mp3", "LTTR5.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR6.mp3", "LTTR6.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR7.mp3", "LTTR7.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR8.mp3", "LTTR8.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTR9.mp3", "LTTR9.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRSTROKE.mp3", "LTTRSTROKE.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/LTTRSPACE.mp3", "LTTRSPACE.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEA.mp3", "VOICEA.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEB.mp3", "VOICEB.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEC.mp3", "VOICEC.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICED.mp3", "VOICED.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEE.mp3", "VOICEE.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEF.mp3", "VOICEF.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEG.mp3", "VOICEG.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEH.mp3", "VOICEH.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEI.mp3", "VOICEI.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEJ.mp3", "VOICEJ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEK.mp3", "VOICEK.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEL.mp3", "VOICEL.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEM.mp3", "VOICEM.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEN.mp3", "VOICEN.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEO.mp3", "VOICEO.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEP.mp3", "VOICEP.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEQ.mp3", "VOICEQ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICER.mp3", "VOICER.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICES.mp3", "VOICES.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICET.mp3", "VOICET.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEU.mp3", "VOICEU.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEV.mp3", "VOICEV.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEW.mp3", "VOICEW.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEX.mp3", "VOICEX.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEY.mp3", "VOICEY.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEZ.mp3", "VOICEZ.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE0.mp3", "VOICE0.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE1.mp3", "VOICE1.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE2.mp3", "VOICE2.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE3.mp3", "VOICE3.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE4.mp3", "VOICE4.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE5.mp3", "VOICE5.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE6.mp3", "VOICE6.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE7.mp3", "VOICE7.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE8.mp3", "VOICE8.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE9.mp3", "VOICE9.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICESTROKE.mp3", "VOICESTROKE.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEBELL.mp3", "VOICEBELL.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEYOUGOTMAIL.mp3", "VOICEYOUGOTMAIL.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICEHELLO.mp3", "VOICEHELLO.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICE73.mp3", "VOICE73.mp3");
ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, "/VOICESTROKEPORTABLE.mp3", "VOICESTROKEPORTABLE.mp3");
}
private Queue<Media> musicList = new LinkedList<Media>();
private MediaPlayer mediaPlayer ;
/**
* Plays notification sounds out of the windws 95 box by given action character<br/>
*<br/>
*
* case '!': Startup<br/>
* case '-': tick<br/>
* case 'C': CQ Window new entry<br/>
* case 'P': PM Window new entry<br/>
* case 'E': Error occured<br/>
* case 'N': other notification sounds<br/>
*
* @param actionChar
*/
public void playNoiseLauncher(char actionChar) {
// ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISESTARTUP.mp3");
switch (actionChar){
case '-':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/tick.mp3")).toURI().toString()));
break;
case '!':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISESTARTUP.mp3")).toURI().toString()));
break;
case 'C':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISECQWINDOW.mp3")).toURI().toString()));
break;
case 'P':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISEPMWINDOW.mp3")).toURI().toString()));
break;
case 'E':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISEERROR.mp3")).toURI().toString()));
break;
case 'N':
musicList.add(new Media(new File (ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/NOISENOTIFY.mp3")).toURI().toString()));
break;
// case 'M':
// musicList.add(new Media(new File ("VOICE.mp3").toURI().toString()));
// break;
default:
System.out.println("[KST4ContestApp, warning, letter not defined!]");
}
playMusic();
// mediaPlayer.dispose();
}
/**
* Plays all chars of a given String-parameter as CW Sound out of the speaker.
* As a workaround for delay problems at the beginning of playing, there are added 2x pause chars to the string.
*
* @param playThisChars
*/
public void playCWLauncher(String playThisChars) {
char[] playThisInCW = playThisChars.toUpperCase().toCharArray();
for (char letterToPlay: playThisInCW){
switch (letterToPlay){
case 'A':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRA.mp3")).toURI().toString()));
break;
case 'B':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRB.mp3")).toURI().toString()));
break;
case 'C':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRC.mp3")).toURI().toString()));
break;
case 'D':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRD.mp3")).toURI().toString()));
break;
case 'E':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRE.mp3")).toURI().toString()));
break;
case 'F':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRF.mp3")).toURI().toString()));
break;
case 'G':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRG.mp3")).toURI().toString()));
break;
case 'H':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRH.mp3")).toURI().toString()));
break;
case 'I':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRI.mp3")).toURI().toString()));
break;
case 'J':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRJ.mp3")).toURI().toString()));
break;
case 'K':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRK.mp3")).toURI().toString()));
break;
case 'L':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRL.mp3")).toURI().toString()));
break;
case 'M':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRM.mp3")).toURI().toString()));
break;
case 'N':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRN.mp3")).toURI().toString()));
break;
case 'O':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRO.mp3")).toURI().toString()));
break;
case 'P':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRP.mp3")).toURI().toString()));
break;
case 'Q':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRQ.mp3")).toURI().toString()));
break;
case 'R':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRR.mp3")).toURI().toString()));
break;
case 'S':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRS.mp3")).toURI().toString()));
break;
case 'T':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRT.mp3")).toURI().toString()));
break;
case 'U':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRU.mp3")).toURI().toString()));
break;
case 'V':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRV.mp3")).toURI().toString()));
break;
case 'W':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRW.mp3")).toURI().toString()));
break;
case 'X':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRX.mp3")).toURI().toString()));
break;
case 'Y':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRY.mp3")).toURI().toString()));
break;
case 'Z':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRZ.mp3")).toURI().toString()));
break;
case '1':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR1.mp3")).toURI().toString()));
break;
case '2':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR2.mp3")).toURI().toString()));
break;
case '3':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR3.mp3")).toURI().toString()));
break;
case '4':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR4.mp3")).toURI().toString()));
break;
case '5':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR5.mp3")).toURI().toString()));
break;
case '6':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR6.mp3")).toURI().toString()));
break;
case '7':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR7.mp3")).toURI().toString()));
break;
case '8':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR8.mp3")).toURI().toString()));
break;
case '9':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR9.mp3")).toURI().toString()));
break;
case '0':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTR0.mp3")).toURI().toString()));
break;
case '/':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRSTROKE.mp3")).toURI().toString()));
break;
case ' ':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/LTTRSPACE.mp3")).toURI().toString()));
break;
default:
System.out.println("[KST4ContestApp, warning, letter not defined:] cwLetters = " + Arrays.toString(playThisInCW));
}
}
playMusic();
// mediaPlayer.dispose();
}
/**
*
* Plays a voice file for each char in the string (only EN alphabetic and numbers) except some specials: <br/><br/>
* <b>Note that the audio settings (ChatPreferences) must be switched on in order to make the sounds playing.</b><br/><br/>
* case '!': BELL<br/>
* case '?': YOUGOTMAIL<br/>
* case '#': HELLO<br/>
* case '*': 73 bye<br/>
* case '$': STROKEPORTABLE<br/>
* @param playThisChars
*/
public void playVoiceLauncher(String playThisChars) {
char[] spellThisWithVoice = playThisChars.toUpperCase().toCharArray();
for (char letterToPlay: spellThisWithVoice){
switch (letterToPlay){
case '!':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEBELL.mp3")).toURI().toString()));
break;
case '?':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEYOUGOTMAIL.mp3")).toURI().toString()));
break;
case '#':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEHELLO.mp3")).toURI().toString()));
break;
case '*':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE73.mp3")).toURI().toString()));
break;
case '$':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICESTROKEPORTABLE.mp3")).toURI().toString()));
break;
case 'A':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEA.mp3")).toURI().toString()));
break;
case 'B':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEB.mp3")).toURI().toString()));
break;
case 'C':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEC.mp3")).toURI().toString()));
break;
case 'D':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICED.mp3")).toURI().toString()));
break;
case 'E':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEE.mp3")).toURI().toString()));
break;
case 'F':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEF.mp3")).toURI().toString()));
break;
case 'G':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEG.mp3")).toURI().toString()));
break;
case 'H':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEH.mp3")).toURI().toString()));
break;
case 'I':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEI.mp3")).toURI().toString()));
break;
case 'J':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEJ.mp3")).toURI().toString()));
break;
case 'K':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEK.mp3")).toURI().toString()));
break;
case 'L':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEL.mp3")).toURI().toString()));
break;
case 'M':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEM.mp3")).toURI().toString()));
break;
case 'N':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEN.mp3")).toURI().toString()));
break;
case 'O':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEO.mp3")).toURI().toString()));
break;
case 'P':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEP.mp3")).toURI().toString()));
break;
case 'Q':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEQ.mp3")).toURI().toString()));
break;
case 'R':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICER.mp3")).toURI().toString()));
break;
case 'S':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICES.mp3")).toURI().toString()));
break;
case 'T':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICET.mp3")).toURI().toString()));
break;
case 'U':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEU.mp3")).toURI().toString()));
break;
case 'V':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEV.mp3")).toURI().toString()));
break;
case 'W':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEW.mp3")).toURI().toString()));
break;
case 'X':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEX.mp3")).toURI().toString()));
break;
case 'Y':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEY.mp3")).toURI().toString()));
break;
case 'Z':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICEZ.mp3")).toURI().toString()));
break;
case '1':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE1.mp3")).toURI().toString()));
break;
case '2':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE2.mp3")).toURI().toString()));
break;
case '3':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE3.mp3")).toURI().toString()));
break;
case '4':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE4.mp3")).toURI().toString()));
break;
case '5':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE5.mp3")).toURI().toString()));
break;
case '6':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE6.mp3")).toURI().toString()));
break;
case '7':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE7.mp3")).toURI().toString()));
break;
case '8':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE8.mp3")).toURI().toString()));
break;
case '9':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE9.mp3")).toURI().toString()));
break;
case '0':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICE0.mp3")).toURI().toString()));
break;
case '/':
musicList.add(new Media(new File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, "/VOICESTROKE.mp3")).toURI().toString()));
break;
// case ' ':
// musicList.add(new Media(new File ("VOICESPACE.mp3").toURI().toString()));
// break;
default:
System.out.println("[KST4ContestApp, warning, letter not defined:] cwLetters = " + Arrays.toString(spellThisWithVoice));
}
}
playMusic();
// mediaPlayer.dispose();
}
private void playMusic() {
// System.out.println("Kst4ContestApplication.playMusic");
if(musicList.peek() == null)
{
return;
}
mediaPlayer = new MediaPlayer(musicList.poll());
mediaPlayer.setRate(1.0);
mediaPlayer.setOnReady(() -> {
mediaPlayer.play();
mediaPlayer.setOnEndOfMedia(() -> {
// mediaPlayer.dispose();
playMusic();
if (musicList.isEmpty()) {
// mediaPlayer.dispose();
}
});
});
}
}

View File

@@ -0,0 +1,19 @@
package kst4contest.utils;
import javafx.application.Application;
import javafx.stage.Stage;
import kst4contest.utils.PlayAudioUtils;
public class TestAudioPlayerUtils extends Application {
public static void main(String[] args) {
}
@Override
public void start(Stage stage) throws Exception {
PlayAudioUtils testAudio = new PlayAudioUtils();
testAudio.playCWLauncher("DO5AMF");
}
}

View File

@@ -1,7 +1,15 @@
package kst4contest.view; package kst4contest.view;
import kst4contest.controller.ChatController;
import kst4contest.model.ChatMember;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GuiUtils { public class GuiUtils {
private static final String PTRN_CALLSIGNSYNTAX = "^(?:[A-Z]{1,2}[0-9]|[0-9][A-Z])[0-9A-Z]{1,3}$";
/** /**
* Checks wheter the input value of the String is numeric or not, true if yes * Checks wheter the input value of the String is numeric or not, true if yes
* TODO: Move to a utils class for checking input values by user... * TODO: Move to a utils class for checking input values by user...
@@ -12,4 +20,49 @@ public class GuiUtils {
return str != null && str.matches("[0-9.]+"); return str != null && str.matches("[0-9.]+");
} }
/**
* Checks wheter the given String has a HAM radio callsign syntax or not
* @param maybeCallSignValue
* @return true if yes
*/
static boolean isCallSignSyntax(String maybeCallSignValue) {
Pattern pattern = Pattern.compile(PTRN_CALLSIGNSYNTAX, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(maybeCallSignValue);
try {
if (matcher.find()) {
return true;
}
else return false;
} catch (Exception exc) {
return false;
}
}
public static void triggerGUIFilteredChatMemberListChange(ChatController chatController) {
{
//trick to trigger gui changes on property changes of obects
Predicate<ChatMember> dummyPredicate = new Predicate<ChatMember>() {
@Override
public boolean test(ChatMember chatMember) {
return true;
}
};
/**
* //TODO: following 2 lines are a quick fix to making disappear worked chatmembers of the list
* Thats uncomfortable due to this also causes selection changes,
* Better way is to change all worked and qrv values to observables and then trigger the underlying
* list to fire an invalidationevent. Really Todo!
*/
chatController.getLst_chatMemberListFilterPredicates().add(dummyPredicate);
chatController.getLst_chatMemberListFilterPredicates().remove(dummyPredicate);
}
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
module praktiKST {
requires javafx.controls;
requires jdk.xml.dom;
requires java.sql;
requires javafx.media;
exports kst4contest.controller;
exports kst4contest.locatorUtils;
exports kst4contest.model;
exports kst4contest.view;
}

View File

@@ -0,0 +1,154 @@
.button:pressed {
-fx-border-color: #ff0000;
}
.button:hover {
-fx-border-color: #ff7777;
}
.toggle-button:selected {
-fx-background-color:linear-gradient(#f0ff35, #a9ff00),
radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.text-field {
-fx-prompt-text-fill: black;
}
.text-field .text {
-fx-fill: linear-gradient(from 0% 0% to 100% 200%, green 0%, lightgreen 100%);
-fx-stroke: green;
-fx-stroke-width: 0.2;
-fx-font-size: 25px;
}
.text-input-MYQRG1 {
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, orange 0%, red 100%);
-fx-font-weight: 300;
}
.button{
-fx-focus-traversable: false;
}
.button:hover{
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, blue 0%, red 100%);
}
.button:hover {
-fx-background-color:linear-gradient(#f0ff35, #a9ff00),
radial-gradient(center 50% -40%, radius 200%, lightblue 45%, orange 50%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.buttonMyQrg1 {
-fx-background-color: linear-gradient(from 0% 0% to 100% 200%, #00ffff 0%, #ff99ff 100%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.toggle-button:selected {
-fx-background-color: linear-gradient(from 0% 0% to 100% 200%, #00ffff 0%, #ff99ff 100%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.table-view .column-header .text {
-fx-fill: linear-gradient(from 0% 0% to 100% 200%, repeat, black 0%, red 50%);
-fx-stroke: black;
-fx-stroke-width: 0.3;
}
.table-view .column-header .label{
-fx-alignment: CENTER_LEFT;
-fx-font-weight: none;
}
.table-row-cell > .defaultText-column {
-fx-text-fill: black;
-fx-background-insets: 0 0 1 0px;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.table-row-cell > .messageToMe-column {
-fx-text-fill: green;
-fx-background-insets: 0 0 1 0px;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlightOwn-column { /*PM own message*/
-fx-background-color: #00ffff;
-fx-background-insets: 0 0 1 0px;
-fx-text-fill: black;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight30-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #33cc33;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight60-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #40bf40;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight90-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #4db34d;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight120-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #59a659;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight180-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #669966;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight300-column { /*PM for 30 sec: works*/
-fx-text-fill: black;
-fx-background-color: #738c73;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.table-cell-bold {
-fx-font-weight: bold;
}
.table-cell-inAngleAndRange {
-fx-text-fill: green;
-fx-font-weight: bold;
}
.table-cell-100PercentAP { /*GEHT*/
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, #f98aff 0%, #f98aff 100%); /*purple*/;
-fx-font-weight: bold;
}
.table-cell-75PercentAP { /*GEHT*/
-fx-text-fill: #fa6666;
-fx-font-weight: bold;
}
.table-cell-50PercentAP {
-fx-text-fill: #fa9f66;
-fx-font-weight: bold;
}

View File

@@ -0,0 +1,192 @@
.root {
-fx-accent: #1e74c6;
-fx-focus-color: -fx-accent;
-fx-base: #373e43;
-fx-control-inner-background: derive(-fx-base, 35%);
-fx-control-inner-background-alt: -fx-control-inner-background ;
}
.label{
-fx-text-fill: lightgray;
}
.label-callSignChatCatDescriptor {
-fx-font-family: "Arial";
-fx-font-size: 18px;
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, green 0%, lightgreen 100%);
-fx-alignment: center;
}
.text-field {
-fx-prompt-text-fill: gray;
}
.text-field .text {
-fx-fill: linear-gradient(from 0% 0% to 100% 200%, green 0%, lightgreen 100%);
-fx-stroke: green;
-fx-stroke-width: 0.2;
-fx-font-size: 25px;
}
.text-input-MYQRG1 {
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, #f98aff 0%, #f98aff 100%); /*purple*/
}
.titulo{
-fx-font-weight: bold;
-fx-font-size: 18px;
}
.button{
-fx-focus-traversable: false;
}
.button:hover{
-fx-text-fill: white;
}
.separator *.line {
-fx-background-color: #3C3C3C;
-fx-border-style: solid;
-fx-border-width: 1px;
}
.scroll-bar{
-fx-background-color: derive(-fx-base,45%)
}
.button:default {
-fx-base: -fx-accent ;
-fx-font-weight: bold;
}
.button:pressed {
-fx-border-color: #ff0000;
}
.button:hover {
-fx-background-color:linear-gradient(#f0ff35, #a9ff00),
radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.buttonMyQrg1 {
-fx-background-color: linear-gradient(from 0% 0% to 100% 200%, green 0%, lightgreen 100%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.toggle-button:selected {
-fx-background-color:linear-gradient(#f0ff35, #a9ff00),
radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);
-fx-background-radius: 6, 5;
-fx-background-insets: 0, 1;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #395306;
}
.table-view .column-header {
-fx-background-color: linear-gradient(to right, #373838, #373838);
}
.table-view .column-header .text {
-fx-fill: linear-gradient(from 0% 0% to 100% 200%, repeat, green 0%, lightgreen 50%);
-fx-stroke: green;
-fx-stroke-width: 0.2;
}
.table-view{
/*-fx-background-color: derive(-fx-base, 10%);*/
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.table-view .column-header .label{
-fx-alignment: CENTER_LEFT;
-fx-font-weight: none;
}
.table-row-cell > .defaultText-column {
-fx-text-fill: white;
-fx-background-insets: 0 0 1 0px;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.table-row-cell > .messageToMe-column {
-fx-text-fill: lightgreen;
-fx-background-insets: 0 0 1 0px;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlightOwn-column { /*PM own message*/
-fx-background-color: #4674b9;
-fx-background-insets: 0 0 1 0px;
-fx-text-fill: white;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight30-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #33cc33;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight60-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #40bf40;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight90-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #4db34d;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight120-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #59a659;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight180-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #669966;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.messageHighlight300-column { /*PM for 30 sec: works*/
-fx-text-fill: white;
-fx-background-color: #738c73;
-fx-selection-bar-non-focused: derive(-fx-base, 50%);
}
.table-cell-bold {
-fx-font-weight: bold;
}
.table-cell-inAngleAndRange {
-fx-text-fill: lightgreen;
-fx-font-weight: bold;
}
.table-cell-100PercentAP { /*GEHT*/
-fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, #f98aff 0%, #f98aff 100%); /*purple*/;
-fx-font-weight: bold;
}
.table-cell-75PercentAP { /*GEHT*/
-fx-text-fill: #fa6666;
-fx-font-weight: bold;
}
.table-cell-50PercentAP {
-fx-text-fill: #fa9f66;
-fx-font-weight: bold;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More