Overhaul Protocol

This commit is contained in:
Steven Tracey 2024-01-16 10:28:00 -06:00
parent d863712c57
commit 6f0de554ae
6 changed files with 170 additions and 30 deletions

View File

@ -5,7 +5,7 @@ plugins {
}
group = 'tech.nevets'
version = '1.1.0'
version = '1.2.0'
repositories {
mavenCentral()

View File

@ -30,9 +30,9 @@ public class ChatWindow extends JPanel {
return instance;
}
public void resetConnection() {
public void resetConnection(boolean error) {
connected = false;
connStatus.setText("Disconnected: Socket Reset");
connStatus.setText(error ? "Disconnected: Socket Reset" : "Disconnected");
connectBtn.setText("Connect");
}
@ -53,7 +53,7 @@ public class ChatWindow extends JPanel {
return;
}
chat.setText("");
conn.setComponents(chat);
conn.setComponents(chat, onlineUsers);
connStatus.setText("Connected");
connectBtn.setText("Disconnect");
connected = true;
@ -115,6 +115,12 @@ public class ChatWindow extends JPanel {
}
}
private void usernameKeyTyped(KeyEvent e) {
if (username.getText().length() > 15) {
e.consume();
}
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
connStatus = new JLabel();
@ -122,9 +128,11 @@ public class ChatWindow extends JPanel {
username = new JTextField();
connAddr = new JTextField();
connectBtn = new JButton();
scrollPane = new JScrollPane();
chatScrollPane = new JScrollPane();
chat = new JTextArea();
new SmartScroller(scrollPane, SmartScroller.VERTICAL, SmartScroller.END);
new SmartScroller(chatScrollPane, SmartScroller.VERTICAL, SmartScroller.END);
onlineScrollPane = new JScrollPane();
onlineUsers = new JTextArea();
messageBox = new JTextField();
sendBtn = new JButton();
@ -168,6 +176,12 @@ public class ChatWindow extends JPanel {
usernameFocusLost(e);
}
});
username.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
usernameKeyTyped(e);
}
});
add(username, "cell 0 1,growy");
//---- connAddr ----
@ -201,18 +215,29 @@ public class ChatWindow extends JPanel {
});
add(connectBtn, "cell 2 1,grow");
//======== scrollPane ========
//======== chatScrollPane ========
{
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setAutoscrolls(true);
chatScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
chatScrollPane.setAutoscrolls(true);
//---- chat ----
chat.setEditable(false);
chat.setFont(new Font("Tahoma", Font.PLAIN, 11));
chat.setLineWrap(true);
scrollPane.setViewportView(chat);
chatScrollPane.setViewportView(chat);
}
add(scrollPane, "cell 0 2 3 1,grow");
add(chatScrollPane, "cell 0 2 2 1,grow");
//======== onlineScrollPane ========
{
onlineScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
onlineScrollPane.setAutoscrolls(true);
//---- onlineUsers ----
onlineUsers.setEditable(false);
onlineScrollPane.setViewportView(onlineUsers);
}
add(onlineScrollPane, "cell 2 2,grow");
//---- messageBox ----
messageBox.addKeyListener(new KeyAdapter() {
@ -242,8 +267,10 @@ public class ChatWindow extends JPanel {
private JTextField username;
private JTextField connAddr;
private JButton connectBtn;
private JScrollPane scrollPane;
private JScrollPane chatScrollPane;
private JTextArea chat;
private JScrollPane onlineScrollPane;
private JTextArea onlineUsers;
private JTextField messageBox;
private JButton sendBtn;
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on

View File

@ -28,6 +28,7 @@ new FormModel {
"text": "Username"
addEvent( new FormEvent( "java.awt.event.FocusListener", "focusGained", "usernameFocusGained", true ) )
addEvent( new FormEvent( "java.awt.event.FocusListener", "focusLost", "usernameFocusLost", true ) )
addEvent( new FormEvent( "java.awt.event.KeyListener", "keyTyped", "usernameKeyTyped", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,growy"
} )
@ -49,7 +50,7 @@ new FormModel {
"value": "cell 2 1,grow"
} )
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane"
name: "chatScrollPane"
"horizontalScrollBarPolicy": 31
"autoscrolls": true
add( new FormComponent( "javax.swing.JTextArea" ) {
@ -58,11 +59,22 @@ new FormModel {
"font": new java.awt.Font( "Tahoma", 0, 11 )
"lineWrap": true
auxiliary() {
"JavaCodeGenerator.postCreateCode": "new SmartScroller(scrollPane, SmartScroller.VERTICAL, SmartScroller.END);"
"JavaCodeGenerator.postCreateCode": "new SmartScroller(chatScrollPane, SmartScroller.VERTICAL, SmartScroller.END);"
}
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1,grow"
"value": "cell 0 2 2 1,grow"
} )
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "onlineScrollPane"
"horizontalScrollBarPolicy": 31
"autoscrolls": true
add( new FormComponent( "javax.swing.JTextArea" ) {
name: "onlineUsers"
"editable": false
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2,grow"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "messageBox"

View File

@ -9,14 +9,32 @@ import java.net.MalformedURLException;
import java.net.Socket;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Commands:
- 0x1: User connect
- 0x2: User disconnect
- 0x3: Message
- 0x4: Online List
- 0xf: End of PDU
Usable: 0-f
*/
public class Connection {
private Socket s;
private InputStream is;
private OutputStream os;
private PrintStream out;
private String username;
private JTextArea chat;
private List<String> onlineList = new ArrayList<>();
public Connection(String username, String address) throws Exception {
String[] addrSplit = address.split(":");
@ -38,33 +56,104 @@ public class Connection {
s = factory.createSocket(addrSplit[0], Integer.parseInt(addrSplit[1]));
is = s.getInputStream();
OutputStream os = s.getOutputStream();
os = s.getOutputStream();
out = new PrintStream(os);
this.username = username;
os.write(0x1);
out.println(username);
os.write(0xf);
}
public void sendMessage(String message) {
try {
os.write(0x3);
out.println(message);
os.write(0xf);
os.flush();
} catch (IOException e) {
Notifier.errorPopup("Error Sending Message", e.getMessage());
}
}
public void setComponents(JTextArea chat) {
public void setComponents(JTextArea chat, JTextArea online) {
this.chat = chat;
new Thread(() -> {
byte[] buf = new byte[1024];
ChatWriter chatWriter = new ChatWriter();
try {
is.transferTo(new ChatWriter());
} catch (IOException ignored) {}
close();
while (!s.isClosed()) {
byte cmd;
try {
cmd = (byte) is.read();
} catch (IOException e) {
ChatWindow.getInstance().resetConnection(false);
break;
}
int i = 0;
for (byte b = (byte) is.read(); b != 0xf && i < 1023; b = (byte) is.read()) {
buf[i] = b;
i++;
}
switch (cmd) {
case 0x1 -> { // User Connect
addOnlineUser(new String(Arrays.copyOfRange(buf, 0, i )));
online.setText(getFormattedOnline());
}
case 0x2 -> { // User Disconnect
removeOnlineUser(new String(Arrays.copyOfRange(buf, 0, i)));
online.setText(getFormattedOnline());
}
case 0x3 -> {
byte[] msg = Arrays.copyOfRange(buf, 0, i);
chatWriter.write(msg); // Send Message
}
case 0x4 -> {
onlineList.clear();
onlineList.add(new String(Arrays.copyOfRange(buf, 0, i + 1)));
online.setText(getFormattedOnline());
}
}
}
} catch (IOException e) {
e.printStackTrace();
Notifier.errorPopup("Error While Closing Connection Thread", e.getMessage());
}
}).start();
}
public void addOnlineUser(String username) {
onlineList.add(username);
}
public void removeOnlineUser(String username) {
onlineList.remove(username);
}
public String getFormattedOnline() {
StringBuilder sb = new StringBuilder();
for (String s : onlineList) {
sb.append(s.trim().replace("\r", "").replace("\n", ""));
sb.append("\n");
}
return sb.substring(0, sb.length());
}
public void close() {
if (!s.isClosed()) {
try {
os.write(0x2);
out.println(username);
os.write(0xf);
s.close();
} catch (IOException e) {
e.printStackTrace();
Notifier.errorPopup("Connection Reset By Server", e.getMessage());
ChatWindow.getInstance().resetConnection(true);
}
ChatWindow.getInstance().resetConnection();
}
ChatWindow.getInstance().resetConnection(false);
}
private class ChatWriter extends OutputStream {
@ -73,11 +162,19 @@ public class Connection {
@Override
public void write(int b) {
buf += (char) b;
if (((char) b) == '\n') this.flush();
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
flush();
}
@Override
public void flush() {
System.out.println(buf);
chat.append(buf);
Notifier.messageReceived(Main.getFrame());
//Notifier.sendNotification(buf.substring(0, buf.indexOf(">") - 1), buf.substring(buf.indexOf(">")));

View File

@ -9,7 +9,7 @@ import java.awt.*;
public class Main {
private static final FlatDarkLaf DARK_LAF = new FlatDarkLaf();
private static final FlatLightLaf LIGHT_LAF = new FlatLightLaf();
private static TrayIcon trayIcon;
//private static TrayIcon trayIcon;
private static JFrame frame;
public static void main(String[] args) {
@ -44,7 +44,7 @@ public class Main {
}
SwingUtilities.updateComponentTreeUI(frame);
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
Notifier.errorPopup("Error Setting Look and Feel", e.getMessage());
}
}

View File

@ -10,4 +10,8 @@ public class Notifier {
Taskbar.getTaskbar().requestWindowUserAttention(frame);
}
}
public static void errorPopup(String title, String message) {
JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
}
}