Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d9faa93f8 | ||
|
|
e5eb4f3f9c | ||
|
|
581a924afc | ||
|
|
7a699cd280 | ||
|
|
88b75ad75f | ||
|
|
d551324e8b | ||
|
|
a628490fcb | ||
|
|
395363e4bd | ||
|
|
12497594e4 | ||
|
|
6a597092fe | ||
|
|
ffd474e7ff | ||
|
|
4d39648ee7 | ||
|
|
095af14463 | ||
|
|
d0083e8069 | ||
|
|
dda324228f | ||
|
|
840183ee9f | ||
|
|
eb3ce132cd | ||
|
|
d1dc427185 |
No files matched your search
+3
-9
@@ -1,9 +1,3 @@
|
|||||||
/pitiupi/build/
|
build/
|
||||||
/pitiupi/dist/
|
dist/
|
||||||
/pitiupi.chat/build/
|
*.class
|
||||||
/pitiupi.chat/dist/
|
|
||||||
/pitiupi.chat/nbproject/private/
|
|
||||||
/pitiupi.screenCast/build/
|
|
||||||
/pitiupi.screenCast/dist/
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="pitiupi">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/pitiupi.screenCast/dist/lib/pitiupi.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="pitiupi.chat">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/pitiupi.chat/dist/pitiupi.chat.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="pitiupi.screenCast">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/pitiupi.screenCast/dist/pitiupi.screenCast.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="plugins">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/pitiupi/plugins/pitiupi.screenCast.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/pitiupi/plugins/pitiupi.chat.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
Generated
+4
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-27" project-jdk-type="JavaSDK" />
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/pitiupi.iml" filepath="$PROJECT_DIR$/.idea/pitiupi.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
# pitiupi
|
# pitiupi
|
||||||
|
|
||||||
Ferramenta p2p para práticas em rede
|
Este repositório tem 4 projetos Java que são independentes:
|
||||||
|
|
||||||
Este repositório tem 3 projetos Java que são independentes:
|
### Sistema:
|
||||||
- A ferramenta pitiupi (P2P)
|
- A ferramenta pitiupi (P2P)
|
||||||
|
|
||||||
|
### Plugins:
|
||||||
- Um plugin de Chat
|
- Um plugin de Chat
|
||||||
|
- Um plugin de Chat multiprotocolo (TCP/UDP)
|
||||||
- Um plugin de ScreenCast
|
- Um plugin de ScreenCast
|
||||||
|
|
||||||
Cada um destes projetos deve ser compilado individualmente. Para isso, use a ferramenta ant no diretório do projeto.
|
Cada um destes projetos deve ser compilado individualmente. Para isso, use a ferramenta ant no diretório do projeto.
|
||||||
@@ -21,9 +24,26 @@ Para criar links simbólicos no Linux, use o comando:
|
|||||||
```
|
```
|
||||||
cd pitiupi/plugins
|
cd pitiupi/plugins
|
||||||
ln -s ../../pitiupi.chat/dist/*.jar .
|
ln -s ../../pitiupi.chat/dist/*.jar .
|
||||||
|
ln -s ../../pitiupi.mpChat/dist/*.jar .
|
||||||
ln -s ../../pitiupi.screenCast/dist/*.jar .
|
ln -s ../../pitiupi.screenCast/dist/*.jar .
|
||||||
```
|
```
|
||||||
Isso deve resolver!
|
Isso deve resolver!
|
||||||
|
|
||||||
Para criar um novo plugin:
|
## Como um plugin conversa com o pitiupi
|
||||||
|
|
||||||
|
Um plugin nunca recebe acesso direto às classes internas do núcleo (ConnectionManager, GuiManager). Em vez disso, recebe uma facade, a classe Pitiupi, que expõe só o que um plugin precisa: enviar mensagem (multicast, unicast ou tcp), abrir conexão tcp privada, ler nome de usuário e porta, criar menu.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public abstract void createPlugin(Pitiupi pitiupi);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Para criar um novo plugin
|
||||||
|
|
||||||
|
1. Implemente `pitiupi.models.Plugin`, incluindo `createPlugin(Pitiupi pitiupi)`
|
||||||
|
2. Registre a classe em `src/META-INF/services/pitiupi.models.Plugin`, com o nome completo da classe numa linha
|
||||||
|
3. Compile com `ant jar`
|
||||||
|
4. Linke o `.jar` em `pitiupi/plugins`
|
||||||
|
|
||||||
|
Use `pitiupi.chat` como referência — é o exemplo mais simples e completo.
|
||||||
|
|
||||||
|
Plugins que ainda não foram atualizados para a Pitiupi (como uma versão mais antiga do screenCast) não compilam contra o núcleo atual e precisam de migração antes de serem usados.
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#Fri, 02 Oct 2026 20:11:21 -0300
|
|
||||||
|
|
||||||
|
|
||||||
C\:\\Users\\extre\\OneDrive\\Documentos\\Faculdade\\2026_02\\Monitoria\\Pitiupi\\pitiupi.chat=
|
|
||||||
|
|
||||||
C\:\\Users\\extre\\OneDrive\\Documentos\\Faculdade\\2026_02\\Monitoria\\Pitiupi\\pitiupi=
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
pitiupi.chat.plugin.ChatPlugin
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -47,8 +47,8 @@ javac.modulepath=
|
|||||||
javac.processormodulepath=
|
javac.processormodulepath=
|
||||||
javac.processorpath=\
|
javac.processorpath=\
|
||||||
${javac.classpath}
|
${javac.classpath}
|
||||||
javac.source=25
|
javac.source=17
|
||||||
javac.target=25
|
javac.target=17
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}
|
${build.classes.dir}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ package pitiupi.chat.GUI;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import pitiupi.chat.net.ChatMessage;
|
import pitiupi.chat.net.ChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.plugin.Pitiupi;
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @author tony
|
||||||
* @author flavio
|
* @author flavio
|
||||||
*/
|
*/
|
||||||
public class ChatWindow extends JDialog {
|
public class ChatWindow extends JDialog {
|
||||||
@@ -28,13 +28,12 @@ public class ChatWindow extends JDialog {
|
|||||||
private JSplitPane jSplitPane1;
|
private JSplitPane jSplitPane1;
|
||||||
private JTextArea jTextArea1;
|
private JTextArea jTextArea1;
|
||||||
|
|
||||||
private final ConnectionManager connectionManager;
|
private final Pitiupi pitiupi;
|
||||||
|
|
||||||
public ChatWindow(ConnectionManager connectionManager) {
|
|
||||||
this.connectionManager = connectionManager;
|
|
||||||
initComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public ChatWindow(Pitiupi pitiupi) {
|
||||||
|
this.pitiupi = pitiupi;
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@@ -93,13 +92,13 @@ public class ChatWindow extends JDialog {
|
|||||||
if (jTextArea1.getText().trim().isEmpty()) {
|
if (jTextArea1.getText().trim().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ChatMessage message = new ChatMessage(connectionManager.getUserName(), jTextArea1.getText());
|
ChatMessage message = new ChatMessage(pitiupi.getUserName(), jTextArea1.getText());
|
||||||
this.sendChatMessage(message);
|
this.sendChatMessage(message);
|
||||||
jTextArea1.setText("");
|
jTextArea1.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendChatMessage(Message message) {
|
public void sendChatMessage(Message message) {
|
||||||
connectionManager.sendUdpMulticast(message);
|
pitiupi.sendUdpMulticast(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveChatMessage(ChatMessage message) {
|
public void receiveChatMessage(ChatMessage message) {
|
||||||
|
|||||||
@@ -8,29 +8,29 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
import pitiupi.chat.GUI.ChatMenu;
|
import pitiupi.chat.GUI.ChatMenu;
|
||||||
import pitiupi.chat.GUI.ChatWindow;
|
import pitiupi.chat.GUI.ChatWindow;
|
||||||
import pitiupi.chat.net.ChatMessage;
|
import pitiupi.chat.net.ChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Menus.MenuCategory;
|
import pitiupi.models.Menus.MenuCategory;
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*@author tony
|
||||||
* @author flavio
|
* @author flavio
|
||||||
*/
|
*/
|
||||||
public class ChatPlugin extends Plugin {
|
public class ChatPlugin extends Plugin {
|
||||||
|
|
||||||
private ChatWindow chatWindow;
|
private ChatWindow chatWindow;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) {
|
public void createPlugin(Pitiupi pitiupi) {
|
||||||
this.chatWindow = new ChatWindow(connectionManager);
|
this.chatWindow = new ChatWindow(pitiupi);
|
||||||
guiManager.createMenu(MenuCategory.Social, new ChatMenu(chatWindow));
|
pitiupi.createMenu(MenuCategory.Social, new ChatMenu(chatWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Class<? extends Message>> getMessages() {
|
public List<Class<? extends Message>> getMessages() {
|
||||||
return List.of(ChatMessage.class);
|
return List.of(ChatMessage.class);
|
||||||
|
|||||||
Generated
+5
@@ -0,0 +1,5 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
Generated
+5
@@ -0,0 +1,5 @@
|
|||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="openjdk-26" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/pitiupi.mpChat.iml" filepath="$PROJECT_DIR$/pitiupi.mpChat.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
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.
@@ -1,40 +0,0 @@
|
|||||||
package GUI;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.MenuCategory;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastSubMenu;
|
|
||||||
import plugin.MultiProtocolChat;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
public class ChatMenu extends MulticastSubMenu {
|
|
||||||
private final MultiProtocolChat multiProtocolChat;
|
|
||||||
|
|
||||||
public ChatMenu(MultiProtocolChat multiProtocolChat) {
|
|
||||||
this.multiProtocolChat = multiProtocolChat;
|
|
||||||
this.setText("MP-Chat");
|
|
||||||
|
|
||||||
JMenuItem startPrivateChat = new JMenuItem("start Private Chat");
|
|
||||||
startPrivateChat.addActionListener(e -> showPrivateChatDialog());
|
|
||||||
this.add(startPrivateChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void newMenuItem(JMenuItem newMenuItem, ChatWindow chatWindow) {
|
|
||||||
newMenuItem.addActionListener(e -> chatWindow.setVisible(true));
|
|
||||||
|
|
||||||
this.add(newMenuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeMenuItem(JMenuItem removeMenuItem) {
|
|
||||||
this.remove(removeMenuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showPrivateChatDialog() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "MP-Chat";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package GUI;
|
|
||||||
|
|
||||||
import net.MpChatMessage;
|
|
||||||
import pitiupi.control.ConnectionManager;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
public abstract class ChatWindow extends JFrame {
|
|
||||||
|
|
||||||
protected final ConnectionManager connectionManager;
|
|
||||||
|
|
||||||
private JTextArea receivedMessagesArea;
|
|
||||||
protected JTextField messageField;
|
|
||||||
|
|
||||||
public ChatWindow(ConnectionManager connectionManager) {
|
|
||||||
this.connectionManager = connectionManager;
|
|
||||||
initComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
setTitle("Socket Test");
|
|
||||||
setSize(700, 500);
|
|
||||||
setLocationRelativeTo(null);
|
|
||||||
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
|
||||||
|
|
||||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
|
||||||
|
|
||||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
||||||
|
|
||||||
initReceivedMessagesPanel(mainPanel);
|
|
||||||
initBottomPanel(mainPanel);
|
|
||||||
|
|
||||||
setContentPane(mainPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initReceivedMessagesPanel(JPanel mainPanel) {
|
|
||||||
receivedMessagesArea = new JTextArea();
|
|
||||||
receivedMessagesArea.setEditable(false);
|
|
||||||
receivedMessagesArea.setLineWrap(true);
|
|
||||||
receivedMessagesArea.setWrapStyleWord(true);
|
|
||||||
|
|
||||||
JScrollPane messagesScrollPane = new JScrollPane(receivedMessagesArea);
|
|
||||||
|
|
||||||
messagesScrollPane.setBorder(BorderFactory.createTitledBorder("Mensagens recebidas"));
|
|
||||||
|
|
||||||
mainPanel.add(messagesScrollPane, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initBottomPanel(JPanel mainPanel) {
|
|
||||||
messageField = new JTextField();
|
|
||||||
|
|
||||||
JPanel bottomPanel = new JPanel(new BorderLayout(10, 10));
|
|
||||||
|
|
||||||
bottomPanel.add(messageField, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
initButtons(bottomPanel);
|
|
||||||
|
|
||||||
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void initButtons(JPanel bottomPanel);
|
|
||||||
|
|
||||||
protected MpChatMessage createMessage(String tipoMensagem) {
|
|
||||||
try {
|
|
||||||
String nome = connectionManager.getUserName();
|
|
||||||
String ip = InetAddress.getLocalHost().getHostAddress();
|
|
||||||
String message = messageField.getText();
|
|
||||||
|
|
||||||
return new MpChatMessage(nome, ip, tipoMensagem, message);
|
|
||||||
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receiveMessage(MpChatMessage msg) {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
String mensagem = String.format(
|
|
||||||
"[%s] %s (%s): %s%n",
|
|
||||||
msg.getTipoMensagem(),
|
|
||||||
msg.getNome(),
|
|
||||||
msg.getIp(),
|
|
||||||
msg.getMessage()
|
|
||||||
);
|
|
||||||
|
|
||||||
receivedMessagesArea.append(mensagem);
|
|
||||||
|
|
||||||
receivedMessagesArea.setCaretPosition(receivedMessagesArea.getDocument().getLength());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-3
@@ -2,10 +2,10 @@ package GUI;
|
|||||||
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu;
|
import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu;
|
||||||
|
|
||||||
public class PublicChatMenu extends MulticastActionMenu {
|
public class MulticastMpChatMenu extends MulticastActionMenu {
|
||||||
PublicChatWindow publicChatWindow;
|
PublicChatWindow publicChatWindow;
|
||||||
|
|
||||||
PublicChatMenu(PublicChatWindow publicChatWindow) {
|
public MulticastMpChatMenu(PublicChatWindow publicChatWindow) {
|
||||||
this.publicChatWindow = publicChatWindow;
|
this.publicChatWindow = publicChatWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,8 +14,9 @@ public class PublicChatMenu extends MulticastActionMenu {
|
|||||||
publicChatWindow.setVisible(true);
|
publicChatWindow.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return "";
|
return "MP-Chat";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package GUI;
|
|
||||||
|
|
||||||
import control.ChatController;
|
|
||||||
import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu;
|
|
||||||
import pitiupi.models.User;
|
|
||||||
import plugin.MultiProtocolChat;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
|
|
||||||
public class PrivateChatMenu extends UnicastActionMenu {
|
|
||||||
PrivateChatWindow privateChatWindow;
|
|
||||||
private final MultiProtocolChat multiProtocolChat;
|
|
||||||
private final ChatController chatController;
|
|
||||||
|
|
||||||
public PrivateChatMenu(PrivateChatWindow PrivateChatWindow, MultiProtocolChat multiProtocolChat, ChatController chatController) {
|
|
||||||
this.privateChatWindow = PrivateChatWindow;
|
|
||||||
this.multiProtocolChat = multiProtocolChat;
|
|
||||||
this.chatController = chatController;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(User user) {
|
|
||||||
if (multiProtocolChat.openConnection(user.getAddress())
|
|
||||||
else errorLabel.setVisible(true);
|
|
||||||
|
|
||||||
dialog.setContentPane(contentPanel);
|
|
||||||
dialog.pack();
|
|
||||||
dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(privateChatWindow));
|
|
||||||
dialog.setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "start Private Chat";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +1,122 @@
|
|||||||
package GUI;
|
package GUI;
|
||||||
|
|
||||||
import net.MpChatMessage;
|
import net.MpChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
|
||||||
import pitiupi.net.tcp.TcpConnection;
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class PrivateChatWindow extends ChatWindow {
|
public class PrivateChatWindow extends JFrame {
|
||||||
|
|
||||||
|
private final Pitiupi pitiupi;
|
||||||
private final TcpConnection connection;
|
private final TcpConnection connection;
|
||||||
|
|
||||||
public PrivateChatWindow(ConnectionManager ConnectionManager, TcpConnection connection) {
|
private final JTextArea receivedMessagesArea;
|
||||||
super(ConnectionManager);
|
private final JTextField messageField;
|
||||||
this.connection = connection;
|
|
||||||
}
|
public PrivateChatWindow(
|
||||||
|
Pitiupi pitiupi,
|
||||||
|
TcpConnection connection
|
||||||
|
) {
|
||||||
|
this.pitiupi = pitiupi;
|
||||||
|
this.connection = connection;
|
||||||
|
|
||||||
|
setTitle("Chat privado");
|
||||||
|
setSize(700, 500);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||||
|
|
||||||
|
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||||
|
mainPanel.setBorder(
|
||||||
|
BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
||||||
|
);
|
||||||
|
|
||||||
|
receivedMessagesArea = new JTextArea();
|
||||||
|
receivedMessagesArea.setEditable(false);
|
||||||
|
receivedMessagesArea.setLineWrap(true);
|
||||||
|
receivedMessagesArea.setWrapStyleWord(true);
|
||||||
|
|
||||||
|
JScrollPane messagesScrollPane =
|
||||||
|
new JScrollPane(receivedMessagesArea);
|
||||||
|
|
||||||
|
messagesScrollPane.setBorder(
|
||||||
|
BorderFactory.createTitledBorder("Mensagens")
|
||||||
|
);
|
||||||
|
|
||||||
|
mainPanel.add(
|
||||||
|
messagesScrollPane,
|
||||||
|
BorderLayout.CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
JPanel bottomPanel = new JPanel(
|
||||||
|
new BorderLayout(10, 10)
|
||||||
|
);
|
||||||
|
|
||||||
|
messageField = new JTextField();
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initButtons(JPanel bottomPanel) {
|
|
||||||
JButton tcpButton = new JButton("TCP");
|
JButton tcpButton = new JButton("TCP");
|
||||||
|
|
||||||
tcpButton.addActionListener(e -> sendTCP());
|
tcpButton.addActionListener(e -> sendTCP());
|
||||||
|
|
||||||
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
|
bottomPanel.add(
|
||||||
|
messageField,
|
||||||
|
BorderLayout.CENTER
|
||||||
|
);
|
||||||
|
|
||||||
buttonsPanel.add(tcpButton);
|
bottomPanel.add(
|
||||||
|
tcpButton,
|
||||||
|
BorderLayout.EAST
|
||||||
|
);
|
||||||
|
|
||||||
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
|
mainPanel.add(
|
||||||
|
bottomPanel,
|
||||||
|
BorderLayout.SOUTH
|
||||||
|
);
|
||||||
|
|
||||||
|
setContentPane(mainPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendTCP() {
|
private void sendTCP() {
|
||||||
try {
|
try {
|
||||||
MpChatMessage msg = createMessage("TCP Private");
|
String nome = pitiupi.getUserName();
|
||||||
connection.send(msg.toByteArray());
|
|
||||||
|
MpChatMessage message = new MpChatMessage(
|
||||||
|
nome,
|
||||||
|
InetAddress.getLocalHost().getHostAddress(),
|
||||||
|
"TCP Private",
|
||||||
|
messageField.getText()
|
||||||
|
);
|
||||||
|
|
||||||
|
connection.send(message.toByteArray());
|
||||||
|
receiveMessage(message);
|
||||||
|
|
||||||
|
messageField.setText("");
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.getLogger(PrivateChatWindow.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(
|
||||||
|
PrivateChatWindow.class.getName()
|
||||||
|
).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void receiveMessage(MpChatMessage message) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
String texto = String.format(
|
||||||
|
"[%s] %s (%s): %s%n",
|
||||||
|
message.getTipoMensagem(),
|
||||||
|
message.getNome(),
|
||||||
|
message.getIp(),
|
||||||
|
message.getMessage()
|
||||||
|
);
|
||||||
|
|
||||||
|
receivedMessagesArea.append(texto);
|
||||||
|
|
||||||
|
receivedMessagesArea.setCaretPosition(
|
||||||
|
receivedMessagesArea.getDocument().getLength()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,36 +2,95 @@ package GUI;
|
|||||||
|
|
||||||
import net.MpChatMessage;
|
import net.MpChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
import javax.swing.text.SimpleAttributeSet;
|
||||||
|
import javax.swing.text.StyleConstants;
|
||||||
|
import javax.swing.text.StyledDocument;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class PublicChatWindow extends ChatWindow {
|
public class PublicChatWindow extends JFrame {
|
||||||
|
private final Pitiupi pitiupi;
|
||||||
|
|
||||||
|
private JTextPane receivedMessagesArea;
|
||||||
|
private JTextField messageField;
|
||||||
private JTextField ipField;
|
private JTextField ipField;
|
||||||
|
|
||||||
public PublicChatWindow(ConnectionManager connectionManager) {
|
public PublicChatWindow(Pitiupi pitiupi) {
|
||||||
super(connectionManager);
|
this.pitiupi = pitiupi;
|
||||||
|
|
||||||
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void initComponents() {
|
||||||
protected void initButtons(JPanel bottomPanel) {
|
setTitle("Public Chat");
|
||||||
|
setSize(700, 500);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||||
|
|
||||||
|
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||||
|
|
||||||
|
mainPanel.setBorder(
|
||||||
|
BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
||||||
|
);
|
||||||
|
|
||||||
|
initReceivedMessagesPanel(mainPanel);
|
||||||
|
initBottomPanel(mainPanel);
|
||||||
|
|
||||||
|
setContentPane(mainPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initReceivedMessagesPanel(JPanel mainPanel) {
|
||||||
|
receivedMessagesArea = new JTextPane();
|
||||||
|
|
||||||
|
receivedMessagesArea.setEditable(false);
|
||||||
|
|
||||||
|
JScrollPane messagesScrollPane = new JScrollPane(receivedMessagesArea);
|
||||||
|
|
||||||
|
messagesScrollPane.setBorder(
|
||||||
|
BorderFactory.createTitledBorder("Mensagens recebidas")
|
||||||
|
);
|
||||||
|
|
||||||
|
mainPanel.add(messagesScrollPane, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initBottomPanel(JPanel mainPanel) {
|
||||||
|
messageField = new JTextField();
|
||||||
|
|
||||||
|
JPanel bottomPanel = new JPanel(
|
||||||
|
new BorderLayout(10, 10)
|
||||||
|
);
|
||||||
|
|
||||||
|
bottomPanel.add(messageField, BorderLayout.CENTER);
|
||||||
|
|
||||||
initIpField(bottomPanel);
|
initIpField(bottomPanel);
|
||||||
initCommunicationButtons(bottomPanel);
|
initCommunicationButtons(bottomPanel);
|
||||||
|
|
||||||
|
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initIpField(JPanel bottomPanel) {
|
private void initIpField(JPanel bottomPanel) {
|
||||||
ipField = new JTextField();
|
ipField = new JTextField();
|
||||||
ipField.setPreferredSize(new Dimension(130, 30));
|
ipField.setPreferredSize(new Dimension(130, 30));
|
||||||
|
|
||||||
JPanel ipPanel = new JPanel(new BorderLayout(5, 5));
|
JPanel ipPanel = new JPanel(
|
||||||
|
new BorderLayout(5, 5)
|
||||||
|
);
|
||||||
|
|
||||||
ipPanel.add(new JLabel("IP destino:"), BorderLayout.WEST);
|
ipPanel.add(
|
||||||
|
new JLabel("IP destino:"),
|
||||||
|
BorderLayout.WEST
|
||||||
|
);
|
||||||
|
|
||||||
ipPanel.add(ipField, BorderLayout.CENTER);
|
ipPanel.add(
|
||||||
|
ipField,
|
||||||
|
BorderLayout.CENTER
|
||||||
|
);
|
||||||
|
|
||||||
bottomPanel.add(ipPanel, BorderLayout.WEST);
|
bottomPanel.add(ipPanel, BorderLayout.WEST);
|
||||||
}
|
}
|
||||||
@@ -45,13 +104,71 @@ public class PublicChatWindow extends ChatWindow {
|
|||||||
udpButton.addActionListener(e -> sendUDP());
|
udpButton.addActionListener(e -> sendUDP());
|
||||||
multicastButton.addActionListener(e -> sendMulticast());
|
multicastButton.addActionListener(e -> sendMulticast());
|
||||||
|
|
||||||
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
|
JPanel buttonsPanel = new JPanel(
|
||||||
|
new FlowLayout(FlowLayout.RIGHT, 5, 0)
|
||||||
|
);
|
||||||
|
|
||||||
buttonsPanel.add(tcpButton);
|
buttonsPanel.add(tcpButton);
|
||||||
buttonsPanel.add(udpButton);
|
buttonsPanel.add(udpButton);
|
||||||
buttonsPanel.add(multicastButton);
|
buttonsPanel.add(multicastButton);
|
||||||
|
|
||||||
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
|
bottomPanel.add(
|
||||||
|
buttonsPanel,
|
||||||
|
BorderLayout.EAST
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MpChatMessage createMessage(String tipoMensagem) {
|
||||||
|
try {
|
||||||
|
String nome = pitiupi.getUserName();
|
||||||
|
String ip = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
String message = messageField.getText();
|
||||||
|
|
||||||
|
return new MpChatMessage(
|
||||||
|
nome,
|
||||||
|
ip,
|
||||||
|
tipoMensagem,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveMessage(MpChatMessage msg) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
String mensagem = String.format(
|
||||||
|
"[%s] %s (%s): %s%n",
|
||||||
|
msg.getTipoMensagem(),
|
||||||
|
msg.getNome(),
|
||||||
|
msg.getIp(),
|
||||||
|
msg.getMessage()
|
||||||
|
);
|
||||||
|
|
||||||
|
StyledDocument document = receivedMessagesArea.getStyledDocument();
|
||||||
|
|
||||||
|
SimpleAttributeSet attributes = new SimpleAttributeSet();
|
||||||
|
|
||||||
|
if (msg.getTipoMensagem().equals("TCP Unicast") || msg.getTipoMensagem().equals("UDP Unicast")) {
|
||||||
|
StyleConstants.setForeground(attributes, new Color(128, 0, 128));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
document.insertString(
|
||||||
|
document.getLength(),
|
||||||
|
mensagem,
|
||||||
|
attributes
|
||||||
|
);
|
||||||
|
|
||||||
|
receivedMessagesArea.setCaretPosition(
|
||||||
|
document.getLength()
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (BadLocationException ex) {
|
||||||
|
Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendTCP() {
|
private void sendTCP() {
|
||||||
@@ -60,10 +177,13 @@ public class PublicChatWindow extends ChatWindow {
|
|||||||
|
|
||||||
InetAddress ip = InetAddress.getByName(ipField.getText());
|
InetAddress ip = InetAddress.getByName(ipField.getText());
|
||||||
|
|
||||||
connectionManager.sendTcp(msg, ip);
|
pitiupi.sendTcp(msg, ip);
|
||||||
|
receiveMessage(msg);
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(
|
||||||
|
PublicChatWindow.class.getName()
|
||||||
|
).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,10 +193,13 @@ public class PublicChatWindow extends ChatWindow {
|
|||||||
|
|
||||||
InetAddress ip = InetAddress.getByName(ipField.getText());
|
InetAddress ip = InetAddress.getByName(ipField.getText());
|
||||||
|
|
||||||
connectionManager.sendUdpUnicast(msg, ip);
|
pitiupi.sendUdpUnicast(msg, ip);
|
||||||
|
receiveMessage(msg);
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(
|
||||||
|
PublicChatWindow.class.getName()
|
||||||
|
).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,10 +207,12 @@ public class PublicChatWindow extends ChatWindow {
|
|||||||
try {
|
try {
|
||||||
MpChatMessage msg = createMessage("UDP Multicast");
|
MpChatMessage msg = createMessage("UDP Multicast");
|
||||||
|
|
||||||
connectionManager.sendUdpMulticast(msg);
|
pitiupi.sendUdpMulticast(msg);
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(
|
||||||
|
PublicChatWindow.class.getName()
|
||||||
|
).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package GUI;
|
||||||
|
|
||||||
|
import control.PrivateChatController;
|
||||||
|
import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu;
|
||||||
|
import pitiupi.models.User;
|
||||||
|
|
||||||
|
public class UnicastMpChatMenu extends UnicastActionMenu {
|
||||||
|
|
||||||
|
private final PrivateChatController controller;
|
||||||
|
|
||||||
|
public UnicastMpChatMenu(
|
||||||
|
PrivateChatController controller
|
||||||
|
) {
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(User user) {
|
||||||
|
controller.openChat(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return "Start Private Chat";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package control;
|
|
||||||
|
|
||||||
import GUI.ChatMenu;
|
|
||||||
import GUI.ChatWindow;
|
|
||||||
import GUI.PrivateChatWindow;
|
|
||||||
import GUI.PublicChatWindow;
|
|
||||||
import net.MpChatMessage;
|
|
||||||
import pitiupi.control.ConnectionManager;
|
|
||||||
import pitiupi.control.PeerListener;
|
|
||||||
import pitiupi.models.User;
|
|
||||||
import pitiupi.net.tcp.TcpConnection;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ChatController implements PeerListener {
|
|
||||||
ConnectionManager connectionManager;
|
|
||||||
ChatMenu chatMenu;
|
|
||||||
|
|
||||||
PublicChatWindow publicChatWindow;
|
|
||||||
|
|
||||||
private final HashMap<TcpConnection, ChatWindow> chatWindows;
|
|
||||||
|
|
||||||
public ChatController(ConnectionManager connectionManager, ChatMenu chatMenu) {
|
|
||||||
this.connectionManager = connectionManager;
|
|
||||||
publicChatWindow = new PublicChatWindow(connectionManager);
|
|
||||||
|
|
||||||
chatMenus = new HashMap<>();
|
|
||||||
chatWindows = new HashMap<>();
|
|
||||||
|
|
||||||
this.chatMenu = chatMenu;
|
|
||||||
|
|
||||||
this.chatMenu.newMenuItem(new JMenuItem("Show global chat"), publicChatWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addChatWindow(TcpConnection tcpConnection) {
|
|
||||||
if (chatWindows.containsKey(tcpConnection)) return;
|
|
||||||
|
|
||||||
PrivateChatWindow newChat = new PrivateChatWindow(connectionManager, tcpConnection);
|
|
||||||
chatWindows.put(tcpConnection, newChat);
|
|
||||||
JMenuItem newMenuItem = new JMenuItem();
|
|
||||||
chatMenus.put(tcpConnection, newMenuItem);
|
|
||||||
newMenuItem.setText(tcpConnection.getAddress().toString());
|
|
||||||
chatMenu.newMenuItem(newMenuItem, newChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeChatWindow(TcpConnection tcpConnection) {
|
|
||||||
ChatWindow removedWindow = chatWindows.remove(tcpConnection);
|
|
||||||
JMenuItem removedMenu = chatMenus.remove(tcpConnection);
|
|
||||||
|
|
||||||
chatMenu.removeMenuItem(removedMenu);
|
|
||||||
removedWindow.setVisible(false);
|
|
||||||
removedWindow.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receivePublic(MpChatMessage message) {
|
|
||||||
publicChatWindow.receiveMessage(message);
|
|
||||||
}
|
|
||||||
public void receivePrivate(TcpConnection tcpConnection, MpChatMessage message) {
|
|
||||||
chatWindows.get(tcpConnection).receiveMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openChatWindow(InetAddress address) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPeersChanged(List<User> list) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package control;
|
||||||
|
|
||||||
|
import GUI.PrivateChatWindow;
|
||||||
|
import net.MpChatMessage;
|
||||||
|
import pitiupi.models.User;
|
||||||
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
|
import plugin.MultiProtocolChat;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class PrivateChatController {
|
||||||
|
|
||||||
|
private final Pitiupi pitiupi;
|
||||||
|
private final MultiProtocolChat multiProtocolChat;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relaciona o endereço do usuário à janela de chat.
|
||||||
|
*/
|
||||||
|
private final Map<String, PrivateChatWindow> windows;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Endereços para os quais uma conexão já foi solicitada,
|
||||||
|
* mas ainda não chegou.
|
||||||
|
*/
|
||||||
|
private final Set<String> pendingConnections;
|
||||||
|
|
||||||
|
public PrivateChatController(
|
||||||
|
Pitiupi pitiupi,
|
||||||
|
MultiProtocolChat multiProtocolChat
|
||||||
|
) {
|
||||||
|
this.pitiupi = pitiupi;
|
||||||
|
this.multiProtocolChat = multiProtocolChat;
|
||||||
|
|
||||||
|
this.windows = new HashMap<>();
|
||||||
|
this.pendingConnections = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openChat(User user) {
|
||||||
|
String address = user.getAddress().getHostAddress();
|
||||||
|
|
||||||
|
PrivateChatWindow window = windows.get(address);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Já existe uma janela para esse usuário.
|
||||||
|
*/
|
||||||
|
if (window != null) {
|
||||||
|
window.setVisible(true);
|
||||||
|
window.toFront();
|
||||||
|
window.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Já estamos esperando uma conexão para esse usuário.
|
||||||
|
*/
|
||||||
|
if (pendingConnections.contains(address)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ainda não existe conexão.
|
||||||
|
*/
|
||||||
|
pendingConnections.add(address);
|
||||||
|
|
||||||
|
multiProtocolChat.openConnection(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveMessage(TcpConnection connection, MpChatMessage message) {
|
||||||
|
String address = connection.getAddress().toString();
|
||||||
|
|
||||||
|
PrivateChatWindow window = windows.get(address);
|
||||||
|
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.receiveMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deve ser chamado quando uma nova conexão privada chegar.
|
||||||
|
*/
|
||||||
|
public void connectionReceived(TcpConnection connection) {
|
||||||
|
String address = connection.getAddress().toString();
|
||||||
|
|
||||||
|
pendingConnections.remove(address);
|
||||||
|
|
||||||
|
PrivateChatWindow window = new PrivateChatWindow(
|
||||||
|
pitiupi,
|
||||||
|
connection
|
||||||
|
);
|
||||||
|
|
||||||
|
windows.put(address, window);
|
||||||
|
|
||||||
|
window.setVisible(true);
|
||||||
|
window.toFront();
|
||||||
|
window.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fecha a janela e remove o relacionamento.
|
||||||
|
*/
|
||||||
|
public void closeChat(TcpConnection connection) {
|
||||||
|
String address = connection.getAddress().toString();
|
||||||
|
|
||||||
|
PrivateChatWindow window = windows.remove(address);
|
||||||
|
|
||||||
|
if (window != null) {
|
||||||
|
window.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,29 @@
|
|||||||
package plugin;
|
package plugin;
|
||||||
|
|
||||||
import GUI.ChatMenu;
|
import GUI.MulticastMpChatMenu;
|
||||||
import control.ChatController;
|
import GUI.PrivateChatWindow;
|
||||||
|
import GUI.PublicChatWindow;
|
||||||
|
import GUI.UnicastMpChatMenu;
|
||||||
|
import control.PrivateChatController;
|
||||||
import net.MpChatMessage;
|
import net.MpChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.models.Menus.MenuCategory;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.net.tcp.TcpConnection;
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MultiProtocolChat extends Plugin {
|
public class MultiProtocolChat extends Plugin {
|
||||||
ChatController chatController;
|
Pitiupi pitiupi;
|
||||||
ConnectionManager connectionManager;
|
|
||||||
GuiManager guiManager;
|
PrivateChatController privateChatController;
|
||||||
|
PublicChatWindow publicChatWindow;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -41,30 +46,37 @@ public class MultiProtocolChat extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) {
|
public void createPlugin(Pitiupi pitiupi) {
|
||||||
this.connectionManager = connectionManager;
|
this.pitiupi = pitiupi;
|
||||||
this.guiManager = guiManager;
|
|
||||||
|
|
||||||
ChatMenu chatMenu = new ChatMenu(this);
|
privateChatController = new PrivateChatController(pitiupi, this);
|
||||||
chatController = new ChatController(connectionManager, chatMenu);
|
|
||||||
guiManager.addMulticastMenu(chatMenu);
|
publicChatWindow = new PublicChatWindow(pitiupi);
|
||||||
|
|
||||||
|
MulticastMpChatMenu multicastMpChatMenu = new MulticastMpChatMenu(publicChatWindow);
|
||||||
|
UnicastMpChatMenu unicastMpChatMenu = new UnicastMpChatMenu(privateChatController);
|
||||||
|
|
||||||
|
pitiupi.createMenu(MenuCategory.Social, multicastMpChatMenu);
|
||||||
|
pitiupi.createMenu(MenuCategory.Social, unicastMpChatMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Message getMessage() {
|
public List<Class<? extends Message>> getMessages() {
|
||||||
return new MpChatMessage();
|
return List.of(MpChatMessage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveMessage(byte[] message) {
|
public void receiveMessage(Message message) {
|
||||||
MpChatMessage mpChatMessage = parseMessage(message);
|
if (message instanceof MpChatMessage mpChatMessage) {
|
||||||
chatController.receivePublic(mpChatMessage);
|
publicChatWindow.receiveMessage(mpChatMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean receivePrivateConnection(TcpConnection connection) {
|
public boolean receivePrivateConnection(TcpConnection connection) {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
chatController.addChatWindow(connection);
|
privateChatController.connectionReceived(connection);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -72,25 +84,29 @@ public class MultiProtocolChat extends Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public boolean receiveBytes(TcpConnection connection, byte[] bytes) {
|
public boolean receiveBytes(TcpConnection connection, byte[] bytes) {
|
||||||
MpChatMessage mpChatMessage = parseMessage(bytes);
|
MpChatMessage mpChatMessage = parseMessage(bytes);
|
||||||
chatController.receivePrivate(connection, mpChatMessage);
|
if (mpChatMessage == null) {
|
||||||
|
System.out.println("Invalid message received");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else System.out.println(mpChatMessage.getMessage());
|
||||||
|
|
||||||
|
privateChatController.receiveMessage(connection, mpChatMessage);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSocketClosed(TcpConnection connection) {
|
public boolean onSocketClosed(TcpConnection connection) {
|
||||||
chatController.removeChatWindow(connection);
|
privateChatController.closeChat(connection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean openConnection(String ip) {
|
public void openConnection(String ip) {
|
||||||
try {
|
try {
|
||||||
connectionManager.connectPluginTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier());
|
pitiupi.connectTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
System.out.println("Error opening connection: " + e.getMessage());
|
System.out.println("Error opening connection: " + e.getMessage());
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MpChatMessage parseMessage(byte[] bytes) {
|
private MpChatMessage parseMessage(byte[] bytes) {
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
File renamed without changes.
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/pitiupi.testSocket.iml" filepath="$PROJECT_DIR$/pitiupi.testSocket.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,2 +1,512 @@
|
|||||||
# Como criar plugins para o Share my Sheet
|
# Como criar plugins para o Pitiupi
|
||||||
|
|
||||||
|
Aqui serão discutidos os métodos e classes que um desenvolvedor pode ou deve usar para criar um plugin para a plataforma Pitiupi.
|
||||||
|
|
||||||
|
Alguns deles estarão marcados com um <span style="color: red;">[REF]</span>, isso indica que eles estão sendo alterados para a versão 3.0 e deixarão de existir ou vão mudar consideravelmente.
|
||||||
|
|
||||||
|
## GUI
|
||||||
|
|
||||||
|
O Pitiupi é feito usando a biblioteca Swing do Java, por isso é altamente recomendado que os plugins também a utilizem na hora de criar sua interface gráfica, porém não é obrigatório.
|
||||||
|
|
||||||
|
## Como tornar o seu plugin visível para o Pitiupi
|
||||||
|
|
||||||
|
A busca por plugins é realizada em três etapas pelo pitiupi:
|
||||||
|
|
||||||
|
1. Encontra todos os jars em `plugins`.
|
||||||
|
2. Verifica o `META-INF` dos jars para saber onde estão as implementações da classe `Plugin`.
|
||||||
|
3. Carrega o plugin no sistema.
|
||||||
|
|
||||||
|
Em relação ao `META-INF`, ele deve conter um diretório `resources` e dentro dele um arquivo contendo o nome completamente qualificado da classe `Plugin` do pitiupi: `pitiupi.models.Plugin`, por fim dentro desse arquivo você deve colocar o nome completamente qualificado de todas as classes que implementam `Plugin` do seu projeto, um em cada linha.
|
||||||
|
|
||||||
|
```
|
||||||
|
build/
|
||||||
|
|---->META-INF/resources/pitiupi.models.Plugin
|
||||||
|
|---->MeusPlugins/...
|
||||||
|
|---->MinhasMensagens/...
|
||||||
|
|---->Restante dos .class
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
src/MeusPlugins/MeuPrimeiroPlugin
|
||||||
|
src/MeusPlugins/MeuSegundoPlugin
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dicas
|
||||||
|
|
||||||
|
- Faça um makefile que automaticamente mova o META-INF para o build/ quando você compilar uma nova versão caso ele esteja sendo alterado com frequência.
|
||||||
|
Ex:
|
||||||
|
```
|
||||||
|
JAR = ../pitiupi/dist/pitiupi.jar
|
||||||
|
BUILD_DIR = build
|
||||||
|
META-INF_DIR = src/META-INF
|
||||||
|
DIST = dist/mpChat.jar
|
||||||
|
|
||||||
|
SOURCES = $(shell find -name "*.java")
|
||||||
|
|
||||||
|
all:
|
||||||
|
mkdir -p "$(BUILD_DIR)"
|
||||||
|
mkdir -p "$(dir $(DIST))"
|
||||||
|
javac -cp "$(JAR)" -d "$(BUILD_DIR)" $(SOURCES)
|
||||||
|
cp -r "$(META-INF_DIR)" "$(BUILD_DIR)"
|
||||||
|
jar cf "$(DIST)" -C "$(BUILD_DIR)" .
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf "$(BUILD_DIR)"/*
|
||||||
|
```
|
||||||
|
|
||||||
|
- Para a versão 3.0 será necessário fazer o mesmo processo para as implementações da classe `Message`, então se quiser deixar preparado para a nova versão adicione `pitiupi.models.Messages.Message` em `resources` e coloque nele todas suas implementações de `Message`, assim como você fez para os de `Plugin`.
|
||||||
|
|
||||||
|
## Pitiupi
|
||||||
|
|
||||||
|
A classe `Pitiupi` é a interface que o seu plugin vai receber quando for criado, ela fornece os métodos necessários para interagir com a interface gráfica e comunicação para outros peers.
|
||||||
|
|
||||||
|
### boolean sendUdpMulticast(Message message)
|
||||||
|
|
||||||
|
Envia uma mensagem multicast, retorna `boolean` indicando se teve sucesso.
|
||||||
|
|
||||||
|
### boolean sendUdpUnicast(Message message, InetAddress address)
|
||||||
|
|
||||||
|
Envia uma mensagem unicast via udp para o endereço fornecido, retorna `boolean` indicando se teve sucesso.
|
||||||
|
|
||||||
|
### boolean sendTcp(Message message, InetAddress address)
|
||||||
|
|
||||||
|
Envia uma mensagem unicast via tcp para o endereço fornecido, retorna `boolean` indicando se teve sucesso.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> TcpConnection connectTcp(InetAddress address, String senderId, String receiverId)
|
||||||
|
|
||||||
|
Pede uma conexão tcp privada para o seu plugin com outro usuário, para utilizar essa funcionalidade é necessário implementar alguns métodos opcionais em Plugin. Maisinformações serão discutidas na seção TcpConnection.
|
||||||
|
|
||||||
|
### String getUserName()
|
||||||
|
|
||||||
|
Retorna o nome do usuário conectado
|
||||||
|
|
||||||
|
### int getPort()
|
||||||
|
|
||||||
|
Retorna a porta que o usuário está usando o Pitiupi
|
||||||
|
|
||||||
|
### void createMenu(MenuCategory category, Menu menu)
|
||||||
|
|
||||||
|
Adiciona um menu ao pitiupi, category define em qual das categoria de Menus ele será adicionado: Jogos, Social, Streaming.
|
||||||
|
|
||||||
|
Os `Menus` serão discutidos em uma seção posterior.
|
||||||
|
|
||||||
|
## Classe Plugin
|
||||||
|
|
||||||
|
Essa é a classe que o pitiupi vai procurar ao carregar o seu plugin, ela define um contrato de métodos que todo plugin deve possuir.
|
||||||
|
|
||||||
|
### getName()
|
||||||
|
|
||||||
|
Indica o nome público do plugin.
|
||||||
|
|
||||||
|
### getAuthor()
|
||||||
|
|
||||||
|
Indica o nome dos desenvolvedores do plugin.
|
||||||
|
|
||||||
|
### getVersion()
|
||||||
|
|
||||||
|
Indica a versão atual do plugin.
|
||||||
|
|
||||||
|
### getIdentifier()
|
||||||
|
|
||||||
|
Indica um id que o pitiupi vai utilizar para enontrar seu plugin, por isso é importante que ele seja bem especifico para evitar que dois plugins sejam confundidos durante a comunicação. Procure usar algo como: MeuPlugin.Autor.Números
|
||||||
|
|
||||||
|
### createPlugin(Pitiupi pitiupi)
|
||||||
|
|
||||||
|
Após o pitiupi identificar e carregar o seu plugin, ele vai chamar esse método para inicializá-lo, por isso pense nele como o construtor do seu plugin, é aqui que você inicializa atributos, adiciona os menus inciais, etc.
|
||||||
|
|
||||||
|
### getMessages()
|
||||||
|
|
||||||
|
Esse método indica ao pitiupi quais tipos de mensagem seu plugin quer receber, normalmente as que ele mesmo implementar.
|
||||||
|
Nesse caso, é normal que ele faça:
|
||||||
|
|
||||||
|
```
|
||||||
|
return List.of(
|
||||||
|
SuaMensagem1.class,
|
||||||
|
SuaMensagem2.class,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Caso você queira que seu plugin receba todo tipo de mensagem, existe um método `receiveAllTypes()` que ele pode sobreescrever para receber todas mensagens
|
||||||
|
que não sejam consideradas privadas.
|
||||||
|
|
||||||
|
### receiveMessage(Message message)
|
||||||
|
|
||||||
|
Esse é o método que o pitiupi vai chamar quando quiser te entregar uma mensagem pelo canal publico de mensagens. Note que ele entrega uma `Message`, então é necessário que
|
||||||
|
seu plugin confira o tipo real ele mesmo. Como em:
|
||||||
|
|
||||||
|
```
|
||||||
|
if (message instanceOf MinhaMensagem minhaMensagem) {...}
|
||||||
|
```
|
||||||
|
|
||||||
|
O pitiupi garante que é uma mensagem de um tipo que o seu plugin diz aceitar.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> métodos opcionais
|
||||||
|
|
||||||
|
Os métodos a seguir possuem uma implementação padrão da própria classe que retornam false. Os três ultimos são necessários caso seu plugin deseje criar e receber conexões privadas.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> receiveAllTypes()
|
||||||
|
|
||||||
|
Indica ao Pitiupi que seu plugin deseja receber todas as mensagens publicas da plataforma, independente do tipo.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> receivePrivateConnection(TcpConnection connection)
|
||||||
|
|
||||||
|
Esse método é chamado quando o Pitiupi precisa entregar uma `TcpConnection` ao seu plugin, seja um que você pediu ou recebeu de um peer.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> receiveBytes(TcpConnection connection, byte[] bytes)
|
||||||
|
|
||||||
|
Esse método é chamado para entregar as mensagens recebidas por um `TcpConnection`, o tcpConnection no parametro indica qual a fonte da mensagem.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> onSocketClosed(TcpConnection connection)
|
||||||
|
|
||||||
|
Esse é método é chamado quando o socket de um `TcpConnection` pertencente ao plugin é fechado.
|
||||||
|
|
||||||
|
## Message
|
||||||
|
|
||||||
|
Essa é a classe abstrata que o pitiupi usa para comunicação nos canais publicos.
|
||||||
|
|
||||||
|
<span style="color: red;">[REF]</span> Ela possui um atributo isPublic que por padrão é true, mas é possível defini-lo no construtor como false caso a mensagem deva ser privada.
|
||||||
|
|
||||||
|
Essa classe implementa `Serializable` e possui um método `toByteArray` que transforma a mensagem em `byte[]`. Porém é importante notar que caso ela possua um objeto de outra classe como atributo aquela classe também deve implementar `Serializable`.
|
||||||
|
|
||||||
|
## <span style="color: red;">[REF]</span> TcpConnection
|
||||||
|
|
||||||
|
Representa uma conexão Tcp ativa para algum outro peer, mensagens enviadas por essa conexão não chegam ao canal publico e em vez disso vão direto para destinatário.
|
||||||
|
|
||||||
|
Caso fique inativa (Sem enviar ou receber mensagens) por 5 minutos a conexão é fechada automaticamente e o dono é notificado.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> void send(byte[] message)
|
||||||
|
|
||||||
|
Envia um conjunto de bytes[] para o destinatario.
|
||||||
|
|
||||||
|
Caso queira enviar uma `Message` chame o método toByteArray para transforma-la em bytes primeiro.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> boolean isClosed()
|
||||||
|
|
||||||
|
Indica se a conexão esta fechada
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> InetAddress getAddress()
|
||||||
|
|
||||||
|
Retorna o endereço do peer que ela esta conectada.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> String getReceiver()
|
||||||
|
|
||||||
|
Retorna o identificador do plugin que ela esta conectada.
|
||||||
|
|
||||||
|
### <span style="color: red;">[REF]</span> getReceiver()
|
||||||
|
|
||||||
|
Retorna o identifador do plugin que pediu pela conexão.
|
||||||
|
|
||||||
|
## Menu
|
||||||
|
|
||||||
|
Essa é a classe que indica ao pitiupi que um menu deve ser adicionado a janela principal da aplicação.
|
||||||
|
|
||||||
|
Menus podem ser de dois tipos `UnicastMenu` e `MulticastMenu` com a principal diferença entre eles sendo onde eles são adicionados na janela principal. Outras mudanças serão discutidas quando for relevante nas classes a seguir.
|
||||||
|
|
||||||
|
Atualmente Menus não podem ser alterados uma vez que são adicionados, então é importante que eles sejam feitos com isso em mente.
|
||||||
|
|
||||||
|
Tem um método `String getText()` que retorna o que deve ser escrito no Menu`.
|
||||||
|
|
||||||
|
### SubMenu
|
||||||
|
|
||||||
|
Permite que o `Menu` expanda em uma nova seção de menus.
|
||||||
|
|
||||||
|
`UnicastSubMenu` o método `getMenu()` retorna `List<UnicastMenu>`
|
||||||
|
|
||||||
|
`MulticastSubMenu` o método `getMenu()` retorna `List<MulticastMenu>`
|
||||||
|
|
||||||
|
Exemplo:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
ChatCasualMulticastMenu chatCasualMulticastMenu;
|
||||||
|
ChatEstudoMutlticastMenu chatEstudoMutlticastMenu;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MulticastMenu> getMenus() {
|
||||||
|
return List.of(chatCasualMulticastMenu, chatEstudoMutlticastMenu);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ActionMenu
|
||||||
|
|
||||||
|
É um `Menu` que que realiza alguma ação quando selecionado pelo usuário.
|
||||||
|
|
||||||
|
`UnicastActionMenu` o método `onClick(User user)` é chamado quando selecionado pelo usuário, recebendo como parametro o peer escolhido pelo usuário.
|
||||||
|
|
||||||
|
`MulticastActionMenu` o método `onClick()` é chamado quando selecionado pelo usuário.
|
||||||
|
|
||||||
|
Exemplo:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(User user) {
|
||||||
|
callManager.openCallWindow(user);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exemplo de plugin no pitiupi:
|
||||||
|
|
||||||
|
### Plugin
|
||||||
|
|
||||||
|
Implementa o contrato de plugin.
|
||||||
|
|
||||||
|
Inicializa a janela principal e cria os menus.
|
||||||
|
|
||||||
|
Também define quais tipos de mensagem ele quer receber.
|
||||||
|
|
||||||
|
```
|
||||||
|
public class ChatPlugin extends Plugin {
|
||||||
|
|
||||||
|
private ChatWindow chatWindow;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createPlugin(Pitiupi pitiupi) {
|
||||||
|
this.chatWindow = new ChatWindow(pitiupi);
|
||||||
|
pitiupi.createMenu(MenuCategory.Social, new ChatMenu(chatWindow));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<? extends Message>> getMessages() {
|
||||||
|
return List.of(ChatMessage.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveMessage(Message message) {
|
||||||
|
if (message instanceof ChatMessage msg) {
|
||||||
|
this.chatWindow.receiveChatMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Chat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthor() {
|
||||||
|
return "Flávio Schiavoni";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "Pitiupi.Chat.Example.123456";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Message
|
||||||
|
|
||||||
|
Implementa uma mensagem customizada que o plugin vai utilizar para comunicação.
|
||||||
|
|
||||||
|
```
|
||||||
|
public class ChatMessage extends Message {
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
public ChatMessage(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatMessage(String name, String text){
|
||||||
|
this.name = name;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the text
|
||||||
|
*/
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param text the text to set
|
||||||
|
*/
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Menus
|
||||||
|
|
||||||
|
Implementa os dois menus de Multicast utilizados pela aplicação.
|
||||||
|
|
||||||
|
#### ActionMenu
|
||||||
|
|
||||||
|
Esse menu apenas abre a janela principal do plugin.
|
||||||
|
|
||||||
|
```
|
||||||
|
public class ChatMulticastMenu extends MulticastActionMenu {
|
||||||
|
ChatWindow chatWindow;
|
||||||
|
|
||||||
|
public ChatMulticastMenu(ChatWindow chatWindow) {
|
||||||
|
this.chatWindow = chatWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return "Show Chat Window";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick() {
|
||||||
|
chatWindow.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Esse menu abre a seção de menus do plugin Chat.
|
||||||
|
|
||||||
|
#### SubMenu
|
||||||
|
|
||||||
|
```
|
||||||
|
public class ChatMenu extends MulticastSubMenu {
|
||||||
|
ChatMulticastMenu chatMulticastMenu;
|
||||||
|
|
||||||
|
public ChatMenu(ChatWindow chatWindow) {
|
||||||
|
this.chatMulticastMenu = new ChatMulticastMenu(chatWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return "Chat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MulticastMenu> getMenus() {
|
||||||
|
return List.of(chatMulticastMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GUI
|
||||||
|
|
||||||
|
Essa é a janela principal do plugin de chat.
|
||||||
|
|
||||||
|
```
|
||||||
|
public class ChatWindow extends JDialog {
|
||||||
|
|
||||||
|
private JButton jButton1;
|
||||||
|
private JEditorPane jEditorPane1;
|
||||||
|
private JPanel jPanel1;
|
||||||
|
private JPanel jPanel2;
|
||||||
|
private JScrollPane jScrollPane1;
|
||||||
|
private JScrollPane jScrollPane2;
|
||||||
|
private JSplitPane jSplitPane1;
|
||||||
|
private JTextArea jTextArea1;
|
||||||
|
|
||||||
|
private final Pitiupi pitiupi;
|
||||||
|
|
||||||
|
public ChatWindow(Pitiupi pitiupi) {
|
||||||
|
this.pitiupi = pitiupi;
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
|
||||||
|
this.setTitle("Chat Window");
|
||||||
|
this.setBounds(new java.awt.Rectangle(0, 0, 800, 600));
|
||||||
|
this.getContentPane().setLayout(new java.awt.BorderLayout(5, 5));
|
||||||
|
this.setPreferredSize(new java.awt.Dimension(800, 600));
|
||||||
|
|
||||||
|
jSplitPane1 = new JSplitPane();
|
||||||
|
jScrollPane1 = new JScrollPane();
|
||||||
|
jEditorPane1 = new JEditorPane();
|
||||||
|
jPanel1 = new JPanel();
|
||||||
|
jScrollPane2 = new JScrollPane();
|
||||||
|
jTextArea1 = new JTextArea();
|
||||||
|
jPanel2 = new JPanel();
|
||||||
|
jButton1 = new JButton();
|
||||||
|
|
||||||
|
jSplitPane1.setDividerLocation(500);
|
||||||
|
jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||||
|
jEditorPane1.setContentType("text/html");
|
||||||
|
jPanel1.setLayout(new java.awt.BorderLayout());
|
||||||
|
jTextArea1.setColumns(20);
|
||||||
|
jTextArea1.setRows(5);
|
||||||
|
jTextArea1.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyTyped(java.awt.event.KeyEvent evt) {
|
||||||
|
if (evt.getKeyChar() == '\n') {
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
jButton1.setText("Send");
|
||||||
|
|
||||||
|
jScrollPane1.setViewportView(jEditorPane1);
|
||||||
|
jScrollPane2.setViewportView(jTextArea1);
|
||||||
|
jSplitPane1.setTopComponent(jScrollPane1);
|
||||||
|
|
||||||
|
jPanel1.add(jScrollPane2, java.awt.BorderLayout.CENTER);
|
||||||
|
jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));
|
||||||
|
jButton1.addActionListener((java.awt.event.ActionEvent evt) -> {
|
||||||
|
sendMessage();
|
||||||
|
});
|
||||||
|
jPanel2.add(jButton1);
|
||||||
|
jPanel1.add(jPanel2, java.awt.BorderLayout.PAGE_END);
|
||||||
|
jSplitPane1.setRightComponent(jPanel1);
|
||||||
|
getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);
|
||||||
|
pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage() {
|
||||||
|
if (jTextArea1.getText().trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ChatMessage message = new ChatMessage(pitiupi.getUserName(), jTextArea1.getText());
|
||||||
|
this.sendChatMessage(message);
|
||||||
|
jTextArea1.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChatMessage(Message message) {
|
||||||
|
pitiupi.sendUdpMulticast(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveChatMessage(ChatMessage message) {
|
||||||
|
SimpleDateFormat dt = new SimpleDateFormat("dd/MM/yyyyy hh:mm:ss");
|
||||||
|
Date date = new Date();
|
||||||
|
this.receiveChatMessage(dt.format(date) + " "
|
||||||
|
+ "<b>" + message.getName() + "</b>: "
|
||||||
|
+ message.getText() + "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveChatMessage(String message) {
|
||||||
|
jEditorPane1.setText(message + jEditorPane1.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -111,7 +111,6 @@ public class MenuBar extends JMenuBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addPluginMenu(MenuCategory category, JMenuItem menu){
|
public void addPluginMenu(MenuCategory category, JMenuItem menu){
|
||||||
System.out.println("addPluginMenu");
|
|
||||||
categories.get(category).add(menu);
|
categories.get(category).add(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,18 +30,6 @@ public class GuiManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void createMenu(MenuCategory category, Menu menu) {
|
public void createMenu(MenuCategory category, Menu menu) {
|
||||||
System.out.println(
|
|
||||||
menu.getClass().getSuperclass().getSuperclass()
|
|
||||||
);
|
|
||||||
|
|
||||||
System.out.println(
|
|
||||||
MulticastMenu.class
|
|
||||||
);
|
|
||||||
|
|
||||||
System.out.println(
|
|
||||||
menu.getClass().getSuperclass().getSuperclass()
|
|
||||||
== MulticastMenu.class
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
JMenuItem newMenu = buildMenu(menu);
|
JMenuItem newMenu = buildMenu(menu);
|
||||||
if (menu instanceof MulticastMenu) {
|
if (menu instanceof MulticastMenu) {
|
||||||
@@ -55,7 +43,6 @@ public class GuiManager {
|
|||||||
logger.log(Level.WARNING, e.getMessage());
|
logger.log(Level.WARNING, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JMenuItem buildMenu(Menu menu) {
|
private JMenuItem buildMenu(Menu menu) {
|
||||||
if (menu instanceof MulticastSubMenu multicastSubMenu) {
|
if (menu instanceof MulticastSubMenu multicastSubMenu) {
|
||||||
JMenu newMenu = new JMenu(menu.getText());
|
JMenu newMenu = new JMenu(menu.getText());
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package pitiupi.control.plugins;
|
package pitiupi.control.plugins;
|
||||||
|
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
import pitiupi.Main;
|
import pitiupi.Main;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
import pitiupi.control.GuiManager;
|
||||||
@@ -60,8 +61,9 @@ public class PluginManager {
|
|||||||
|
|
||||||
private Plugin getPlugin(String pluginId) {
|
private Plugin getPlugin(String pluginId) {
|
||||||
for (LoadedPlugin loadedPlugin : loadedPlugins) {
|
for (LoadedPlugin loadedPlugin : loadedPlugins) {
|
||||||
if (loadedPlugin.getPlugin().getIdentifier().equals(pluginId))
|
if (loadedPlugin.getPlugin().getIdentifier().equals(pluginId)) {
|
||||||
return loadedPlugin.getPlugin();
|
return loadedPlugin.getPlugin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -79,7 +81,7 @@ public class PluginManager {
|
|||||||
|
|
||||||
plugin.receivePrivateConnection(connection);
|
plugin.receivePrivateConnection(connection);
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleDisconnection(TcpConnection connection, String receiverId) {
|
public void handleDisconnection(TcpConnection connection, String receiverId) {
|
||||||
@@ -92,6 +94,7 @@ public class PluginManager {
|
|||||||
public void loadPlugins(ConnectionManager connectionManager, GuiManager guiManager) {
|
public void loadPlugins(ConnectionManager connectionManager, GuiManager guiManager) {
|
||||||
File pluginDir = new File("plugins");
|
File pluginDir = new File("plugins");
|
||||||
File[] jarFiles = pluginDir.listFiles((dir, name) -> name.endsWith(".jar"));
|
File[] jarFiles = pluginDir.listFiles((dir, name) -> name.endsWith(".jar"));
|
||||||
|
Pitiupi pitiupi = new Pitiupi(connectionManager, guiManager);
|
||||||
|
|
||||||
if (jarFiles == null || jarFiles.length == 0) {
|
if (jarFiles == null || jarFiles.length == 0) {
|
||||||
System.out.println("No plugins found in the " + pluginDir.getAbsolutePath() + " directory.");
|
System.out.println("No plugins found in the " + pluginDir.getAbsolutePath() + " directory.");
|
||||||
@@ -115,10 +118,9 @@ public class PluginManager {
|
|||||||
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, classLoader);
|
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, classLoader);
|
||||||
|
|
||||||
for (Plugin plugin : serviceLoader) {
|
for (Plugin plugin : serviceLoader) {
|
||||||
System.out.println("Loading: " + plugin.getName());
|
|
||||||
LoadedPlugin loadedPlugin = new LoadedPlugin(plugin, classLoader);
|
LoadedPlugin loadedPlugin = new LoadedPlugin(plugin, classLoader);
|
||||||
|
|
||||||
plugin.createPlugin(connectionManager, guiManager);
|
plugin.createPlugin(pitiupi);
|
||||||
loadedPlugins.add(loadedPlugin);
|
loadedPlugins.add(loadedPlugin);
|
||||||
loadedJars.add(file.getName());
|
loadedJars.add(file.getName());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template
|
||||||
*/
|
*/
|
||||||
package pitiupi.models;
|
package pitiupi.models;
|
||||||
|
import pitiupi.plugin.Pitiupi;
|
||||||
import pitiupi.control.ConnectionManager;
|
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.net.tcp.TcpConnection;
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
|
||||||
@@ -30,10 +28,9 @@ public abstract class Plugin {
|
|||||||
*
|
*
|
||||||
* <p>Este método é chamado pela aplicação após o carregamento do plugin.</p>
|
* <p>Este método é chamado pela aplicação após o carregamento do plugin.</p>
|
||||||
*
|
*
|
||||||
* @param connectionManager interface com o sistema de conexões da aplicação.
|
* @param pitiupi interface com o sistema de conexões da aplicação.
|
||||||
* @param guiManager interface com a janela principal da aplicação
|
|
||||||
*/
|
*/
|
||||||
public abstract void createPlugin(ConnectionManager connectionManager, GuiManager guiManager);
|
public abstract void createPlugin(Pitiupi pitiupi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retorna uma mensagem utilizada pelo plugin.
|
* Retorna uma mensagem utilizada pelo plugin.
|
||||||
@@ -62,4 +59,4 @@ public abstract class Plugin {
|
|||||||
public boolean onSocketClosed(TcpConnection connection) {
|
public boolean onSocketClosed(TcpConnection connection) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,8 +271,9 @@ public class SocketTCP extends Thread {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pluginManager.handleConnection(connection, connection.getReceiver()))
|
if (pluginManager.handleConnection(connection, connection.getReceiver())) {
|
||||||
privateConnectionReceiver(connection);
|
privateConnectionReceiver(connection);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
InfoMessage.sendSystemInfo(
|
InfoMessage.sendSystemInfo(
|
||||||
connection,
|
connection,
|
||||||
@@ -336,7 +337,7 @@ public class SocketTCP extends Thread {
|
|||||||
* ao plugin destinatário.
|
* ao plugin destinatário.
|
||||||
*
|
*
|
||||||
* <p>Dados que não representam mensagens de controle são entregues
|
* <p>Dados que não representam mensagens de controle são entregues
|
||||||
* diretamente ao {@link PrivateConnectionPlugin}. Mensagens de controle
|
* diretamente ao {@link pitiupi.models.Plugin}. Mensagens de controle
|
||||||
* relacionadas ao encerramento ou a erros internos provocam a notificação
|
* relacionadas ao encerramento ou a erros internos provocam a notificação
|
||||||
* do plugin e o fechamento da conexão.</p>
|
* do plugin e o fechamento da conexão.</p>
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.io.IOException;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representa uma conexão TCP ativa com um peer remoto.
|
* Representa uma conexão TCP ativa com um peer remoto.
|
||||||
@@ -77,6 +78,7 @@ public class TcpConnection {
|
|||||||
|
|
||||||
byte[] message = input.readNBytes(length);
|
byte[] message = input.readNBytes(length);
|
||||||
|
|
||||||
|
|
||||||
if (message.length != length) {
|
if (message.length != length) {
|
||||||
throw new IOException("Connection closed before receiving the complete message.");
|
throw new IOException("Connection closed before receiving the complete message.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package pitiupi.plugin;
|
||||||
|
|
||||||
|
import pitiupi.control.ConnectionManager;
|
||||||
|
import pitiupi.control.GuiManager;
|
||||||
|
import pitiupi.models.Menus.Menu;
|
||||||
|
import pitiupi.models.Menus.MenuCategory;
|
||||||
|
import pitiupi.models.Messages.Message;
|
||||||
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class Pitiupi {
|
||||||
|
|
||||||
|
private final ConnectionManager connectionManager;
|
||||||
|
private final GuiManager guiManager;
|
||||||
|
|
||||||
|
public Pitiupi(ConnectionManager connectionManager, GuiManager guiManager) {
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
|
this.guiManager = guiManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendUdpMulticast(Message message) {
|
||||||
|
return connectionManager.sendUdpMulticast(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendUdpUnicast(Message message, InetAddress address) {
|
||||||
|
return connectionManager.sendUdpUnicast(message, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendTcp(Message message, InetAddress address) {
|
||||||
|
return connectionManager.sendTcp(message, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TcpConnection connectTcp(InetAddress address, String senderId, String receiverId) {
|
||||||
|
return connectionManager.connectPluginTcp(address, senderId, receiverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return connectionManager.getUserName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return connectionManager.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createMenu(MenuCategory category, Menu menu) {
|
||||||
|
guiManager.createMenu(category, menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user