Archived
1
0
Fork 0

Setup commands action

This commit is contained in:
Ethanell 2022-01-05 08:58:33 +01:00
parent 06bc4d5451
commit f8a5cde8bf
13 changed files with 210 additions and 116 deletions

View file

@ -1,51 +1,39 @@
package fr.univ.lyon1.client; package fr.univ.lyon1.client;
import fr.univ.lyon1.common.Channel;
import fr.univ.lyon1.common.Message; import fr.univ.lyon1.common.Message;
import fr.univ.lyon1.common.User; import fr.univ.lyon1.common.command.Command;
import fr.univ.lyon1.common.command.CommandType;
import fr.univ.lyon1.common.exception.ChatException;
import fr.univ.lyon1.common.exception.UnknownCommand;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Client { public class Client {
private final int port; private final int port;
private final String address; private final String address;
private final String username;
private final String password;
protected final Socket socket; protected final Socket socket;
protected final ObjectOutputStream out; protected final ObjectOutputStream out;
private ObjectInputStream in; private ObjectInputStream in;
private List<Channel> channels = new ArrayList<>();
protected boolean started = false; protected boolean started = false;
public Client(String address, int port, String uuid, String password) throws Exception {
public Client(String address, int port, String username, String password) throws Exception {
this.address = address; this.address = address;
this.port = port; this.port = port;
this.username = username;
this.password = password;
socket = new Socket(address, port); socket = new Socket(address, port);
out = new ObjectOutputStream(socket.getOutputStream()); out = new ObjectOutputStream(socket.getOutputStream());
while (!this.auth(uuid, password));
out.writeObject("listUsers");
out.flush();
out.writeObject("join general");
out.flush();
}
public boolean auth(String uuid, String password) throws IOException {
getIn(); getIn();
out.writeUTF(uuid);
out.flush();
out.writeUTF(password);
out.flush();
String response = in.readUTF();
System.out.println(response);
if (response.startsWith("err:"))
return false;
else if (response.equals("logged"))
return true;
else
throw new IOException("Uk message");
} }
public void disconnectedServer() throws IOException { public void disconnectedServer() throws IOException {
@ -60,7 +48,7 @@ public class Client {
public String sendMessage(String content) { public String sendMessage(String content) {
try { try {
out.writeObject(new Message(content)); out.writeObject(new Command(CommandType.message, List.of(new Message(content, channels.get(0)))));
out.flush(); out.flush();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Fail to send message !"); System.err.println("Fail to send message !");
@ -70,26 +58,51 @@ public class Client {
return content; return content;
} }
public Message messageReceived(Message msg) { public void action(Object data) throws IOException {
System.out.println(); if (data instanceof Command)
System.out.println(msg); command((Command) data);
return msg; else if (data instanceof ChatException)
((ChatException) data).printStackTrace();
else {
out.writeObject(new UnknownCommand());
out.flush();
}
} }
public void action(Object data) { private void command(Command cmd) throws IOException {
if (data instanceof Message) switch (cmd.getType()) {
messageReceived((Message) data); case login -> commandLogin();
else if (data instanceof List) { case message -> commandMessage(cmd);
List<Object> tmpList = (List<Object>) data; case list -> commandList(cmd);
if (tmpList.get(0) instanceof User) { case join -> commandJoin(cmd);
List<User> users = (List<User>) data;
for (User u : users) {
System.out.println(u);
}
}
} }
} }
private void commandLogin() throws IOException {
out.writeObject(new Command(CommandType.list, null));
out.flush();
out.writeObject(new Command(CommandType.join, List.of("general")));
out.flush();
}
protected void commandMessage(Command cmd) {
System.out.println();
System.out.println(cmd.getArgs().get(0));
}
private void commandList(Command cmd) {
List<Object> users = cmd.getArgs();
for (Object u : users) {
System.out.println(u);
}
}
private void commandJoin(Command cmd) {
Channel chan = (Channel) cmd.getArgs().get(0);
channels.add(chan);
System.out.println("You join "+chan);
}
public void run() throws InterruptedException, IOException { public void run() throws InterruptedException, IOException {
if (started) if (started)
return; return;
@ -102,6 +115,9 @@ public class Client {
started = true; started = true;
out.writeObject(new Command(CommandType.login, List.of(username, password)));
out.flush();
clientSendThread.join(); clientSendThread.join();
socket.close(); socket.close();
clientReceiveThread.interrupt(); clientReceiveThread.interrupt();

View file

@ -46,7 +46,11 @@ public class ClientReceive implements Runnable {
if (data == null) if (data == null)
break; break;
this.client.action(data); try {
this.client.action(data);
} catch (IOException e) {
e.printStackTrace();
}
} }
try { try {

View file

@ -24,9 +24,10 @@ public class Message implements Serializable {
this.content = content; this.content = content;
} }
public Message(String content) { public Message(String content, Channel channel) {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
this.content = content; this.content = content;
this.channel = channel;
} }
public Message repley(User user, String content) { public Message repley(User user, String content) {

View file

@ -0,0 +1,23 @@
package fr.univ.lyon1.common.command;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Command implements Serializable {
private final CommandType type;
private final List<Object> args;
public Command(CommandType type, List<Object> args) {
this.type = type;
this.args = args;
}
public CommandType getType() {
return type;
}
public List<Object> getArgs() {
return new ArrayList<>(args);
}
}

View file

@ -0,0 +1,27 @@
package fr.univ.lyon1.common.command;
import java.io.Serializable;
public enum CommandType implements Serializable {
login("login", "Login to the server"),
message("message", "Send a message"),
join("join", "Join a channel"),
leave("leave", "Leave a channel"),
list("list", "List all users"),
listChannels("listChannels", "List all channels");
private final String name;
private final String description;
CommandType(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
}

View file

@ -0,0 +1,7 @@
package fr.univ.lyon1.common.exception;
public class ChatException extends Exception {
public ChatException(String message) {
super(message);
}
}

View file

@ -0,0 +1,7 @@
package fr.univ.lyon1.common.exception;
public class LoginInvalid extends ChatException {
public LoginInvalid(String message) {
super(message);
}
}

View file

@ -0,0 +1,7 @@
package fr.univ.lyon1.common.exception;
public class LoginRequired extends ChatException {
public LoginRequired() {
super("Login required");
}
}

View file

@ -0,0 +1,9 @@
package fr.univ.lyon1.common.exception;
import fr.univ.lyon1.common.command.Command;
public class UnknownCommand extends ChatException {
public UnknownCommand() {
super("Command unknown");
}
}

View file

@ -2,22 +2,21 @@ package fr.univ.lyon1.gui;
import fr.univ.lyon1.client.Client; import fr.univ.lyon1.client.Client;
import fr.univ.lyon1.client.ClientReceive; import fr.univ.lyon1.client.ClientReceive;
import fr.univ.lyon1.common.Message; import fr.univ.lyon1.common.command.Command;
import java.io.IOException; import java.io.IOException;
public class ClientGUI extends Client { public class ClientGUI extends Client {
private final MainGui gui; private final MainGui gui;
public ClientGUI(MainGui gui, String address, int port) throws IOException, InterruptedException, Exception { public ClientGUI(MainGui gui, String address, int port) throws Exception {
super(address, port, null, null); super(address, port, null, null);
this.gui = gui; this.gui = gui;
} }
@Override @Override
public Message messageReceived(Message msg) { protected void commandMessage(Command cmd) {
gui.receiveMessage(msg.toString()); gui.receiveMessage(cmd.getArgs().get(0).toString());
return msg;
} }
@Override @Override

View file

@ -3,6 +3,12 @@ package fr.univ.lyon1.server;
import fr.univ.lyon1.common.Channel; import fr.univ.lyon1.common.Channel;
import fr.univ.lyon1.common.Message; import fr.univ.lyon1.common.Message;
import fr.univ.lyon1.common.User; import fr.univ.lyon1.common.User;
import fr.univ.lyon1.common.command.Command;
import fr.univ.lyon1.common.command.CommandType;
import fr.univ.lyon1.common.exception.ChatException;
import fr.univ.lyon1.common.exception.LoginInvalid;
import fr.univ.lyon1.common.exception.LoginRequired;
import fr.univ.lyon1.common.exception.UnknownCommand;
import fr.univ.lyon1.server.models.ChannelModel; import fr.univ.lyon1.server.models.ChannelModel;
import fr.univ.lyon1.server.models.UserModel; import fr.univ.lyon1.server.models.UserModel;
@ -11,6 +17,7 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.Collections;
import java.util.List; import java.util.List;
public class ConnectedClient implements Runnable { public class ConnectedClient implements Runnable {
@ -26,77 +33,67 @@ public class ConnectedClient implements Runnable {
this.server = server; this.server = server;
this.socket = socket; this.socket = socket;
this.out = new ObjectOutputStream(socket.getOutputStream()); this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
System.out.println("New user try to auth");
while (!this.auth());
}
private boolean auth() throws IOException {
if (in == null)
in = new ObjectInputStream(socket.getInputStream());
String username = in.readUTF();
System.out.println("username: "+username);
String password = in.readUTF();
System.out.println("Pass: "+password);
if (username.isEmpty() || password.isEmpty()) {
out.writeUTF("err: Login required");
out.flush();
return false;
}
UserModel user = UserModel.get(username);
if (user == null)
out.writeUTF("err: Username not found !");
else if (!user.checkPassword(password))
out.writeUTF("err: Password invalid !");
else {
out.writeUTF("logged");
out.flush();
this.user = user;
return true;
}
out.flush();
return false;
} }
public Message sendMessage(Message message) throws IOException { public Message sendMessage(Message message) throws IOException {
out.writeObject(message); out.writeObject(new Command(CommandType.message, List.of(message)));
out.flush(); out.flush();
return message; return message;
} }
private void actionMessage(Object data) throws IOException, ClassNotFoundException { private void actionCommand(Command command) throws IOException, ChatException {
Message msg = (Message) data; CommandType type = command.getType();
if (user == null && type != CommandType.login)
throw new LoginRequired();
if (msg.getContent().startsWith("/")) switch (command.getType()) {
command(msg); case login -> commandLogin(command);
else { case message -> commandMessage(command);
msg.setSender(this.user); case list -> commandList();
server.broadcastMessage(msg, id); case join -> commandJoin(command);
} }
} }
private void command(Message msg) throws IOException { private void commandLogin(Command cmd) throws IOException, ChatException {
String content = msg.getContent(); List<Object> args = cmd.getArgs();
if (content.equals("/list")) {
List<User> users = server.getUsers(); String username = (String) args.get(0);
sendMessage(msg.repley(Server.getServerUser(), "Total: "+users.toArray().length + "\n" + String.join(", ", users.stream().map(User::getUsername).toList()))); System.out.println("username: "+username);
} else if (content.startsWith("/join")) String password = (String) args.get(1);
actionJoinChannel(content); System.out.println("Pass: "+password);
if (username.isEmpty() || password.isEmpty())
throw new LoginInvalid("Invalid args");
UserModel user = UserModel.get(username);
if (user == null)
throw new LoginInvalid("Username not found");
else if (!user.checkPassword(password))
throw new LoginInvalid("Password invalid");
else {
out.writeObject(new Command(CommandType.login, null));
out.flush();
this.user = user;
System.out.println("Client "+user.getUsername()+" is connected !");
}
} }
private void actionListUsers() throws IOException { private void commandMessage(Command cmd) {
out.writeObject(server.getUsers()); Message msg = (Message) cmd.getArgs().get(0);
msg.setSender(this.user);
// ToDo: Check the user channel
server.broadcastMessage(msg, id);
}
private void commandList() throws IOException {
out.writeObject(new Command(CommandType.list, Collections.singletonList(server.getUsers())));
out.flush(); out.flush();
} }
private void actionJoinChannel(String msg) throws IOException { private void commandJoin(Command cmd) throws IOException {
String name = msg.replaceAll("^(/?join) ", ""); String name = (String) cmd.getArgs().get(0);
System.out.println(name);
ChannelModel chan = ChannelModel.get(name); ChannelModel chan = ChannelModel.get(name);
if (chan == null) { if (chan == null) {
@ -106,7 +103,7 @@ public class ConnectedClient implements Runnable {
if (!chan.have(user)) if (!chan.have(user))
chan.addUser(user); chan.addUser(user);
out.writeObject(chan); out.writeObject(new Command(CommandType.join, List.of((Channel) chan)));
out.flush(); out.flush();
server.broadcastMessage(new Message(chan, Server.getServerUser(), user.getUsername()+" joined the channel !"), -1); server.broadcastMessage(new Message(chan, Server.getServerUser(), user.getUsername()+" joined the channel !"), -1);
@ -115,19 +112,18 @@ public class ConnectedClient implements Runnable {
public void run() { public void run() {
try { try {
while (true) { while (true) {
Object data = in.readObject(); Object data = in.readObject();
if (data == null) if (data == null)
break; break;
if (data instanceof Message) try {
actionMessage(data); if (data instanceof Command)
else if (data instanceof String) { actionCommand((Command) data);
String msg = (String) data; else
if (data.equals("listUsers")) throw new UnknownCommand();
actionListUsers(); } catch (ChatException e) {
else if (((String) data).startsWith("join")) out.writeObject(e);
actionJoinChannel(msg); out.flush();
} }
} }
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {

View file

@ -23,9 +23,6 @@ public class Server {
public ConnectedClient addClient(ConnectedClient newClient) { public ConnectedClient addClient(ConnectedClient newClient) {
clients.add(newClient); clients.add(newClient);
System.out.println("Client "+newClient.getUser().getUsername()+" is connected !");
return newClient; return newClient;
} }

View file

@ -8,5 +8,6 @@ module fr.univ.lyon1.gui {
requires org.mariadb.jdbc; requires org.mariadb.jdbc;
opens fr.univ.lyon1.gui to javafx.fxml; opens fr.univ.lyon1.gui to javafx.fxml;
exports fr.univ.lyon1.common.command;
exports fr.univ.lyon1.gui; exports fr.univ.lyon1.gui;
} }