Overhaul Protocol
This commit is contained in:
parent
d863712c57
commit
6f0de554ae
@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = 'tech.nevets'
|
group = 'tech.nevets'
|
||||||
version = '1.1.0'
|
version = '1.2.0'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -30,9 +30,9 @@ public class ChatWindow extends JPanel {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetConnection() {
|
public void resetConnection(boolean error) {
|
||||||
connected = false;
|
connected = false;
|
||||||
connStatus.setText("Disconnected: Socket Reset");
|
connStatus.setText(error ? "Disconnected: Socket Reset" : "Disconnected");
|
||||||
connectBtn.setText("Connect");
|
connectBtn.setText("Connect");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ public class ChatWindow extends JPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chat.setText("");
|
chat.setText("");
|
||||||
conn.setComponents(chat);
|
conn.setComponents(chat, onlineUsers);
|
||||||
connStatus.setText("Connected");
|
connStatus.setText("Connected");
|
||||||
connectBtn.setText("Disconnect");
|
connectBtn.setText("Disconnect");
|
||||||
connected = true;
|
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() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
|
||||||
connStatus = new JLabel();
|
connStatus = new JLabel();
|
||||||
@ -122,9 +128,11 @@ public class ChatWindow extends JPanel {
|
|||||||
username = new JTextField();
|
username = new JTextField();
|
||||||
connAddr = new JTextField();
|
connAddr = new JTextField();
|
||||||
connectBtn = new JButton();
|
connectBtn = new JButton();
|
||||||
scrollPane = new JScrollPane();
|
chatScrollPane = new JScrollPane();
|
||||||
chat = new JTextArea();
|
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();
|
messageBox = new JTextField();
|
||||||
sendBtn = new JButton();
|
sendBtn = new JButton();
|
||||||
|
|
||||||
@ -168,6 +176,12 @@ public class ChatWindow extends JPanel {
|
|||||||
usernameFocusLost(e);
|
usernameFocusLost(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
username.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
usernameKeyTyped(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
add(username, "cell 0 1,growy");
|
add(username, "cell 0 1,growy");
|
||||||
|
|
||||||
//---- connAddr ----
|
//---- connAddr ----
|
||||||
@ -201,18 +215,29 @@ public class ChatWindow extends JPanel {
|
|||||||
});
|
});
|
||||||
add(connectBtn, "cell 2 1,grow");
|
add(connectBtn, "cell 2 1,grow");
|
||||||
|
|
||||||
//======== scrollPane ========
|
//======== chatScrollPane ========
|
||||||
{
|
{
|
||||||
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
chatScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
scrollPane.setAutoscrolls(true);
|
chatScrollPane.setAutoscrolls(true);
|
||||||
|
|
||||||
//---- chat ----
|
//---- chat ----
|
||||||
chat.setEditable(false);
|
chat.setEditable(false);
|
||||||
chat.setFont(new Font("Tahoma", Font.PLAIN, 11));
|
chat.setFont(new Font("Tahoma", Font.PLAIN, 11));
|
||||||
chat.setLineWrap(true);
|
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 ----
|
||||||
messageBox.addKeyListener(new KeyAdapter() {
|
messageBox.addKeyListener(new KeyAdapter() {
|
||||||
@ -242,8 +267,10 @@ public class ChatWindow extends JPanel {
|
|||||||
private JTextField username;
|
private JTextField username;
|
||||||
private JTextField connAddr;
|
private JTextField connAddr;
|
||||||
private JButton connectBtn;
|
private JButton connectBtn;
|
||||||
private JScrollPane scrollPane;
|
private JScrollPane chatScrollPane;
|
||||||
private JTextArea chat;
|
private JTextArea chat;
|
||||||
|
private JScrollPane onlineScrollPane;
|
||||||
|
private JTextArea onlineUsers;
|
||||||
private JTextField messageBox;
|
private JTextField messageBox;
|
||||||
private JButton sendBtn;
|
private JButton sendBtn;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
||||||
|
@ -28,6 +28,7 @@ new FormModel {
|
|||||||
"text": "Username"
|
"text": "Username"
|
||||||
addEvent( new FormEvent( "java.awt.event.FocusListener", "focusGained", "usernameFocusGained", true ) )
|
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.FocusListener", "focusLost", "usernameFocusLost", true ) )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.KeyListener", "keyTyped", "usernameKeyTyped", true ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 1,growy"
|
"value": "cell 0 1,growy"
|
||||||
} )
|
} )
|
||||||
@ -49,7 +50,7 @@ new FormModel {
|
|||||||
"value": "cell 2 1,grow"
|
"value": "cell 2 1,grow"
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
name: "scrollPane"
|
name: "chatScrollPane"
|
||||||
"horizontalScrollBarPolicy": 31
|
"horizontalScrollBarPolicy": 31
|
||||||
"autoscrolls": true
|
"autoscrolls": true
|
||||||
add( new FormComponent( "javax.swing.JTextArea" ) {
|
add( new FormComponent( "javax.swing.JTextArea" ) {
|
||||||
@ -58,11 +59,22 @@ new FormModel {
|
|||||||
"font": new java.awt.Font( "Tahoma", 0, 11 )
|
"font": new java.awt.Font( "Tahoma", 0, 11 )
|
||||||
"lineWrap": true
|
"lineWrap": true
|
||||||
auxiliary() {
|
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 ) {
|
}, 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" ) {
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
name: "messageBox"
|
name: "messageBox"
|
||||||
|
@ -9,14 +9,32 @@ import java.net.MalformedURLException;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.SecureRandom;
|
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 {
|
public class Connection {
|
||||||
private Socket s;
|
private Socket s;
|
||||||
private InputStream is;
|
private InputStream is;
|
||||||
|
private OutputStream os;
|
||||||
private PrintStream out;
|
private PrintStream out;
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
private JTextArea chat;
|
private JTextArea chat;
|
||||||
|
private List<String> onlineList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
public Connection(String username, String address) throws Exception {
|
public Connection(String username, String address) throws Exception {
|
||||||
String[] addrSplit = address.split(":");
|
String[] addrSplit = address.split(":");
|
||||||
@ -38,33 +56,104 @@ public class Connection {
|
|||||||
s = factory.createSocket(addrSplit[0], Integer.parseInt(addrSplit[1]));
|
s = factory.createSocket(addrSplit[0], Integer.parseInt(addrSplit[1]));
|
||||||
|
|
||||||
is = s.getInputStream();
|
is = s.getInputStream();
|
||||||
OutputStream os = s.getOutputStream();
|
os = s.getOutputStream();
|
||||||
out = new PrintStream(os);
|
out = new PrintStream(os);
|
||||||
this.username = username;
|
this.username = username;
|
||||||
|
|
||||||
|
os.write(0x1);
|
||||||
out.println(username);
|
out.println(username);
|
||||||
|
os.write(0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(String message) {
|
public void sendMessage(String message) {
|
||||||
out.println(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;
|
this.chat = chat;
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
ChatWriter chatWriter = new ChatWriter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
is.transferTo(new ChatWriter());
|
while (!s.isClosed()) {
|
||||||
} catch (IOException ignored) {}
|
byte cmd;
|
||||||
close();
|
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();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void addOnlineUser(String username) {
|
||||||
try {
|
onlineList.add(username);
|
||||||
s.close();
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
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");
|
||||||
}
|
}
|
||||||
ChatWindow.getInstance().resetConnection();
|
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) {
|
||||||
|
Notifier.errorPopup("Connection Reset By Server", e.getMessage());
|
||||||
|
ChatWindow.getInstance().resetConnection(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ChatWindow.getInstance().resetConnection(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChatWriter extends OutputStream {
|
private class ChatWriter extends OutputStream {
|
||||||
@ -73,11 +162,19 @@ public class Connection {
|
|||||||
@Override
|
@Override
|
||||||
public void write(int b) {
|
public void write(int b) {
|
||||||
buf += (char) 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
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
System.out.println(buf);
|
||||||
chat.append(buf);
|
chat.append(buf);
|
||||||
Notifier.messageReceived(Main.getFrame());
|
Notifier.messageReceived(Main.getFrame());
|
||||||
//Notifier.sendNotification(buf.substring(0, buf.indexOf(">") - 1), buf.substring(buf.indexOf(">")));
|
//Notifier.sendNotification(buf.substring(0, buf.indexOf(">") - 1), buf.substring(buf.indexOf(">")));
|
||||||
|
@ -9,7 +9,7 @@ import java.awt.*;
|
|||||||
public class Main {
|
public class Main {
|
||||||
private static final FlatDarkLaf DARK_LAF = new FlatDarkLaf();
|
private static final FlatDarkLaf DARK_LAF = new FlatDarkLaf();
|
||||||
private static final FlatLightLaf LIGHT_LAF = new FlatLightLaf();
|
private static final FlatLightLaf LIGHT_LAF = new FlatLightLaf();
|
||||||
private static TrayIcon trayIcon;
|
//private static TrayIcon trayIcon;
|
||||||
private static JFrame frame;
|
private static JFrame frame;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -44,7 +44,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
SwingUtilities.updateComponentTreeUI(frame);
|
SwingUtilities.updateComponentTreeUI(frame);
|
||||||
} catch (UnsupportedLookAndFeelException e) {
|
} catch (UnsupportedLookAndFeelException e) {
|
||||||
e.printStackTrace();
|
Notifier.errorPopup("Error Setting Look and Feel", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,4 +10,8 @@ public class Notifier {
|
|||||||
Taskbar.getTaskbar().requestWindowUserAttention(frame);
|
Taskbar.getTaskbar().requestWindowUserAttention(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void errorPopup(String title, String message) {
|
||||||
|
JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user