Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe1c8d24b9 |
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
/pitiupi/build/
|
||||||
|
/pitiupi/dist/
|
||||||
|
/pitiupi.chat/build/
|
||||||
|
/pitiupi.chat/dist/
|
||||||
|
/pitiupi.chat/nbproject/private/
|
||||||
|
/pitiupi.screenCast/build/
|
||||||
|
/pitiupi.screenCast/dist/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#Thu, 16 Jul 2026 15:21:36 -0300
|
#Fri, 17 Jul 2026 17:31:55 -0300
|
||||||
|
|
||||||
|
|
||||||
/home/flavio/NetBeansProjects/pitiupi.chat=
|
/home/perolanegra/facul/pitiupi/pitiupi.chat=
|
||||||
|
|
||||||
/home/flavio/NetBeansProjects/pitiupi=
|
/home/perolanegra/facul/pitiupi/pitiupi=
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Vendored
BIN
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=21
|
||||||
javac.target=25
|
javac.target=21
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}
|
${build.classes.dir}
|
||||||
|
|||||||
@@ -5,18 +5,16 @@
|
|||||||
*/
|
*/
|
||||||
package pitiupi.chat.GUI;
|
package pitiupi.chat.GUI;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import pitiupi.chat.net.ChatMessage;
|
import pitiupi.chat.net.ChatMessage;
|
||||||
import pitiupi.GUI.MainWindow;
|
import pitiupi.plugin.PitiupiFacade;
|
||||||
import pitiupi.net.Message;
|
import pitiupi.net.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author flavio
|
* @author flavio
|
||||||
|
* @author tony
|
||||||
*/
|
*/
|
||||||
public class ChatWindow extends javax.swing.JDialog {
|
public class ChatWindow extends javax.swing.JDialog {
|
||||||
|
|
||||||
@@ -29,10 +27,10 @@ public class ChatWindow extends javax.swing.JDialog {
|
|||||||
private javax.swing.JSplitPane jSplitPane1;
|
private javax.swing.JSplitPane jSplitPane1;
|
||||||
private javax.swing.JTextArea jTextArea1;
|
private javax.swing.JTextArea jTextArea1;
|
||||||
|
|
||||||
private final MainWindow mainWindow;
|
private final PitiupiFacade pitiupi;
|
||||||
|
|
||||||
public ChatWindow(MainWindow mainWindow) {
|
public ChatWindow(PitiupiFacade pitiupi) {
|
||||||
this.mainWindow = mainWindow;
|
this.pitiupi = pitiupi;
|
||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,17 +92,13 @@ public class ChatWindow extends javax.swing.JDialog {
|
|||||||
if (jTextArea1.getText().trim().length() == 0) {
|
if (jTextArea1.getText().trim().length() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ChatMessage message = new ChatMessage(mainWindow.getName(), 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) {
|
||||||
try {
|
pitiupi.send(message);
|
||||||
mainWindow.getSocket().send(message.toByteArray());
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveChatMessage(ChatMessage message) {
|
public void receiveChatMessage(ChatMessage message) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package pitiupi.chat.plugin;
|
|||||||
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 pitiupi.GUI.MainWindow;
|
import pitiupi.plugin.PitiupiFacade;
|
||||||
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;
|
||||||
@@ -17,20 +17,18 @@ import pitiupi.plugin.Plugin;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author flavio
|
* @author flavio
|
||||||
|
* @author tony
|
||||||
*/
|
*/
|
||||||
public class ChatPlugin implements Plugin {
|
public class ChatPlugin implements Plugin {
|
||||||
|
|
||||||
private ChatWindow chatWindow;
|
private ChatWindow chatWindow;
|
||||||
private MainWindow mainWindow;
|
private PitiupiFacade pitiupi;
|
||||||
|
|
||||||
public ChatPlugin() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(MainWindow mainWindow) {
|
public void createPlugin(PitiupiFacade pitiupi) {
|
||||||
this.mainWindow = mainWindow;
|
this.pitiupi = pitiupi;
|
||||||
this.chatWindow = new ChatWindow(mainWindow);
|
this.chatWindow = new ChatWindow(pitiupi);
|
||||||
this.mainWindow.addMenu(new ChatMenu(chatWindow));
|
this.pitiupi.addMenu(new ChatMenu(chatWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Thu, 16 Jul 2026 15:21:39 -0300
|
#Thu, 16 Jul 2026 17:43:45 -0300
|
||||||
|
|
||||||
|
|
||||||
/home/flavio/NetBeansProjects/pitiupi.screenCast=
|
/home/perolanegra/facul/2.26/fls/pitiupi/pitiupi.screenCast=
|
||||||
|
|
||||||
/home/flavio/NetBeansProjects/pitiupi=
|
/home/perolanegra/facul/2.26/fls/pitiupi/pitiupi=
|
||||||
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.
Vendored
-32
@@ -1,32 +0,0 @@
|
|||||||
========================
|
|
||||||
BUILD OUTPUT DESCRIPTION
|
|
||||||
========================
|
|
||||||
|
|
||||||
When you build an Java application project that has a main class, the IDE
|
|
||||||
automatically copies all of the JAR
|
|
||||||
files on the projects classpath to your projects dist/lib folder. The IDE
|
|
||||||
also adds each of the JAR files to the Class-Path element in the application
|
|
||||||
JAR files manifest file (MANIFEST.MF).
|
|
||||||
|
|
||||||
To run the project from the command line, go to the dist folder and
|
|
||||||
type the following:
|
|
||||||
|
|
||||||
java -jar "pitiupi.screenCast.jar"
|
|
||||||
|
|
||||||
To distribute this project, zip up the dist folder (including the lib folder)
|
|
||||||
and distribute the ZIP file.
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
* If two JAR files on the project classpath have the same name, only the first
|
|
||||||
JAR file is copied to the lib folder.
|
|
||||||
* Only JAR files are copied to the lib folder.
|
|
||||||
If the classpath contains other types of files or folders, these files (folders)
|
|
||||||
are not copied.
|
|
||||||
* If a library on the projects classpath also has a Class-Path element
|
|
||||||
specified in the manifest,the content of the Class-Path element has to be on
|
|
||||||
the projects runtime path.
|
|
||||||
* To set a main class in a standard Java project, right-click the project node
|
|
||||||
in the Projects window and choose Properties. Then click Run and enter the
|
|
||||||
class name in the Main Class field. Alternatively, you can manually type the
|
|
||||||
class name in the manifest Main-Class element.
|
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -45,8 +45,8 @@ javac.modulepath=
|
|||||||
javac.processormodulepath=
|
javac.processormodulepath=
|
||||||
javac.processorpath=\
|
javac.processorpath=\
|
||||||
${javac.classpath}
|
${javac.classpath}
|
||||||
javac.source=25
|
javac.source=21
|
||||||
javac.target=25
|
javac.target=21
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}
|
${build.classes.dir}
|
||||||
|
|||||||
Whitespace-only changes.
Whitespace-only 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.
Binary file not shown.
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -5,4 +5,4 @@ do.jlink=false
|
|||||||
javac.debug=true
|
javac.debug=true
|
||||||
javadoc.preview=true
|
javadoc.preview=true
|
||||||
jlink.strip=false
|
jlink.strip=false
|
||||||
user.properties.file=/home/flavio/snap/netbeans/145/build.properties
|
user.properties.file=/home/perolanegra/snap/netbeans/145/build.properties
|
||||||
@@ -2,9 +2,6 @@
|
|||||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||||
<group>
|
<group/>
|
||||||
<file>file:/home/flavio/NetBeansProjects/pitiupi/src/pitiupi/control/PluginManager.java</file>
|
|
||||||
<file>file:/home/flavio/NetBeansProjects/pitiupi/src/pitiupi/control/ImageTransformation.java</file>
|
|
||||||
</group>
|
|
||||||
</open-files>
|
</open-files>
|
||||||
</project-private>
|
</project-private>
|
||||||
@@ -46,8 +46,8 @@ javac.modulepath=
|
|||||||
javac.processormodulepath=
|
javac.processormodulepath=
|
||||||
javac.processorpath=\
|
javac.processorpath=\
|
||||||
${javac.classpath}
|
${javac.classpath}
|
||||||
javac.source=25
|
javac.source=21
|
||||||
javac.target=25
|
javac.target=21
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}
|
${build.classes.dir}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../../pitiupi.screenCast/dist/pitiupi.screenCast.jar
|
|
||||||
@@ -11,6 +11,7 @@ import java.util.List;
|
|||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import pitiupi.control.PluginLoader;
|
import pitiupi.control.PluginLoader;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
|
import pitiupi.control.HeartbeatManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -23,6 +24,8 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
private javax.swing.JLabel status;
|
private javax.swing.JLabel status;
|
||||||
private javax.swing.JPanel statusPanel;
|
private javax.swing.JPanel statusPanel;
|
||||||
private javax.swing.JTabbedPane tabbedPane;
|
private javax.swing.JTabbedPane tabbedPane;
|
||||||
|
private HeartbeatManager heartbeatManager;
|
||||||
|
private OnlineUsersPanel onlineUsersPanel;
|
||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
|
|
||||||
@@ -63,6 +66,12 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
|
|
||||||
this.socket = new Socket(this);
|
this.socket = new Socket(this);
|
||||||
this.socket.start();
|
this.socket.start();
|
||||||
|
|
||||||
|
this.heartbeatManager = new HeartbeatManager(this);
|
||||||
|
this.onlineUsersPanel = new OnlineUsersPanel();
|
||||||
|
this.heartbeatManager.addPeerListener(this.onlineUsersPanel);
|
||||||
|
this.getContentPane().add(this.onlineUsersPanel, java.awt.BorderLayout.LINE_END);
|
||||||
|
this.heartbeatManager.start();
|
||||||
|
|
||||||
this.setSize(new java.awt.Dimension(1024, 768));
|
this.setSize(new java.awt.Dimension(1024, 768));
|
||||||
this.pluginManager = new PluginLoader(this);
|
this.pluginManager = new PluginLoader(this);
|
||||||
@@ -76,6 +85,10 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HeartbeatManager getHeartbeatManager() {
|
||||||
|
return heartbeatManager;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUserName(){
|
public String getUserName(){
|
||||||
return this.userName;
|
return this.userName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package pitiupi.GUI;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.DefaultListModel;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import pitiupi.control.PeerInfo;
|
||||||
|
import pitiupi.control.PeerListener;
|
||||||
|
|
||||||
|
public class OnlineUsersPanel extends JPanel implements PeerListener {
|
||||||
|
|
||||||
|
private final DefaultListModel<String> listModel;
|
||||||
|
private final JList<String> userList;
|
||||||
|
|
||||||
|
public OnlineUsersPanel() {
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
setBorder(BorderFactory.createTitledBorder("Online"));
|
||||||
|
setPreferredSize(new Dimension(160, 0));
|
||||||
|
|
||||||
|
listModel = new DefaultListModel<>();
|
||||||
|
userList = new JList<>(listModel);
|
||||||
|
add(new JScrollPane(userList), BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPeersChanged(List<PeerInfo> peers) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
listModel.clear();
|
||||||
|
for (PeerInfo peer : peers) {
|
||||||
|
listModel.addElement(peer.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package pitiupi.control;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import pitiupi.GUI.MainWindow;
|
||||||
|
import pitiupi.net.HeartbeatMessage;
|
||||||
|
|
||||||
|
public class HeartbeatManager {
|
||||||
|
|
||||||
|
private static final long HEARTBEAT_INTERVAL_MS = 5000;
|
||||||
|
private static final long PEER_TIMEOUT_MS = 15000; // ~3 batimentos perdidos
|
||||||
|
|
||||||
|
private final MainWindow mainWindow;
|
||||||
|
private final Map<String, PeerInfo> peers = new ConcurrentHashMap<>();
|
||||||
|
private final List<PeerListener> listeners = new CopyOnWriteArrayList<>();
|
||||||
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
|
public HeartbeatManager(MainWindow mainWindow) {
|
||||||
|
this.mainWindow = mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
scheduler.scheduleAtFixedRate(this::announce, 0, HEARTBEAT_INTERVAL_MS, TimeUnit.MILLISECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(this::checkTimeouts, HEARTBEAT_INTERVAL_MS, HEARTBEAT_INTERVAL_MS, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (scheduler != null) {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void announce() {
|
||||||
|
try {
|
||||||
|
HeartbeatMessage msg = new HeartbeatMessage(mainWindow.getUserName());
|
||||||
|
mainWindow.getSocket().send(msg.toByteArray());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(HeartbeatManager.class.getName()).log(Level.WARNING, "Falha ao enviar heartbeat", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chamado pelo Socket quando um pacote é identificado como heartbeat
|
||||||
|
public void receiveHeartbeat(HeartbeatMessage msg, InetAddress from) {
|
||||||
|
// ignora o próprio heartbeat (multicast normalmente ecoa pro remetente)
|
||||||
|
if (msg.getUserName().equals(mainWindow.getUserName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = from.getHostAddress() + "#" + msg.getUserName();
|
||||||
|
boolean isNew = !peers.containsKey(key);
|
||||||
|
|
||||||
|
PeerInfo peer = peers.computeIfAbsent(key, k -> new PeerInfo(msg.getUserName(), from, msg.getTimestamp()));
|
||||||
|
peer.touch(System.currentTimeMillis());
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTimeouts() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
boolean changed = peers.values().removeIf(p -> now - p.getLastSeen() > PEER_TIMEOUT_MS);
|
||||||
|
if (changed) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyListeners() {
|
||||||
|
List<PeerInfo> snapshot = new ArrayList<>(peers.values());
|
||||||
|
for (PeerListener l : listeners) {
|
||||||
|
l.onPeersChanged(snapshot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPeerListener(PeerListener l) {
|
||||||
|
listeners.add(l);
|
||||||
|
l.onPeersChanged(new ArrayList<>(peers.values()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePeerListener(PeerListener l) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PeerInfo> getPeers() {
|
||||||
|
return new ArrayList<>(peers.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package pitiupi.control;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class PeerInfo {
|
||||||
|
|
||||||
|
private final String userName;
|
||||||
|
private final InetAddress address;
|
||||||
|
private volatile long lastSeen;
|
||||||
|
|
||||||
|
public PeerInfo(String userName, InetAddress address, long lastSeen) {
|
||||||
|
this.userName = userName;
|
||||||
|
this.address = address;
|
||||||
|
this.lastSeen = lastSeen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InetAddress getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastSeen() {
|
||||||
|
return lastSeen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void touch(long timestamp) {
|
||||||
|
this.lastSeen = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return userName + " (" + address.getHostAddress() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package pitiupi.control;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface PeerListener {
|
||||||
|
void onPeersChanged(List<PeerInfo> peers);
|
||||||
|
}
|
||||||
@@ -15,10 +15,11 @@ import java.util.Vector;
|
|||||||
import pitiupi.GUI.MainWindow;
|
import pitiupi.GUI.MainWindow;
|
||||||
import pitiupi.Main;
|
import pitiupi.Main;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
|
import pitiupi.plugin.PitiupiFacade;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author flavio
|
* @author flavio
|
||||||
|
* @author tony
|
||||||
*/
|
*/
|
||||||
public class PluginLoader {
|
public class PluginLoader {
|
||||||
|
|
||||||
@@ -55,12 +56,14 @@ public class PluginLoader {
|
|||||||
// 4. Locate and instantiate all classes implementing the Plugin interface
|
// 4. Locate and instantiate all classes implementing the Plugin interface
|
||||||
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, pluginClassLoader);
|
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, pluginClassLoader);
|
||||||
|
|
||||||
System.out.println("\n--- Executing Discovered Plugins ---" + serviceLoader.findFirst());
|
PitiupiFacade facade = new PitiupiFacade(this.mainWindow);
|
||||||
for (Plugin plugin : serviceLoader) {
|
|
||||||
System.out.println("Loading: " + plugin.getName());
|
System.out.println("\n--- Executing Discovered Plugins ---" + serviceLoader.findFirst());
|
||||||
plugin.createPlugin(this.mainWindow);
|
for (Plugin plugin : serviceLoader) {
|
||||||
this.mainWindow.getPlugins().add(plugin);
|
System.out.println("Loading: " + plugin.getName());
|
||||||
}
|
plugin.createPlugin(facade);
|
||||||
|
this.mainWindow.getPlugins().add(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
System.out.println(e.toString());
|
System.out.println(e.toString());
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package pitiupi.net;
|
||||||
|
|
||||||
|
public class HeartbeatMessage extends Message {
|
||||||
|
|
||||||
|
private final String userName;
|
||||||
|
private final long timestamp;
|
||||||
|
|
||||||
|
public HeartbeatMessage(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
this.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
Line truncated
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
|
|||||||
@@ -17,10 +17,13 @@ import java.net.UnknownHostException;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import pitiupi.net.HeartbeatMessage; // lib
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author flavio
|
* @author flavio
|
||||||
|
* @author tony
|
||||||
*/
|
*/
|
||||||
public class Socket extends Thread {
|
public class Socket extends Thread {
|
||||||
|
|
||||||
@@ -41,7 +44,45 @@ public class Socket extends Thread {
|
|||||||
multicastSocket.setSendBufferSize(256000);
|
multicastSocket.setSendBufferSize(256000);
|
||||||
multicastSocket.setReceiveBufferSize(256000);
|
multicastSocket.setReceiveBufferSize(256000);
|
||||||
multicastSocket.setReuseAddress(true);
|
multicastSocket.setReuseAddress(true);
|
||||||
multicastSocket.joinGroup(address);
|
System.out.println("Endereço local: " + multicastSocket.getLocalAddress());
|
||||||
|
System.out.println("Interface: " + multicastSocket.getNetworkInterface());
|
||||||
|
//InetAddress local = InetAddress.getLocalHost();
|
||||||
|
|
||||||
|
NetworkInterface nif = null;
|
||||||
|
|
||||||
|
for (NetworkInterface ni : java.util.Collections.list(
|
||||||
|
NetworkInterface.getNetworkInterfaces())) {
|
||||||
|
|
||||||
|
if (ni.isUp()
|
||||||
|
&& ni.supportsMulticast()
|
||||||
|
&& !ni.isLoopback()) {
|
||||||
|
|
||||||
|
nif = ni;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nif != null) {
|
||||||
|
System.out.println("Interface escolhida:");
|
||||||
|
System.out.println("Nome: " + nif.getName());
|
||||||
|
System.out.println("Descrição: " + nif.getDisplayName());
|
||||||
|
System.out.println("Ativa: " + nif.isUp());
|
||||||
|
System.out.println("Multicast: " + nif.supportsMulticast());
|
||||||
|
|
||||||
|
System.out.println("Endereços IP:");
|
||||||
|
|
||||||
|
for (InetAddress ip : java.util.Collections.list(nif.getInetAddresses())) {
|
||||||
|
System.out.println(" " + ip.getHostAddress());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Nenhuma interface multicast encontrada");
|
||||||
|
}
|
||||||
|
multicastSocket.joinGroup(
|
||||||
|
new InetSocketAddress(address, main.getPort()),
|
||||||
|
nif
|
||||||
|
);
|
||||||
|
System.out.println("nif: " + nif);
|
||||||
|
|
||||||
|
// multicastSocket.joinGroup(address);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.out.println("There is no socket connection. Sorry.");
|
System.out.println("There is no socket connection. Sorry.");
|
||||||
System.out.println(ex.toString());
|
System.out.println(ex.toString());
|
||||||
@@ -51,15 +92,27 @@ public class Socket extends Thread {
|
|||||||
public void send(byte[] msg) throws IOException {
|
public void send(byte[] msg) throws IOException {
|
||||||
DatagramPacket msgPacket;
|
DatagramPacket msgPacket;
|
||||||
msgPacket = new DatagramPacket(msg, msg.length, this.address, this.main.getPort());
|
msgPacket = new DatagramPacket(msg, msg.length, this.address, this.main.getPort());
|
||||||
|
|
||||||
|
System.out.println("Enviando pacote");
|
||||||
|
System.out.println("Destino: " + address);
|
||||||
|
System.out.println("Porta: " + this.main.getPort());
|
||||||
|
System.out.println("Bytes: " + msg.length);
|
||||||
|
|
||||||
multicastSocket.send(msgPacket);
|
multicastSocket.send(msgPacket);
|
||||||
}
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
public void receive() throws UnknownHostException, IOException, ClassNotFoundException {
|
public void receive() throws UnknownHostException, IOException, ClassNotFoundException {
|
||||||
byte[] buf = new byte[256000];
|
byte[] buf = new byte[256000];
|
||||||
while (true) {
|
while (true) {
|
||||||
// Receive the information and print it.
|
|
||||||
DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);
|
DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);
|
||||||
multicastSocket.receive(msgPacket);
|
multicastSocket.receive(msgPacket);
|
||||||
|
|
||||||
|
HeartbeatMessage heartbeat = tryParseHeartbeat(msgPacket.getData());
|
||||||
|
if (heartbeat != null) {
|
||||||
|
main.getHeartbeatManager().receiveHeartbeat(heartbeat, msgPacket.getAddress());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (Plugin plugin : main.getPlugins()) {
|
for (Plugin plugin : main.getPlugins()) {
|
||||||
System.out.println(msgPacket.getAddress().toString());
|
System.out.println(msgPacket.getAddress().toString());
|
||||||
plugin.receiveMessage(msgPacket.getData());
|
plugin.receiveMessage(msgPacket.getData());
|
||||||
@@ -67,6 +120,17 @@ public class Socket extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HeartbeatMessage tryParseHeartbeat(byte[] data) {
|
||||||
|
try {
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||||
|
ObjectInput in = new ObjectInputStream(bais);
|
||||||
|
Object obj = in.readObject();
|
||||||
|
return (obj instanceof HeartbeatMessage) ? (HeartbeatMessage) obj : null;
|
||||||
|
} catch (IOException | ClassNotFoundException | ClassCastException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package pitiupi.plugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import pitiupi.GUI.MainWindow;
|
||||||
|
import pitiupi.net.Message;
|
||||||
|
|
||||||
|
public class PitiupiFacade {
|
||||||
|
|
||||||
|
private final MainWindow mainWindow;
|
||||||
|
|
||||||
|
public PitiupiFacade(MainWindow mainWindow) {
|
||||||
|
this.mainWindow = mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMenu(JMenu menu) {
|
||||||
|
mainWindow.addMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(Message message) {
|
||||||
|
try {
|
||||||
|
mainWindow.getSocket().send(message.toByteArray());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.out.println("Falha ao enviar mensagem: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return mainWindow.getUserName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return mainWindow.getPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,20 +4,19 @@
|
|||||||
*/
|
*/
|
||||||
package pitiupi.plugin;
|
package pitiupi.plugin;
|
||||||
|
|
||||||
import javax.swing.JMenu;
|
|
||||||
import pitiupi.GUI.MainWindow;
|
|
||||||
import pitiupi.net.Message;
|
import pitiupi.net.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author flavio
|
* @author flavio
|
||||||
|
* @author tony
|
||||||
*/
|
*/
|
||||||
public interface Plugin {
|
public interface Plugin {
|
||||||
|
|
||||||
public String getName();
|
public String getName();
|
||||||
public String getAuthor();
|
public String getAuthor();
|
||||||
public String getVersion();
|
public String getVersion();
|
||||||
public void createPlugin(MainWindow window);
|
public void createPlugin(PitiupiFacade pitiupi);
|
||||||
public Message getMessage();
|
public Message getMessage();
|
||||||
public void receiveMessage(byte[] message);
|
public void receiveMessage(byte[] message);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user