Compare commits

..

13 commits

Author SHA1 Message Date
Lorenzo Iovino
7ad9252882 last commit 2017-07-16 00:30:18 +02:00
Lorenzo Iovino
bcf684bdf6 up 2017-07-16 00:25:19 +02:00
Lorenzo Iovino
697d96b322 up 2017-07-16 00:23:40 +02:00
Lorenzo Iovino
ee230f911c up 2017-07-15 16:41:20 +02:00
Lorenzo Iovino
8eab4d97c1 up 2017-07-15 04:32:35 +02:00
Lorenzo Iovino
44a9e43cd4 up 2017-07-14 01:43:06 +02:00
Lorenzo Iovino
afbd45f51e up 2017-07-14 01:19:13 +02:00
Lorenzo Iovino
ab307b0a97 UPPPP FINISH 2017-07-14 00:46:37 +02:00
Lorenzo Iovino
e1622dfaa1 UP 2017-07-14 00:06:59 +02:00
Lorenzo Iovino
71ff3c4820 Strano ma funziona 2017-07-13 23:30:51 +02:00
Lorenzo Iovino
3305d6500b FUNZIONAAAAAHAHHA 2017-07-13 21:31:49 +02:00
Lorenzo Iovino
e1b02284b6 ora funziona 2017-07-13 15:43:42 +02:00
Lorenzo Iovino
5117b28e2c non funziona 2017-07-13 14:17:32 +02:00
51 changed files with 1528 additions and 21746 deletions

10
.idea/artifacts/Client_jar.xml generated Normal file
View file

@ -0,0 +1,10 @@
<component name="ArtifactManager">
<artifact type="jar" name="Client:jar">
<output-path>$PROJECT_DIR$/out/artifacts/Client_jar</output-path>
<root id="archive" name="Client.jar">
<element id="module-output" name="Client" />
<element id="module-output" name="Commons" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/cliftonlabs/json-simple/2.1.2/json-simple-2.1.2.jar" path-in-jar="/" />
</root>
</artifact>
</component>

14
.idea/artifacts/Server_jar.xml generated Normal file
View file

@ -0,0 +1,14 @@
<component name="ArtifactManager">
<artifact type="jar" name="Server:jar">
<output-path>$PROJECT_DIR$/out/artifacts/Server_jar</output-path>
<root id="archive" name="Server.jar">
<element id="module-output" name="Server" />
<element id="module-output" name="Commons" />
<element id="module-output" name="Client" />
<element id="library" level="application" name="jedis-2.1.0-sources" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/redis/clients/jedis/2.9.0/jedis-2.9.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/cliftonlabs/json-simple/2.1.2/json-simple-2.1.2.jar" path-in-jar="/" />
</root>
</artifact>
</component>

1651
.idea/workspace.xml generated

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.texttwist.client.Main

View file

@ -32,8 +32,8 @@ import java.rmi.server.UnicastRemoteObject;
*/ */
public class App extends JFrame { public class App extends JFrame {
private static InetSocketAddress clientTCPSocketAddress = new InetSocketAddress(Config.GameServerURI, Config.GameServerPort); private static InetSocketAddress clientTCPSocketAddress = new InetSocketAddress(Config.MessageServiceURI, Config.MessageServicePort);
public static InetSocketAddress clientUDPSocketAddress = new InetSocketAddress(Config.WordsReceiverServerURI, Config.WordsReceiverServerPort); public static InetSocketAddress clientUDPSocketAddress = new InetSocketAddress(Config.WordsReceiverServiceURI, Config.WordsReceiverServicePort);
private static InetAddress clientMulticastSocketAddress; private static InetAddress clientMulticastSocketAddress;
public static AuthService authService; public static AuthService authService;
@ -68,7 +68,7 @@ public class App extends JFrame {
logger.write("APP: Font not found!"); logger.write("APP: Font not found!");
} }
/*Services*/ /*services*/
gameService = new GameService(); gameService = new GameService();
authService = new AuthService(); authService = new AuthService();
@ -79,10 +79,10 @@ public class App extends JFrame {
public static void registerForNotifications() throws RemoteException, NotBoundException { public static void registerForNotifications() throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry(Config.NotificationServerStubPort); Registry registry = LocateRegistry.getRegistry(Config.NotificationServiceStubPort);
INotificationClient callbackObj = new NotificationClientService(); INotificationClient callbackObj = new NotificationClientService();
notificationStub = (INotificationClient) UnicastRemoteObject.exportObject(callbackObj, 0); notificationStub = (INotificationClient) UnicastRemoteObject.exportObject(callbackObj, 0);
INotificationServer notificationServer = (INotificationServer) registry.lookup(Config.NotificationServerName); INotificationServer notificationServer = (INotificationServer) registry.lookup(Config.NotificationServiceName);
notificationServer.registerForCallback(notificationStub); notificationServer.registerForCallback(notificationStub);
} }
@ -98,7 +98,7 @@ public class App extends JFrame {
public static void openClientMulticastSocket(Integer multicastId){ public static void openClientMulticastSocket(Integer multicastId){
try { try {
App.gameService.setMulticastId(multicastId); App.gameService.setMulticastId(multicastId);
clientMulticastSocketAddress = InetAddress.getByName(Config.ScoreMulticastServerURI); clientMulticastSocketAddress = InetAddress.getByName(Config.ScoreMulticastServiceURI);
clientMulticast = new MulticastSocket(gameService.multicastId); clientMulticast = new MulticastSocket(gameService.multicastId);
clientMulticast.joinGroup(clientMulticastSocketAddress); clientMulticast.joinGroup(clientMulticastSocketAddress);
} catch (IOException e) { } catch (IOException e) {
@ -109,7 +109,7 @@ public class App extends JFrame {
public static void closeClientMulticastSocket(){ public static void closeClientMulticastSocket(){
//Leave group and close multicast socket //Leave group and close multicast socket
try { try {
App.clientMulticast.leaveGroup(InetAddress.getByName(Config.ScoreMulticastServerURI)); App.clientMulticast.leaveGroup(InetAddress.getByName(Config.ScoreMulticastServiceURI));
App.clientMulticast.close(); App.clientMulticast.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -18,6 +18,11 @@ public class HomeController {
public Response login(String userName, String password) throws RemoteException, NotBoundException, MalformedURLException { public Response login(String userName, String password) throws RemoteException, NotBoundException, MalformedURLException {
Response res = authService.login(userName,password); Response res = authService.login(userName,password);
if (res.code == 200){ if (res.code == 200){
try {
App.registerForNotifications();
} catch (RemoteException e) {
App.logger.write("AUTH SERVICE: Can't register for notification");
}
App.session = (new Session(new User(userName,password,0), res.data.get("token").toString())); App.session = (new Session(new User(userName,password,0), res.data.get("token").toString()));
} }
return res; return res;

View file

@ -1,6 +1,8 @@
package com.texttwist.client.controllers; package com.texttwist.client.controllers;
import com.texttwist.client.App; import com.texttwist.client.App;
import com.texttwist.client.tasks.JoinMatch;
import javax.swing.*; import javax.swing.*;
/** /**
@ -14,6 +16,6 @@ public class MatchRequestController {
} }
public void joinMatch(String matchName){ public void joinMatch(String matchName){
App.gameService.joinMatch(matchName); new JoinMatch(matchName).execute();
} }
} }

View file

@ -1,5 +1,7 @@
package com.texttwist.client.controllers; package com.texttwist.client.controllers;
import com.texttwist.client.tasks.InvitePlayers;
import javax.swing.*; import javax.swing.*;
import static com.texttwist.client.App.gameService; import static com.texttwist.client.App.gameService;
@ -10,6 +12,7 @@ import static com.texttwist.client.App.gameService;
public class MatchSetupController { public class MatchSetupController {
public void play(DefaultListModel<String> userNames) { public void play(DefaultListModel<String> userNames) {
gameService.beginMatch(userNames); new InvitePlayers(userNames).execute();
} }
} }

View file

@ -58,7 +58,7 @@ public class MatchSetupPage extends Page{
new Callable<Object>() { new Callable<Object>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
//If notificationServer response ok, start beginMatch, else error //If notificationServer response ok, start newMatch, else error
matchSetupController.play(searchUserBar.list); matchSetupController.play(searchUserBar.list);
return null; return null;
} }

View file

@ -17,14 +17,9 @@ import java.rmi.RemoteException;
*/ */
public class AuthService { public class AuthService {
private String baseUrl = Config.getAuthServerURI().concat("/auth"); private String baseUrl = Config.getAuthServiceURI().concat("/auth");
public Response login(String userName, String password) throws RemoteException, NotBoundException, MalformedURLException { public Response login(String userName, String password) throws RemoteException, NotBoundException, MalformedURLException {
try {
App.registerForNotifications();
} catch (RemoteException e) {
App.logger.write("AUTH SERVICE: Can't register for notification");
}
IAuth auth = (IAuth) Naming.lookup(baseUrl); IAuth auth = (IAuth) Naming.lookup(baseUrl);
return auth.login(userName, password); return auth.login(userName, password);
} }

View file

@ -5,6 +5,7 @@ import com.texttwist.client.pages.GamePage;
import com.texttwist.client.pages.MenuPage; import com.texttwist.client.pages.MenuPage;
import com.texttwist.client.pages.Page; import com.texttwist.client.pages.Page;
import com.texttwist.client.tasks.InvitePlayers; import com.texttwist.client.tasks.InvitePlayers;
import com.texttwist.client.tasks.JoinMatch;
import com.texttwist.client.ui.TTDialog; import com.texttwist.client.ui.TTDialog;
import javafx.util.Pair; import javafx.util.Pair;
import models.Message; import models.Message;
@ -26,9 +27,10 @@ public class GameService {
public DefaultListModel<String> letters = new DefaultListModel<>(); public DefaultListModel<String> letters = new DefaultListModel<>();
public DefaultListModel<Pair<String,Integer>> globalRanks = new DefaultListModel<>(); public DefaultListModel<Pair<String,Integer>> globalRanks = new DefaultListModel<>();
public DefaultListModel<Pair<String,Integer>> ranks = new DefaultListModel<>(); public DefaultListModel<Pair<String,Integer>> ranks = new DefaultListModel<>();
private Boolean gameIsStarted = false; public Boolean gameIsStarted = false;
public Boolean isWaiting = false;
private void addToPendingList(String username) throws IOException { public void addToPendingList(String username) throws IOException {
pendingList.addElement(username); pendingList.addElement(username);
} }
@ -36,33 +38,6 @@ public class GameService {
App.openClientTCPSocket(); App.openClientTCPSocket();
} }
public void newMatch(String userName) {
//Add to pending invites list
try {
this.addToPendingList(userName);
} catch (IOException e) {
e.printStackTrace();
}
if(!App.gameService.gameIsStarted) {
//Show invite popup
new TTDialog("success", "New invite from: " + userName + "!",
new Callable() {
@Override
public Object call() throws Exception {
App.gameService.joinMatch(userName);
return null;
}
},
new Callable() {
@Override
public Object call() throws Exception {
return new MenuPage(Page.window);
}
});
}
}
public DefaultListModel<String> getLetters(){ public DefaultListModel<String> getLetters(){
return App.gameService.letters; return App.gameService.letters;
} }
@ -75,32 +50,6 @@ public class GameService {
this.letters = letters; this.letters = letters;
} }
public void joinMatch(String matchName) {
//Clear pending invitation list and join selected match
if(!gameIsStarted) {
this.pendingList.clear();
try {
DefaultListModel<String> matchNames = new DefaultListModel<>();
matchNames.addElement(matchName);
Message message = new Message("JOIN_GAME", App.session.account.userName, App.session.token, matchNames);
byte[] byteMessage = message.toString().getBytes();
ByteBuffer buffer = ByteBuffer.wrap(byteMessage);
App.clientTCP.write(buffer);
new GamePage(Page.window);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Start game and wait for other players
public void beginMatch(DefaultListModel<String> userNames) {
new InvitePlayers(userNames).execute();
}
public void start(){ public void start(){
gameIsStarted = true; gameIsStarted = true;
} }

View file

@ -1,6 +1,7 @@
package com.texttwist.client.services; package com.texttwist.client.services;
import com.texttwist.client.App; import com.texttwist.client.App;
import com.texttwist.client.tasks.BeginMatch;
import interfaces.INotificationClient; import interfaces.INotificationClient;
import javax.swing.*; import javax.swing.*;
import java.rmi.RemoteException; import java.rmi.RemoteException;
@ -18,7 +19,7 @@ public class NotificationClientService implements INotificationClient {
if(App.session != null) { if(App.session != null) {
if (users.contains(App.session.account.userName)) { if (users.contains(App.session.account.userName)) {
App.logger.write(userName + " send a invitation!"); App.logger.write(userName + " send a invitation!");
App.gameService.newMatch(userName); new BeginMatch(userName).execute();
} else { } else {
App.logger.write("User " + userName + " is slogged"); App.logger.write("User " + userName + " is slogged");
} }

View file

@ -0,0 +1,52 @@
package com.texttwist.client.tasks;
import com.texttwist.client.App;
import com.texttwist.client.pages.MenuPage;
import com.texttwist.client.pages.Page;
import com.texttwist.client.ui.TTDialog;
import javax.swing.*;
import java.io.IOException;
import java.util.concurrent.Callable;
/**
* Author: Lorenzo Iovino on 15/07/2017.
* Description: Task: BeginMatch
*
*/
public class BeginMatch extends SwingWorker<Void,Void> {
private String userName;
public BeginMatch(String userName) {
this.userName = userName;
}
@Override
public Void doInBackground() {
//Add to pending invites list
try {
App.gameService.addToPendingList(userName);
} catch (IOException e) {
e.printStackTrace();
}
if(!App.gameService.gameIsStarted && !App.gameService.isWaiting) {
//Show invite popup
new TTDialog("success", "New invite from: " + userName + "!",
new Callable() {
@Override
public Object call() throws Exception {
new JoinMatch(userName).execute();
return null;
}
},
new Callable() {
@Override
public Object call() throws Exception {
return new MenuPage(Page.window);
}
});
}
return null;
}
}

View file

@ -0,0 +1,47 @@
package com.texttwist.client.tasks;
import com.texttwist.client.App;
import com.texttwist.client.pages.GamePage;
import com.texttwist.client.pages.Page;
import models.Message;
import javax.swing.*;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Author: Lorenzo Iovino on 25/06/2017.
* Description: Task: JoinMatch
*
*/
public class JoinMatch extends SwingWorker<Void,Void> {
private String matchName;
public JoinMatch(String matchName) {
this.matchName = matchName;
}
@Override
public Void doInBackground() {
//Clear pending invitation list and join selected match
if(!App.gameService.gameIsStarted) {
App.gameService.pendingList.clear();
try {
DefaultListModel<String> matchNames = new DefaultListModel<>();
matchNames.addElement(matchName);
Message message = new Message("JOIN_GAME", App.session.account.userName, App.session.token, matchNames);
byte[] byteMessage = message.toString().getBytes();
ByteBuffer buffer = ByteBuffer.wrap(byteMessage);
App.clientTCP.write(buffer);
new GamePage(Page.window);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

View file

@ -36,8 +36,6 @@ public class SendWords extends SwingWorker<Void,Void> {
buffer.flip(); buffer.flip();
App.clientUDP.send(buffer, App.clientUDPSocketAddress); App.clientUDP.send(buffer, App.clientUDPSocketAddress);
return null;
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
App.logger.write("SEND WORDS: Host address not correct"); App.logger.write("SEND WORDS: Host address not correct");
} catch (IOException e) { } catch (IOException e) {

View file

@ -28,6 +28,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
@Override @Override
public Void doInBackground() { public Void doInBackground() {
try { try {
App.gameService.isWaiting = true;
ByteBuffer buffer = ByteBuffer.allocate(1024); ByteBuffer buffer = ByteBuffer.allocate(1024);
TTDialog loading = new TTDialog("alert", "Waiting for users joins",null,null); TTDialog loading = new TTDialog("alert", "Waiting for users joins",null,null);
buffer.flip(); buffer.flip();
@ -42,6 +43,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
Message msg = Message.toMessage(line); Message msg = Message.toMessage(line);
if (msg.message.equals("JOIN_TIMEOUT")) { if (msg.message.equals("JOIN_TIMEOUT")) {
loading.dispose(); loading.dispose();
App.gameService.isWaiting = false;
joinTimeout = true; joinTimeout = true;
new TTDialog("alert", "TIMEOUT!", new TTDialog("alert", "TIMEOUT!",
@ -58,6 +60,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
if (msg.message.equals("MATCH_NOT_AVAILABLE")) { if (msg.message.equals("MATCH_NOT_AVAILABLE")) {
loading.dispose(); loading.dispose();
joinTimeout = true; joinTimeout = true;
App.gameService.isWaiting = false;
new TTDialog("alert", "THE GAME IS NOT MORE AVAILABLE!", new TTDialog("alert", "THE GAME IS NOT MORE AVAILABLE!",
new Callable() { new Callable() {
@ -72,9 +75,11 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
if (msg.message.equals("GAME_STARTED")) { if (msg.message.equals("GAME_STARTED")) {
loading.dispose(); loading.dispose();
App.gameService.isWaiting = false;
if(msg.data !=null ) { if(msg.data !=null ) {
DefaultListModel<String> data = msg.data; DefaultListModel<String> data = msg.data;
App.openClientMulticastSocket(Integer.valueOf(data.remove(data.size()-2))); App.openClientMulticastSocket(Integer.valueOf(data.remove(data.size()-2)));
App.gameService.setLetters(msg.data); App.gameService.setLetters(msg.data);
break; break;

View file

@ -6,29 +6,29 @@ package constants;
*/ */
public class Config { public class Config {
public static String AuthServerURI = "localhost"; public static String AuthServiceURI = "localhost";
public static Integer AuthServerPort = 9999; public static Integer AuthServicePort = 9999;
public static String GameServerURI = "localhost"; public static String MessageServiceURI = "localhost";
public static Integer GameServerPort = 10000; public static Integer MessageServicePort = 10000;
public static String WordsReceiverServerURI = "localhost"; public static String WordsReceiverServiceURI = "localhost";
public static Integer WordsReceiverServerPort = 10001; public static Integer WordsReceiverServicePort = 10001;
public static String ScoreMulticastServerURI = "226.226.226.226"; public static String ScoreMulticastServiceURI = "226.226.226.226";
public static Integer NotificationServerPort = 20000; public static Integer NotificationServicePort = 20000;
public static Integer NotificationServerStubPort = 30000; public static Integer NotificationServiceStubPort = 30000;
public static String NotificationServerName ="notification"; public static String NotificationServiceName ="notification";
public static String RedisServerURI = "localhost"; public static String RedisServiceURI = "localhost";
public static int gameTimeout = 10; //2 minuti in sec public static int gameTimeout = 120; //2 minuti in sec
public static int joinMatchTimeout = 5000; //7 minuti in millisec public static int joinMatchTimeout = 7*1000*60; //7 minuti in millisec
public static int sendWordsTimeout = 3000; //5 minuti in millisec public static int sendWordsTimeout = 5*1000*60; //5 minuti in millisec
public static String getAuthServerURI(){ public static String getAuthServiceURI(){
return "rmi://".concat(AuthServerURI).concat(":").concat(AuthServerPort.toString()); return "rmi://".concat(AuthServiceURI).concat(":").concat(AuthServicePort.toString());
} }
} }

View file

@ -1,5 +1,6 @@
package interfaces; package interfaces;
import javax.swing.*;
import java.rmi.Remote; import java.rmi.Remote;
import java.rmi.RemoteException; import java.rmi.RemoteException;
@ -9,5 +10,6 @@ import java.rmi.RemoteException;
*/ */
public interface INotificationServer extends Remote { public interface INotificationServer extends Remote {
void registerForCallback (INotificationClient ClientInterface) throws RemoteException; void registerForCallback (INotificationClient ClientInterface) throws RemoteException;
void unregisterForCallback (INotificationClient ClientInterface) throws RemoteException; void unregisterForCallback (INotificationClient ClientInterface) throws RemoteException;
void sendInvitations(String username, DefaultListModel<String> users) throws RemoteException;
} }

View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.texttwist.server.Main

View file

@ -1,5 +1,4 @@
package com.texttwist.server; package com.texttwist.server;
import java.io.IOException; import java.io.IOException;
/** /**

View file

@ -1,8 +1,10 @@
package com.texttwist.server; package com.texttwist.server;
import com.texttwist.server.models.Dictionary;
import com.texttwist.server.services.AuthService; import com.texttwist.server.services.AuthService;
import com.texttwist.server.services.MessageService; import com.texttwist.server.services.MessageService;
import com.texttwist.server.services.NotificationService; import com.texttwist.server.services.NotificationService;
import com.texttwist.server.services.ReceiveWordsService;
import constants.Config; import constants.Config;
import interfaces.INotificationServer; import interfaces.INotificationServer;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
@ -26,22 +28,29 @@ public class Server {
public static JedisPool jedisPool; public static JedisPool jedisPool;
public static Logger logger; public static Logger logger;
public static AuthService auth; public static AuthService auth;
private String dictionaryPath = "./Server/resources/dictionary";
public static Dictionary dict;
public static Integer multicastId = Config.NotificationServiceStubPort;
public Server() throws IOException { public Server() throws IOException {
logger = new Logger(new File("./notificationServer.log"), "Server", true); logger = new Logger(new File("./server.log"), "Server", true);
Server.logger.write("Services starting ..."); Server.logger.write("Services starting ...");
startAuthService(); startAuthService();
startJedisService(); startJedisService();
startMessageService(); startMessageService();
startWordsReceiverService();
startNotificationService(); startNotificationService();
dict = new Dictionary(dictionaryPath);
Server.logger.write("Services started correctly ..."); Server.logger.write("Services started correctly ...");
} }
private void startAuthService(){ private void startAuthService(){
//Starting AuthService service based on RMI //Starting Auth service based on RMI
try { try {
auth = new AuthService(Config.AuthServerPort); auth = new AuthService();
Registry authRegistry = LocateRegistry.createRegistry(auth.serverPort); Registry authRegistry = LocateRegistry.createRegistry(Config.AuthServicePort);
authRegistry.bind("auth", auth); authRegistry.bind("auth", auth);
} catch (RemoteException e) { } catch (RemoteException e) {
Server.logger.write("SERVER: RMI authentication service error (Remote exception)"); Server.logger.write("SERVER: RMI authentication service error (Remote exception)");
@ -52,27 +61,32 @@ public class Server {
private void startJedisService(){ private void startJedisService(){
//Starting Jedis pool for Redis connection //Starting Jedis pool for Redis connection
jedisPool = new JedisPool(new JedisPoolConfig(), Config.RedisServerURI); jedisPool = new JedisPool(new JedisPoolConfig(), Config.RedisServiceURI);
} }
private void startMessageService(){ private void startMessageService(){
//Starting the Message service based on TCP //Starting the Message service based on TCP
new Thread(new MessageService(Config.GameServerPort)).start(); new Thread(new MessageService()).start();
}
private void startWordsReceiverService(){
//Starting the Receive Words service based on UDP
new Thread(new ReceiveWordsService()).start();
} }
private void startNotificationService(){ private void startNotificationService(){
//Starting Notification service based on RMI //Starting Notification service based on RMI
try { try {
notificationServer = new NotificationService(); notificationServer = new NotificationService();
INotificationServer stub = (INotificationServer) UnicastRemoteObject.exportObject(notificationServer, Config.NotificationServerPort); INotificationServer stub = (INotificationServer) UnicastRemoteObject.exportObject(notificationServer, Config.NotificationServicePort);
LocateRegistry.createRegistry(Config.NotificationServerStubPort); LocateRegistry.createRegistry(Config.NotificationServiceStubPort);
Registry notificationRegistry = LocateRegistry.getRegistry(Config.NotificationServerStubPort); Registry notificationRegistry = LocateRegistry.getRegistry(Config.NotificationServiceStubPort);
notificationRegistry.bind(Config.NotificationServerName, stub); notificationRegistry.bind(Config.NotificationServiceName, stub);
} catch (RemoteException e) { } catch (RemoteException e) {
Server.logger.write("SERVER: RMI notification service error (Remote exception)"); Server.logger.write("SERVER: RMI notification service error (Remote exception)");
} catch (AlreadyBoundException e) { } catch (AlreadyBoundException e) {
Server.logger.write("SERVER: RMI notification service can't use this port because is busy "); Server.logger.write("SERVER: RMI notification service can't use this port because is busy ");
} }
} }
} }

View file

@ -1,26 +1,28 @@
package com.texttwist.server.services; package com.texttwist.server.models;
import com.texttwist.server.services.JedisService;
import models.User; import models.User;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
/** /**
* Created by loke on 18/06/2017. * Author: Lorenzo Iovino on 18/06/2017.
* Description: Accounts
*/ */
public class AccountsService { public class Accounts {
public List<User> users = Collections.synchronizedList(new ArrayList<User>()); public List<User> users = Collections.synchronizedList(new ArrayList<User>());
private static class Holder { private static class Holder {
static final AccountsService INSTANCE = new AccountsService(); static final Accounts INSTANCE = new Accounts();
} }
public static AccountsService getInstance() { public static Accounts getInstance() {
return AccountsService.Holder.INSTANCE; return Accounts.Holder.INSTANCE;
} }
private AccountsService(){ private Accounts(){
List<Serializable> l = JedisService.get("users"); List<Serializable> l = JedisService.get("users");
for(int i=0; i<l.size(); i++) { for(int i=0; i<l.size(); i++) {
users.add((User) l.get(i)); users.add((User) l.get(i));
@ -71,9 +73,4 @@ public class AccountsService {
} }
return null; return null;
} }
public int size(){
return users.size();
}
} }

View file

@ -1,23 +1,19 @@
package com.texttwist.server.models; package com.texttwist.server.models;
import com.texttwist.server.Server;
import javax.swing.*; import javax.swing.*;
import java.io.*; import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Random; import java.util.Random;
import java.util.stream.Stream;
/** /**
* Created by loke on 26/06/2017. * Author: Lorenzo Iovino on 26/06/2017.
* Description: Dictionary Model. Provides the dictionary and methods for manage it
*/ */
public class Dictionary { public class Dictionary {
static DefaultListModel<String> wordList = new DefaultListModel<>(); private static DefaultListModel<String> wordList = new DefaultListModel<>();
private Random randomGenerator;
public Dictionary(String dictionaryPath) { public Dictionary(String dictionaryPath) {
try (BufferedReader br = new BufferedReader(new FileReader(new File(dictionaryPath)))) { try (BufferedReader br = new BufferedReader(new FileReader(new File(dictionaryPath)))) {
@ -25,15 +21,16 @@ public class Dictionary {
wordList.addElement(line); wordList.addElement(line);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); Server.logger.write("DICTIONARY: Dictionary file not found!");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Server.logger.write("DICTIONARY: Can't read dictionary file!");
} }
} }
//Get a random word in wordsList with minimumWordSize < size < maximumWordSize
public String getRandomWord(int minimumWordSize, int maximumWordSize){ public String getRandomWord(int minimumWordSize, int maximumWordSize){
randomGenerator = new Random(); Random randomGenerator = new Random();
int index = randomGenerator.nextInt(wordList.size()); int index = randomGenerator.nextInt(wordList.size());
String word = wordList.get(index); String word = wordList.get(index);
if(word.length() >= minimumWordSize && word.length() <= maximumWordSize) { if(word.length() >= minimumWordSize && word.length() <= maximumWordSize) {
@ -55,6 +52,7 @@ public class Dictionary {
} }
} }
//Check if a word is contained in dictionary
public static Boolean isContainedInDictionary(String word){ public static Boolean isContainedInDictionary(String word){
if(word.equals("")){ if(word.equals("")){
return true; return true;
@ -66,5 +64,4 @@ public class Dictionary {
} }
return false; return false;
} }
} }

View file

@ -1,39 +1,59 @@
package com.texttwist.server.models; package com.texttwist.server.models;
import com.texttwist.server.Server;
import com.texttwist.server.services.MessageService; import com.texttwist.server.services.MessageService;
import com.texttwist.server.tasks.MatchTimeout; import com.texttwist.server.tasks.TimeoutMatch;
import constants.Config;
import javafx.util.Pair; import javafx.util.Pair;
import models.Message;
import javax.swing.*; import javax.swing.*;
import java.io.IOException;
import java.net.*;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.*; import java.util.*;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import static com.texttwist.server.services.MessageService.activeMatches;
/** /**
* Created by loke on 23/06/2017. * Author: Lorenzo Iovino on 23/06/2017.
* Description: Match Model. Methods for manage the matches and model of single match.
* Single point of concurrent access.
*/ */
public class Match { public class Match {
public final List<Pair<String,Integer>> playersStatus = Collections.synchronizedList(new ArrayList<>()); //Usare Liste!!!!!!!
public final List<Pair<String,SocketChannel>> playersSocket = Collections.synchronizedList(new ArrayList<>());
private boolean started = false;
public final String matchCreator;
public Integer multicastId;
public Future<Boolean> timeout;
public boolean matchTimeout = true;
public boolean joinTimeout =true;
public DefaultListModel<String> letters;
protected ExecutorService threadPool = Executors.newSingleThreadExecutor();
/****GLOBAL AREA OF ALL MATCHES****/
//Players status: A list of pair where elements are <playerName, status>.
// status is 0 if user is not currently in a match, and 1 otherwise
public final List<Pair<String,Integer>> playersStatus = Collections.synchronizedList(new ArrayList<>());
//Players socket: A list of pair where elements are <playerName, socketChannel>.
// socketChannel is the TCP socket associated with client for messages exchange
public final List<Pair<String,SocketChannel>> playersSocket = Collections.synchronizedList(new ArrayList<>());
//Players score: A list of pair where elements are <playerName, score>.
public final List<Pair<String,Integer>> playersScore = Collections.synchronizedList(new ArrayList<>()); public final List<Pair<String,Integer>> playersScore = Collections.synchronizedList(new ArrayList<>());
//Players score: A list of active matches.
public static List<Match> activeMatches = Collections.synchronizedList(new ArrayList<>());
/****SINGLE INSTANCE OF MATCH****/
//If match is started
private boolean started = false;
//Name of the creator of the match
public final String matchCreator;
//MulticastID associated with this match
public Integer multicastId;
//True if happen timeout, false otherwise
public boolean matchTimeout = false;
public boolean joinTimeout = false;
//Letters of the match
public DefaultListModel<String> letters;
private ExecutorService matchTimeoutThread = Executors.newSingleThreadExecutor();
public Match(String matchCreator, DefaultListModel<String> players){ public Match(String matchCreator, DefaultListModel<String> players){
for (int i =0; i < players.size(); i++){ for (int i =0; i < players.size(); i++){
this.playersStatus.add(new Pair<>(players.get(i), 0)); this.playersStatus.add(new Pair<>(players.get(i), 0));
@ -43,119 +63,86 @@ public class Match {
this.multicastId = this.generateMulticastId(); this.multicastId = this.generateMulticastId();
this.matchCreator = matchCreator; this.matchCreator = matchCreator;
} }
public Void sendScores(){
while (true) {
System.out.println("SENDING");
Message msg = new Message("FINALSCORE", "SERVER", "", this.getMatchPlayersScoreAsStringList());
MulticastSocket multicastSocket = null;
try {
multicastSocket = new MulticastSocket(this.multicastId);
InetAddress ia = null;
ia = InetAddress.getByName(Config.ScoreMulticastServerURI);
DatagramPacket hi = new DatagramPacket(msg.toString().getBytes(), msg.toString().length(), ia, this.multicastId);
multicastSocket.send(hi);
} catch (IOException e) {
e.printStackTrace();
}
activeMatches.remove(Match.findMatchIndex(activeMatches, this.matchCreator));
}
}
public static Match findMatch(List<Match> matches, String matchName){ public static Match findMatch(List<Match> matches, String matchName){
for (int i = 0; i < matches.size(); i++) { for (Match match : matches) {
if (matches.get(i).matchCreator.equals(matchName)) { if (match.matchCreator.equals(matchName)) {
return matches.get(i); return match;
} }
} }
return null; return null;
} }
public void printAll(){
for (int i = 0; i < playersScore.size(); i++) {
System.out.println(playersScore.get(i).getKey() + " : " +playersScore.get(i).getValue());
}
}
public static int findMatchIndex(List<Match> matches, String matchName){ public static int findMatchIndex(List<Match> matches, String matchName){
for (int i = 0; i < matches.size(); i++) { for (int i = 0; i < matches.size(); i++) {
if (matches.get(i).matchCreator.equals(matchName)) { if (matches.get(i).matchCreator.equals(matchName)) {
return i; return i;
}
} }
return -1; }
return -1;
} }
public boolean isStarted(){ public boolean isStarted(){
return started; return started;
} }
public static Match findMatchByPlayer(String player){ public static Match findMatchByPlayerName(String player){
for (int i = 0; i < activeMatches.size(); i++) { for (Match activeMatch : activeMatches) {
for (int j = 0; j < activeMatches.get(i).playersStatus.size(); j++) { for (int j = 0; j < activeMatch.playersStatus.size(); j++) {
if (activeMatches.get(i).playersStatus.get(j).getKey().equals(player)) { if (activeMatch.playersStatus.get(j).getKey().equals(player)) {
return activeMatches.get(i); return activeMatch;
} }
} }
/* if (matches.get(i).matchCreator.equals(matchName)) {
return i;
}*/
} }
return null; return null;
} }
public void startGame(){ public void startGame(){
this.started=true; this.started = true;
threadPool.submit(new MatchTimeout(this)); matchTimeoutThread.submit(new TimeoutMatch(this));
} }
public void setScore(String player, Integer score){ public void setScore(String player, Integer score){
Match m = findMatchByPlayer(player); Match m = findMatchByPlayerName(player);
m.printAll(); if(m!=null) {
for (int i = 0; i < m.playersScore.size(); i++) {
for (int i = 0; i < m.playersScore.size(); i++) { if (m.playersScore.get(i).getKey().equals(player)) {
if (m.playersScore.get(i).getKey().equals(player)) { m.playersScore.set(i, new Pair<>(player, score));
m.playersScore.set(i, new Pair<String, Integer>(player, score)); }
} }
} }
} }
public Boolean allPlayersSendedHisScore(){ public Boolean allPlayersSendedHisScore(){
System.out.println(matchCreator); for (Pair<String, Integer> player : playersScore) {
printAll(); if (player.getValue() == -1) {
for (int i = 0; i < playersScore.size(); i++) { return false;
if (playersScore.get(i).getValue() == -1) {
return false;
}
} }
return true; }
return true;
} }
public void setUndefinedScorePlayersToZero(){ public void setUndefinedScorePlayersToZero(){
for (int i = 0; i < playersScore.size(); i++) { for (int i = 0; i < playersScore.size(); i++) {
if (playersScore.get(i).getValue() == -1) { if (playersScore.get(i).getValue() == -1) {
playersScore.set(i, new Pair<String, Integer>(playersScore.get(i).getKey(), 0)); playersScore.set(i, new Pair<>(playersScore.get(i).getKey(), 0));
}
} }
}
} }
public DefaultListModel<String> getMatchPlayersScoreAsStringList(){ public DefaultListModel<String> getMatchPlayersScoreAsStringList(){
DefaultListModel<String> l = new DefaultListModel<>(); DefaultListModel<String> l = new DefaultListModel<>();
for (int i = 0; i < playersScore.size(); i++) { for (Pair<String, Integer> player : playersScore) {
l.addElement(playersScore.get(i).getKey() + ":" + playersScore.get(i).getValue()); l.addElement(player.getKey() + ":" + player.getValue());
} }
return l; return l;
} }
private int generateMulticastId(){ private int generateMulticastId(){
return MessageService.multicastID++; return Server.multicastId++;
} }
public void setLetters(DefaultListModel<String> letters){ public void setLetters(DefaultListModel<String> letters){
this.letters = letters; this.letters = letters;
} }

View file

@ -0,0 +1,68 @@
package com.texttwist.server.models;
import models.Session;
import models.User;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Author: Lorenzo Iovino on 17/06/2017.
* Description: Sessions. It is a singleton that provides the model and methods for manage sessions
*/
public class Sessions {
private List<Session> sessions = Collections.synchronizedList(new ArrayList<Session>());
private static class Holder {
static final Sessions INSTANCE = new Sessions();
}
public static Sessions getInstance() {
return Holder.INSTANCE;
}
private Session getSession(String userName) {
for (Session elem : sessions) {
if (elem.account.userName.equals(userName)) {
return elem;
}
}
return null;
}
public boolean add(String userName, String token) {
remove(userName);
return sessions.add(new Session(new User(userName,"",0), token));
}
public boolean remove(String userName){
if(exists(userName)) {
Session s = getSession(userName);
if(s != null) {
sessions.remove(s);
return true;
}
}
return false;
}
public boolean exists(String userName) {
for (Session elem : sessions) {
if (elem.account.userName.equals(userName)) {
return true;
}
}
return false;
}
public boolean isValidToken(String token) {
for (Session session : sessions) {
if (session.token.equals(token)) {
return true;
}
}
return false;
}
}

View file

@ -1,6 +1,9 @@
package com.texttwist.server.services; package com.texttwist.server.services;
import com.texttwist.server.Server; import com.texttwist.server.Server;
import com.texttwist.server.models.Accounts;
import com.texttwist.server.models.Sessions;
import constants.Config;
import interfaces.IAuth; import interfaces.IAuth;
import interfaces.INotificationClient; import interfaces.INotificationClient;
import models.Response; import models.Response;
@ -13,24 +16,22 @@ import java.security.SecureRandom;
import static com.texttwist.server.Server.notificationServer; import static com.texttwist.server.Server.notificationServer;
/** /**
* Created by loke on 15/06/2017. * Author: Lorenzo Iovino on 15/06/2017.
* Description: AuthService
*/ */
public class AuthService extends UnicastRemoteObject implements IAuth { public class AuthService extends UnicastRemoteObject implements IAuth {
private SecureRandom random = new SecureRandom(); private SecureRandom random = new SecureRandom();
public int serverPort = 9999;
public AuthService() throws RemoteException{
public AuthService(int serverPort) throws RemoteException{ Server.logger.write("AuthService Service running at "+ Config.AuthServicePort +" port...");
this.serverPort=serverPort;
Server.logger.write("AuthService Service running at "+serverPort+" port...");
} }
@Override @Override
public Response register(String userName, String password) throws RemoteException { public Response register(String userName, String password) throws RemoteException {
Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password); Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password);
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) { if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
if(AccountsService.getInstance().register(userName, password)){ if(Accounts.getInstance().register(userName, password)){
Server.logger.write("Registration successfull"); Server.logger.write("Registration successfull");
return new Response("Registration successfull", 200, null); return new Response("Registration successfull", 200, null);
} else { } else {
@ -45,11 +46,11 @@ public class AuthService extends UnicastRemoteObject implements IAuth {
public Response login(String userName, String password) throws RemoteException { public Response login(String userName, String password) throws RemoteException {
Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password); Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password);
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) { if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
if(AccountsService.getInstance().exists(userName) && AccountsService.getInstance().checkPassword(userName, password)) { if(Accounts.getInstance().exists(userName) && Accounts.getInstance().checkPassword(userName, password)) {
JsonObject data = new JsonObject(); JsonObject data = new JsonObject();
String token = nextSessionId(); String token = nextSessionId();
data.put("token", token); data.put("token", token);
SessionsService.getInstance().add(userName,token); Sessions.getInstance().add(userName,token);
Server.logger.write("Login successfull"); Server.logger.write("Login successfull");
return new Response("Login successfull", 200, data); return new Response("Login successfull", 200, data);
} }
@ -64,14 +65,14 @@ public class AuthService extends UnicastRemoteObject implements IAuth {
notificationServer.unregisterForCallback(stub); notificationServer.unregisterForCallback(stub);
if ((userName != null && !userName.isEmpty()) && (token != null && !token.isEmpty())) { if ((userName != null && !userName.isEmpty()) && (token != null && !token.isEmpty())) {
boolean res = SessionsService.getInstance().remove(userName); boolean res = Sessions.getInstance().remove(userName);
if(res) { if(res) {
Server.logger.write("Logout successfull"); Server.logger.write("Logout successfull");
} }
} }
SessionsService.getInstance().remove(userName); Sessions.getInstance().remove(userName);
Server.logger.write("Logout successfull (but something gone wrong)"); Server.logger.write("Logout successfull (but something gone wrong)");
return new Response("Logout successfull (but something gone wrong)", 200, null); return new Response("Logout successfull (but something gone wrong)", 200, null);
} }

View file

@ -1,5 +1,6 @@
package com.texttwist.server.services; package com.texttwist.server.services;
import com.texttwist.server.Server;
import models.User; import models.User;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
@ -11,12 +12,14 @@ import java.util.List;
import static com.texttwist.server.Server.jedisPool; import static com.texttwist.server.Server.jedisPool;
/** /**
* Created by loke on 11/07/2017. * Author: Lorenzo Iovino on 11/07/2017.
* Description: Jedis Service
*/ */
public class JedisService { public class JedisService {
public JedisService(){
JedisService(){
Server.logger.write("Jedis Service running on localhost...");
} }
/** Read the object from Base64 string. */ /** Read the object from Base64 string. */
@ -56,11 +59,8 @@ public class JedisService {
Jedis jedis = null; Jedis jedis = null;
List<Serializable> l = new ArrayList<>(); List<Serializable> l = new ArrayList<>();
try { try {
System.out.println("USER ss");
jedis = jedisPool.getResource(); jedis = jedisPool.getResource();
String usersString = jedis.get(key); String usersString = jedis.get(key);
System.out.println("USER "+usersString);
if(usersString!=null) { if(usersString!=null) {
String[] lines = usersString.split("\n"); String[] lines = usersString.split("\n");
for (int i = 0; i < lines.length; i++) { for (int i = 0; i < lines.length; i++) {

View file

@ -1,75 +1,48 @@
package com.texttwist.server.services; package com.texttwist.server.services;
import com.texttwist.server.Server; import com.texttwist.server.Server;
import com.texttwist.server.tasks.MessageDispatcher;
import com.texttwist.server.models.Dictionary; import com.texttwist.server.models.Dictionary;
import com.texttwist.server.models.Match;
import com.texttwist.server.models.servers.ThreadProxy;
import com.texttwist.server.tasks.ReceiveWords;
import constants.Config; import constants.Config;
import models.Message; import models.Message;
import java.net.*; import java.net.*;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.*; import java.nio.channels.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static java.nio.channels.SelectionKey.OP_ACCEPT; import static java.nio.channels.SelectionKey.OP_ACCEPT;
import static java.nio.channels.SelectionKey.OP_READ; import static java.nio.channels.SelectionKey.OP_READ;
/**
* Author: Lorenzo Iovino on 17/06/2017.
* Description: Message Service
*/
public class MessageService implements Runnable{ public class MessageService implements Runnable{
private int serverPort;
private ThreadProxy proxy;
private ReceiveWords wordsReceiver;
private DatagramChannel datagramChannel;
private Selector selector = null; private Selector selector = null;
private ExecutorService threadPool = Executors.newCachedThreadPool(); private ExecutorService dispatcherPool = Executors.newCachedThreadPool();
private String dictionaryPath = "./Server/resources/dictionary";
public static Dictionary dict;
SocketChannel client;
ByteBuffer bufferWords = ByteBuffer.allocate(1024);
ByteBuffer bufferMessages = ByteBuffer.allocate(1024);
public MessageService()
public static List<Match> activeMatches = Collections.synchronizedList(new ArrayList<>()); {
public static Integer multicastID = 30000;
public MessageService(int port){
this.serverPort = port;
}
public void run(){
dict = new Dictionary(dictionaryPath);
try { try {
selector = Selector.open(); selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(serverPort)); serverSocketChannel.socket().bind(new InetSocketAddress(Config.MessageServicePort));
serverSocketChannel.register(selector, OP_ACCEPT); serverSocketChannel.register(selector, OP_ACCEPT);
InetSocketAddress address = new InetSocketAddress(Config.WordsReceiverServerURI,Config.WordsReceiverServerPort); Server.logger.write("Message Service is running at "+Config.MessageServicePort +" port...");
datagramChannel = DatagramChannel.open();
datagramChannel.configureBlocking(true);
datagramChannel.connect(address);
Server.logger.write("MessageService Service is running at "+this.serverPort+" port...");
wordsReceiver = new ReceiveWords(datagramChannel, bufferWords, bufferMessages, client);
threadPool.submit(wordsReceiver);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
}
public void run(){
while (true) { while (true) {
System.out.println("WAITING FOR MSG");
try { try {
selector.select(); selector.select();
} catch (IOException e) { } catch (IOException e) {
@ -78,9 +51,9 @@ public class MessageService implements Runnable{
Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
bufferMessages = ByteBuffer.allocate(1024); ByteBuffer bufferMessages = ByteBuffer.allocate(1024);
bufferMessages.clear(); bufferMessages.clear();
client = null; SocketChannel client = null;
SelectionKey key = iter.next(); SelectionKey key = iter.next();
iter.remove(); iter.remove();
@ -97,12 +70,10 @@ public class MessageService implements Runnable{
if (client.read(bufferMessages) != -1) { if (client.read(bufferMessages) != -1) {
bufferMessages.flip(); bufferMessages.flip();
String line = new String(bufferMessages.array(), bufferMessages.position(), bufferMessages.remaining()); String line = new String(bufferMessages.array(), bufferMessages.position(), bufferMessages.remaining());
System.out.println(line);
if (line.startsWith("MESSAGE")) { if (line.startsWith("MESSAGE")) {
SessionsService.getInstance().printAll();
Message msg = Message.toMessage(line); Message msg = Message.toMessage(line);
proxy = new ThreadProxy(msg, client, bufferMessages); MessageDispatcher proxy = new MessageDispatcher(msg, client, bufferMessages);
threadPool.submit(proxy); dispatcherPool.submit(proxy);
} }
if (line.startsWith("CLOSE")) { if (line.startsWith("CLOSE")) {
@ -119,7 +90,6 @@ public class MessageService implements Runnable{
key.cancel(); key.cancel();
} }
break; break;
default: default:
break; break;
} }

View file

@ -1,5 +1,7 @@
package com.texttwist.server.services; package com.texttwist.server.services;
import com.texttwist.server.Server;
import constants.Config;
import interfaces.INotificationClient; import interfaces.INotificationClient;
import interfaces.INotificationServer; import interfaces.INotificationServer;
@ -11,45 +13,36 @@ import java.util.List;
/** /**
* Created by loke on 19/06/2017. * Author: Lorenzo Iovino on 19/06/2017.
* Description: Notification Service
*/ */
public class NotificationService implements INotificationServer { public class NotificationService implements INotificationServer {
private List<INotificationClient> clients; private List<INotificationClient> clients;
public NotificationService() throws RemoteException { public NotificationService() throws RemoteException {
super(); super();
Server.logger.write("Notification Service running at "+ Config.NotificationServicePort +" port...");
clients = new ArrayList<>(); clients = new ArrayList<>();
} }
public synchronized void registerForCallback(INotificationClient clientInterface) throws RemoteException { public synchronized void registerForCallback(INotificationClient clientInterface) throws RemoteException {
if(!clients.contains(clientInterface)){ if(!clients.contains(clientInterface)){
clients.add(clientInterface); clients.add(clientInterface);
System.out.println(clientInterface);
System.out.println("New client registered");
} }
} }
public synchronized void unregisterForCallback(INotificationClient client) throws RemoteException { public synchronized void unregisterForCallback(INotificationClient client) throws RemoteException {
if (clients.remove(client)) { clients.remove(client);
System.out.println("Client unregistered");
} else {
System.out.println("Unable to unregister client");
}
} }
public synchronized void sendInvitations(String username, DefaultListModel<String> users){ public synchronized void sendInvitations(String username, DefaultListModel<String> users){
Iterator i = clients.iterator(); Iterator i = clients.iterator();
INotificationClient client = null; INotificationClient client = null;
System.out.println("Starting callbacks");
while (i.hasNext()) { while (i.hasNext()) {
client = (INotificationClient) i.next(); client = (INotificationClient) i.next();
try { try {
System.out.println("SENDING INVITE TO "+users);
client.sendInvite(username, users); client.sendInvite(username, users);
} catch (RemoteException e) { } catch (RemoteException e) {
System.out.println("Sembra down");
try { try {
unregisterForCallback(client); unregisterForCallback(client);
} catch (RemoteException e1) { } catch (RemoteException e1) {
@ -57,6 +50,5 @@ public class NotificationService implements INotificationServer {
} }
} }
} }
} }
} }

View file

@ -0,0 +1,58 @@
package com.texttwist.server.services;
import com.texttwist.server.Server;
import com.texttwist.server.models.Sessions;
import com.texttwist.server.models.Match;
import com.texttwist.server.tasks.ComputeScore;
import constants.Config;
import models.Message;
import java.io.IOException;
import java.net.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Author: Lorenzo Iovino on 27/06/2017.
* Description: Receive Words Service
*/
public class ReceiveWordsService implements Runnable {
private ExecutorService threadPool = Executors.newCachedThreadPool();
public ReceiveWordsService() {
Server.logger.write("ReceiveWords Service running at "+Config.WordsReceiverServicePort +" port...");
}
@Override
public void run(){
Message msg;
DatagramSocket s = null;
try {
s = new DatagramSocket(Config.WordsReceiverServicePort);
} catch (SocketException e) {
e.printStackTrace();
}
DatagramPacket packet;
while(true) {
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
try {
s.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String rcv = new String(packet.getData());
if (rcv.startsWith("MESSAGE")) {
msg = Message.toMessage(rcv);
if(Sessions.getInstance().isValidToken(msg.token)) {
Match match = Match.findMatchByPlayerName(msg.sender);
threadPool.submit(new ComputeScore(msg.sender, msg.data, match));
}
}
}
}
}

View file

@ -1,87 +0,0 @@
package com.texttwist.server.services;
import models.Session;
import models.User;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Created by loke on 17/06/2017.
*/
public class SessionsService {
private List<Session> sessions = Collections.synchronizedList(new ArrayList<Session>());
private static class Holder {
static final SessionsService INSTANCE = new SessionsService();
}
public static SessionsService getInstance() {
return Holder.INSTANCE;
}
private SessionsService(){}
public boolean add(String userName, String token) {
remove(userName);
return sessions.add(new Session(new User(userName,"",0), token));
}
public void printAll(){
Iterator<Session> i = sessions.iterator();
while (i.hasNext()) {
Session elem = i.next();
System.out.println(elem.account.userName + " | " + elem.token);
}
}
public boolean remove(String userName){
if(exists(userName)) {
Session s = getSession(userName);
if(s != null) {
sessions.remove(s);
return true;
}
}
return false;
}
public Session getSession(String userName) {
Iterator<Session> i = sessions.iterator();
while (i.hasNext()) {
Session elem = i.next();
if (elem.account.userName.equals(userName)) {
return elem;
}
}
return null;
}
public boolean exists(String userName) {
Iterator<Session> i = sessions.iterator();
while (i.hasNext()) {
Session elem = i.next();
if (elem.account.userName.equals(userName)) {
return true;
}
}
return false;
}
public boolean isValidToken(String token) {
Iterator<Session> i = sessions.iterator();
while (i.hasNext()) {
if (i.next().token.equals(token)) {
return true;
}
}
return false;
}
}

View file

@ -1,12 +1,13 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.services.SessionsService; import com.texttwist.server.models.Sessions;
import javax.swing.*; import javax.swing.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 19/06/2017. * Author: Lorenzo Iovino on 19/06/2017.
* Description: Task: Check Online Users
*/ */
public class CheckOnlineUsers implements Callable<Boolean> { public class CheckOnlineUsers implements Callable<Boolean> {
private final DefaultListModel<String> users; private final DefaultListModel<String> users;
@ -18,7 +19,7 @@ public class CheckOnlineUsers implements Callable<Boolean> {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
for(int i = 0; i < users.size(); i++){ for(int i = 0; i < users.size(); i++){
if(!(SessionsService.getInstance().exists(users.get(i)))){ if(!(Sessions.getInstance().exists(users.get(i)))){
return false; return false;
} }
} }

View file

@ -1,6 +1,6 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.services.AccountsService; import com.texttwist.server.models.Accounts;
import com.texttwist.server.services.JedisService; import com.texttwist.server.services.JedisService;
import models.User; import models.User;
@ -9,26 +9,25 @@ import java.util.Comparator;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 28/06/2017. * Author: Lorenzo Iovino on 28/06/2017.
* Description: Task: Compute Highscores
*/ */
public class ComputeHighscores implements Callable<DefaultListModel<String>> { public class ComputeHighscores implements Callable<DefaultListModel<String>> {
public ComputeHighscores(){}
@Override @Override
public DefaultListModel<String> call() throws Exception { public DefaultListModel<String> call() throws Exception {
DefaultListModel<String> l = new DefaultListModel<>(); DefaultListModel<String> l = new DefaultListModel<>();
AccountsService.getInstance().users.sort(new Comparator<User>() { Accounts.getInstance().users.sort(new Comparator<User>() {
@Override @Override
public int compare(User o1, User o2) { public int compare(User o1, User o2) {
return o2.score.compareTo(o1.score); return o2.score.compareTo(o1.score);
} }
}); });
JedisService.removeAll("users"); JedisService.removeAll("users");
for(int i = 0; i< AccountsService.getInstance().users.size(); i++){ for(int i = 0; i< Accounts.getInstance().users.size(); i++){
l.addElement(AccountsService.getInstance().users.get(i).userName+":"+ AccountsService.getInstance().users.get(i).score); l.addElement(Accounts.getInstance().users.get(i).userName+":"+ Accounts.getInstance().users.get(i).score);
JedisService.add("users", AccountsService.getInstance().users.get(i)); JedisService.add("users", Accounts.getInstance().users.get(i));
} }
return l; return l;
} }

View file

@ -1,21 +1,22 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.services.AccountsService;
import com.texttwist.server.models.Accounts;
import com.texttwist.server.models.Dictionary; import com.texttwist.server.models.Dictionary;
import com.texttwist.server.models.Match; import com.texttwist.server.models.Match;
import models.User; import models.User;
import javax.swing.*; import javax.swing.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 27/06/2017. * Author: Lorenzo Iovino on 27/06/2017.
* Description: Task: Ccmpute Score
*/ */
public class ComputeScore implements Callable<Integer> { public class ComputeScore implements Callable<Integer> {
public DefaultListModel<String> words; private DefaultListModel<String> words;
public final String sender; private final String sender;
public Match match; public Match match;
public DefaultListModel<String> wordsValid; private DefaultListModel<String> wordsValid = new DefaultListModel<>();
public ComputeScore(String sender, DefaultListModel<String> words, Match match){ public ComputeScore(String sender, DefaultListModel<String> words, Match match){
this.words = words; this.words = words;
@ -25,36 +26,26 @@ public class ComputeScore implements Callable<Integer> {
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
wordsValid = new DefaultListModel<>();
Integer score = 0;
for (int i = 0; i < words.size(); i++) { //Compute the score depending on the size of the words
if (isValid(words.get(i), match.letters)) { Integer score = 0;
score += words.get(i).length(); for (int i = 0; i < words.size(); i++) {
System.out.println(words.get(i) + " is valid!" + " : " + score ); if (isValid(words.get(i), match.letters)) {
wordsValid.addElement(words.get(i)); score += words.get(i).length();
} wordsValid.addElement(words.get(i));
} }
}
match.setScore(sender, score);
System.out.println(sender +" totalize SCORE = " + score); User u = Accounts.getInstance().findUser(sender);
match.setScore(sender, score); u.addScore(score);
System.out.println(score);
User u = AccountsService.getInstance().findUser(sender);
u.addScore(score);
if(match.allPlayersSendedHisScore()) {
match.matchTimeout = false;
System.out.println("MATCH TIMEOUT CANCELLATO");
match.setUndefinedScorePlayersToZero();
match.sendScores();
}
return score;
if(match.allPlayersSendedHisScore()) {
match.matchTimeout = false;
match.setUndefinedScorePlayersToZero();
new SendFinalScores(match).call();
}
return score;
} }
private Boolean isValid(String word, DefaultListModel<String> letters) { private Boolean isValid(String word, DefaultListModel<String> letters) {
@ -69,7 +60,6 @@ public class ComputeScore implements Callable<Integer> {
if(word.equals("")){ if(word.equals("")){
return true; return true;
} }
if(!isCharacterPresent || wordsValid.indexOf(word)!=-1){ if(!isCharacterPresent || wordsValid.indexOf(word)!=-1){
return false; return false;
} }

View file

@ -1,25 +1,21 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.services.MessageService; import com.texttwist.server.Server;
import javax.swing.*; import javax.swing.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 25/06/2017. * Author: Lorenzo Iovino on 25/06/2017.
* Description: Task: Generate Letters
*/ */
public class GenerateLetters implements Callable<DefaultListModel<String>> { public class GenerateLetters implements Callable<DefaultListModel<String>> {
public GenerateLetters(){
}
@Override @Override
public DefaultListModel<String> call() throws Exception { public DefaultListModel<String> call() throws Exception {
DefaultListModel<String> l = new DefaultListModel<String>(); DefaultListModel<String> l = new DefaultListModel<>();
String word = MessageService.dict.getRandomWord(6, 7); String word = Server.dict.getRandomWord(6, 7);
for (int i = 0;i < word.length(); i++){ for (int i = 0;i < word.length(); i++){
l.addElement(String.valueOf(word.charAt(i))); l.addElement(String.valueOf(word.charAt(i)));
} }

View file

@ -5,15 +5,15 @@ import javafx.util.Pair;
import javax.swing.*; import javax.swing.*;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import static com.texttwist.server.services.MessageService.activeMatches;
/** /**
* Created by loke on 23/06/2017. * Author: Lorenzo Iovino on 23/06/2017.
* Description: Task: Join Match
*/ */
public class JoinMatch implements Callable<Boolean> { public class JoinMatch implements Callable<Boolean> {
public final String matchName; private final String matchName;
public final String playerName; private final String playerName;
public final SocketChannel socketChannel; private final SocketChannel socketChannel;
public JoinMatch(String playerName, DefaultListModel<String> matchName, SocketChannel socketChannel) { public JoinMatch(String playerName, DefaultListModel<String> matchName, SocketChannel socketChannel) {
this.playerName = playerName; this.playerName = playerName;
@ -23,32 +23,20 @@ public class JoinMatch implements Callable<Boolean> {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
final Match thisMatch = Match.findMatch(activeMatches, this.matchName); final Match thisMatch = Match.findMatch(Match.activeMatches, this.matchName);
if (thisMatch != null) { if (thisMatch != null) {
for (int j = 0; j < thisMatch.playersStatus.size(); j++) { for (int j = 0; j < thisMatch.playersStatus.size(); j++) {
String name = thisMatch.playersStatus.get(j).getKey(); String name = thisMatch.playersStatus.get(j).getKey();
if (name.equals(playerName)) { if (name.equals(playerName)) {
thisMatch.playersStatus.remove(j); thisMatch.playersStatus.remove(j);
thisMatch.playersStatus.add(new Pair<>(name, 1)); thisMatch.playersStatus.add(new Pair<>(name, 1));
thisMatch.playersSocket.remove(j); thisMatch.playersSocket.remove(j);
thisMatch.playersSocket.add(new Pair<>(name, socketChannel)); thisMatch.playersSocket.add(new Pair<>(name, socketChannel));
return allJoined(thisMatch); return allJoined(thisMatch);
}
} }
} }
return false;
}
private void printAll(Match match){
for (int i = 0; i < match.playersStatus.size(); i++) {
System.out.println(match.playersStatus.get(i).getKey());
System.out.println(match.playersStatus.get(i).getValue());
System.out.println(match.playersSocket.get(i).getKey());
System.out.println(match.playersSocket.get(i).getValue());
} }
return false;
} }
private Boolean allJoined(Match match) { private Boolean allJoined(Match match) {
@ -57,7 +45,7 @@ public class JoinMatch implements Callable<Boolean> {
return false; return false;
} }
} }
match.joinTimeout=false; match.joinTimeout = false;
return true; return true;
} }
} }

View file

@ -1,116 +1,109 @@
package com.texttwist.server.models.servers; package com.texttwist.server.tasks;
import com.texttwist.server.Server;
import com.texttwist.server.models.Sessions;
import com.texttwist.server.models.Match; import com.texttwist.server.models.Match;
import com.texttwist.server.services.SessionsService;
import com.texttwist.server.tasks.*; import com.texttwist.server.tasks.*;
import models.Message; import models.Message;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.*; import java.util.concurrent.*;
import static com.texttwist.server.services.MessageService.activeMatches;
/** /**
* Created by loke on 18/06/2017. * Author: Lorenzo Iovino on 18/06/2017.
*/ * Description: Message Dispatcher
public class ThreadProxy implements Callable<Boolean> { * */
protected final ExecutorService threadPool = Executors.newCachedThreadPool(); public class MessageDispatcher implements Callable<Boolean> {
private final ExecutorService threadPool = Executors.newCachedThreadPool();
private final Message request; private final Message request;
private final SocketChannel socketChannel; private final SocketChannel socketChannel;
private ByteBuffer bufferMessage; private ByteBuffer bufferMessage;
boolean matchNotAvailable =false; private boolean matchNotAvailable = false;
public MessageDispatcher(Message request, SocketChannel socketChannel, ByteBuffer bufferMessage) {
public ThreadProxy(Message request, SocketChannel socketChannel, ByteBuffer bufferMessage) {
this.request = request; this.request = request;
this.socketChannel = socketChannel; this.socketChannel = socketChannel;
this.bufferMessage = bufferMessage; this.bufferMessage = bufferMessage;
} }
@Override @Override
public Boolean call() { public Boolean call() {
bufferMessage = ByteBuffer.allocate(1024); bufferMessage = ByteBuffer.allocate(1024);
byte[] byteMessage = null; byte[] byteMessage = null;
if(SessionsService.getInstance().isValidToken(request.token)){ if(Sessions.getInstance().isValidToken(request.token)){
switch(request.message){ switch(request.message){
case "START_GAME": case "START_GAME":
Future<Boolean> onlineUsers = threadPool.submit(new CheckOnlineUsers(request.data)); Future<Boolean> onlineUsers = threadPool.submit(new CheckOnlineUsers(request.data));
try { try {
//Check if invited users are online
Boolean usersOnline = onlineUsers.get(); Boolean usersOnline = onlineUsers.get();
if(usersOnline){ if(usersOnline){
Future<Boolean> sendInvitations = threadPool.submit(new SendInvitations(request.sender, request.data)); Future<Boolean> sendInvitations = threadPool.submit(new SendInvitations(request.sender, request.data));
try { Boolean invitationSended = sendInvitations.get();
Boolean invitationSended = sendInvitations.get(); if (invitationSended) {
if (invitationSended) {
//Crea nuova partita e attendi i giocatori //Server create new match
request.data.addElement(request.sender); request.data.addElement(request.sender);
final Match match = new Match(request.sender, request.data); final Match match = new Match(request.sender, request.data);
match.printAll(); Match.activeMatches.add(match);
activeMatches.add(match); DefaultListModel<String> matchName = new DefaultListModel<>();
matchName.addElement(request.sender);
DefaultListModel<String> matchName = new DefaultListModel<>(); //Match creator join match
matchName.addElement(request.sender); Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, matchName, socketChannel));
Boolean joinMatchRes = joinMatch.get();
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, matchName, socketChannel)); //Notify to the client that invites was sents correctly
Boolean joinMatchRes = joinMatch.get(); if(!joinMatchRes){
bufferMessage = ByteBuffer.allocate(1024);
if(!joinMatchRes){ Message message = new Message("INVITES_ALL_SENDED", "", "", new DefaultListModel<>());
bufferMessage = ByteBuffer.allocate(1024); byteMessage = message.toString().getBytes();
bufferMessage = ByteBuffer.wrap(byteMessage);
//NON FARE NULLA, ASPETTA GLI ALTRI socketChannel.write(bufferMessage);
Message message = new Message("INVITES_ALL_SENDED", "", "", new DefaultListModel<>()); }
byteMessage = message.toString().getBytes();
bufferMessage = ByteBuffer.wrap(byteMessage); //Starts to wait until all player joins
socketChannel.write(bufferMessage); Future<Boolean> joinTimeout = threadPool.submit(new TimeoutJoin(match));
} Boolean joinTimeoutRes = joinTimeout.get();
//If joinTimeoutRes==true timeout happen, need to notify to all waiting clients
Future<Boolean> joinTimeout = threadPool.submit(new JoinTimeout(match)); if(joinTimeoutRes){
joinTimeout.get(); Future<Boolean> sendMessageToAllPlayers = threadPool.submit(
if(match.joinTimeout){ new SendMessageToAllPlayers(match,
Future<Boolean> sendMessageJoinTimeout = threadPool.submit( new Message("JOIN_TIMEOUT", "", "", new DefaultListModel<>()), socketChannel));
new SendMessageToAllPlayers(match, new Message("JOIN_TIMEOUT", "", "", new DefaultListModel<>()), socketChannel)); Boolean sendMessageToAllPlayersRes = sendMessageToAllPlayers.get();
Boolean sendMessageJoinTimeoutRes = sendMessageJoinTimeout.get(); if(!sendMessageToAllPlayersRes){
if(!sendMessageJoinTimeoutRes){ Match.activeMatches.remove(Match.findMatchIndex(Match.activeMatches, match.matchCreator));
activeMatches.remove(Match.findMatchIndex(activeMatches, match.matchCreator)); return sendMessageToAllPlayersRes;
return sendMessageJoinTimeoutRes; }
} } else {
} else { //All done, all player joined
System.out.println("TIMEOUT FINITO SENZA EFFETTI"); return true;
return true;
}
} else {
return false;
} }
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} }
} else { } else {
//Some user in the list is not online
Message message = new Message("USER_NOT_ONLINE", "", "", new DefaultListModel<>()); Message message = new Message("USER_NOT_ONLINE", "", "", new DefaultListModel<>());
byteMessage = new String(message.toString()).getBytes(); byteMessage = message.toString().getBytes();
bufferMessage.clear(); bufferMessage.clear();
bufferMessage = ByteBuffer.wrap(byteMessage); bufferMessage = ByteBuffer.wrap(byteMessage);
this.socketChannel.write(bufferMessage); this.socketChannel.write(bufferMessage);
return false; return false;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - START GAME: InterruptedException");
} catch (ExecutionException e) { } catch (ExecutionException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - START GAME: ExecutionException");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - START GAME: IOException");
} }
case "FETCH_HIGHSCORES": case "FETCH_HIGHSCORES":
//Fetch hisghscore and send back to client
Future<DefaultListModel<String>> computeHighscores = threadPool.submit(new ComputeHighscores()); Future<DefaultListModel<String>> computeHighscores = threadPool.submit(new ComputeHighscores());
try { try {
DefaultListModel<String> computeHighscoresRes = computeHighscores.get(); DefaultListModel<String> computeHighscoresRes = computeHighscores.get();
@ -122,27 +115,31 @@ public class ThreadProxy implements Callable<Boolean> {
bufferMessage = ByteBuffer.wrap(byteMessage); bufferMessage = ByteBuffer.wrap(byteMessage);
try { try {
String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining());
System.out.println("INVIO HIGHSCORES "+ s);
socketChannel.write(bufferMessage); socketChannel.write(bufferMessage);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return false; return false;
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - FETCH HIGHSCORES: InterruptedException");
} catch (ExecutionException e) { } catch (ExecutionException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - FETCH HIGHSCORES: ExecutionException");
} }
case "JOIN_GAME": case "JOIN_GAME":
//An user joined the game
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, request.data, socketChannel)); Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, request.data, socketChannel));
try { try {
Match match = Match.findMatch(activeMatches, request.data.get(0));; Match match = Match.findMatch(Match.activeMatches, request.data.get(0));;
Boolean joinMatchRes = joinMatch.get(); Boolean joinMatchRes = joinMatch.get();
//If joinMatchRes=true start the game! Because all player joined
if(joinMatchRes){ if(joinMatchRes){
//If match not fired join timeout, notify all player that game is started
if(!match.joinTimeout) { if(!match.joinTimeout) {
//Generate letters to send to clients
Future<DefaultListModel<String>> generateLetters = threadPool.submit(new GenerateLetters()); Future<DefaultListModel<String>> generateLetters = threadPool.submit(new GenerateLetters());
match.setLetters(generateLetters.get()); match.setLetters(generateLetters.get());
match.letters.addElement(String.valueOf(match.multicastId)); match.letters.addElement(String.valueOf(match.multicastId));
@ -155,31 +152,28 @@ public class ThreadProxy implements Callable<Boolean> {
Message message = new Message("GAME_STARTED", "", "", match.letters); Message message = new Message("GAME_STARTED", "", "", match.letters);
match.startGame(); match.startGame();
System.out.println("TIMEOUT CANCELLEd");
byteMessage = message.toString().getBytes(); byteMessage = message.toString().getBytes();
bufferMessage = ByteBuffer.wrap(byteMessage); bufferMessage = ByteBuffer.wrap(byteMessage);
try { try {
String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining()); String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining());
System.out.println("INVIO GAME_STARTED "+ s);
socketClient.write(bufferMessage); socketClient.write(bufferMessage);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
if (matchNotAvailable) { if (matchNotAvailable) {
matchNotAvailable = false;
return false; return false;
} }
} }
} else { } else {
//Match doesn't exist more because a timeout happen
if(match == null){ if(match == null){
bufferMessage = ByteBuffer.allocate(1024); bufferMessage = ByteBuffer.allocate(1024);
if (socketChannel != null) { if (socketChannel != null) {
bufferMessage = ByteBuffer.allocate(1024); bufferMessage = ByteBuffer.allocate(1024);
Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>()); Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>());
bufferMessage.clear(); bufferMessage.clear();
byteMessage = msg.toString().getBytes(); byteMessage = msg.toString().getBytes();
@ -187,27 +181,23 @@ public class ThreadProxy implements Callable<Boolean> {
socketChannel.write(bufferMessage); socketChannel.write(bufferMessage);
matchNotAvailable = true; matchNotAvailable = true;
} }
} }
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: InterruptedException");
} catch (ExecutionException e) { } catch (ExecutionException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: ExecutionException");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: IOException");
} }
default: default:
break; break;
} }
} else { } else {
//If token is invalid, return error message to client
threadPool.submit(new TokenInvalid(request.sender, socketChannel, bufferMessage)); threadPool.submit(new TokenInvalid(request.sender, socketChannel, bufferMessage));
return false; return false;
} }
return false; return false;
} }
} }

View file

@ -1,71 +0,0 @@
package com.texttwist.server.tasks;
import com.texttwist.server.services.SessionsService;
import com.texttwist.server.models.Match;
import constants.Config;
import models.Message;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by loke on 27/06/2017.
*/
public class ReceiveWords implements Callable<Boolean>{
protected ExecutorService threadPool = Executors.newCachedThreadPool();
public DatagramChannel channel;
ByteBuffer bufferWords;
ByteBuffer bufferMessages;
public SocketChannel socketChannel;
public ReceiveWords(DatagramChannel channel, ByteBuffer buffer, ByteBuffer bufferMessages, SocketChannel socketChannel) {
this.bufferWords = buffer;
this.channel = channel;
this.bufferMessages = bufferMessages;
this.socketChannel = socketChannel;
}
@Override
public Boolean call() throws Exception {
Message msg;
DatagramSocket s = new DatagramSocket(Config.WordsReceiverServerPort);
while(true) {
byte[] buf = new byte[1024];
System.out.println("RECEIVIN WORDS");
DatagramPacket packet = new DatagramPacket(buf, buf.length);
s.receive(packet);
System.out.println("WORDS RECEIVED");
String rcv = new String(packet.getData());
System.out.println(rcv);
if (rcv.startsWith("MESSAGE")) {
msg = Message.toMessage(rcv);
if(SessionsService.getInstance().isValidToken(msg.token)) {
System.out.println(msg.sender);
Match match = Match.findMatchByPlayer(msg.sender);
threadPool.submit(new ComputeScore(msg.sender, msg.data, match));
} else {
threadPool.submit(new TokenInvalid(msg.sender, socketChannel, bufferMessages));
return false;
}
}
}
}
}

View file

@ -0,0 +1,41 @@
package com.texttwist.server.tasks;
import com.texttwist.server.models.Match;
import constants.Config;
import models.Message;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.concurrent.Callable;
/**
* Author: Lorenzo Iovino on 13/07/2017.
* Description: Task: Send Final Scores
*/
public class SendFinalScores implements Callable<Void> {
private Match match;
public SendFinalScores(Match match){
this.match = match;
}
@Override
public Void call() throws Exception {
Message msg = new Message("FINALSCORE", "SERVER", "", match.getMatchPlayersScoreAsStringList());
MulticastSocket multicastSocket = null;
try {
multicastSocket = new MulticastSocket(match.multicastId);
InetAddress ia = InetAddress.getByName(Config.ScoreMulticastServiceURI);
DatagramPacket hi = new DatagramPacket(msg.toString().getBytes(), msg.toString().length(), ia, match.multicastId);
multicastSocket.send(hi);
} catch (IOException e) {
e.printStackTrace();
}
Match.activeMatches.remove(Match.findMatchIndex(Match.activeMatches, match.matchCreator));
return null;
}
}

View file

@ -1,12 +1,12 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.Server; import com.texttwist.server.Server;
import javax.swing.*; import javax.swing.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 19/06/2017. * Author: Lorenzo Iovino on 19/06/2017.
* Description: Task: Send Invitations
*/ */
public class SendInvitations implements Callable<Boolean> { public class SendInvitations implements Callable<Boolean> {
private DefaultListModel<String> users; private DefaultListModel<String> users;
@ -20,15 +20,10 @@ public class SendInvitations implements Callable<Boolean> {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
try { try {
System.out.println("INVIA INVITO A" + users);
Server.notificationServer.sendInvitations(sender, users); Server.notificationServer.sendInvitations(sender, users);
} catch (Exception e) { } catch (Exception e) {
System.out.println("Eccezione" + e);
e.printStackTrace(); e.printStackTrace();
} }
return true; return true;
} }
} }

View file

@ -2,21 +2,21 @@ package com.texttwist.server.tasks;
import com.texttwist.server.models.Match; import com.texttwist.server.models.Match;
import models.Message; import models.Message;
import javax.swing.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 27/06/2017. * Author: Lorenzo Iovino on 27/06/2017.
* Description: Task: Send Message To All Players
*/ */
public class SendMessageToAllPlayers implements Callable<Boolean> { public class SendMessageToAllPlayers implements Callable<Boolean> {
public final Match match; public final Match match;
public final Message message; private final Message message;
public SocketChannel socketChannel; private SocketChannel socketChannel;
public SendMessageToAllPlayers(Match match, Message message, SocketChannel socketChannel){ public SendMessageToAllPlayers(Match match, Message message, SocketChannel socketChannel){
this.match = match; this.match = match;
this.message = message; this.message = message;
@ -36,10 +36,8 @@ public class SendMessageToAllPlayers implements Callable<Boolean> {
buffer = ByteBuffer.wrap(byteMessage); buffer = ByteBuffer.wrap(byteMessage);
socketChannel.write(buffer); socketChannel.write(buffer);
} }
} }
return false; return false;
} else { } else {
return true; return true;
} }

View file

@ -1,30 +1,34 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.models.Match; import com.texttwist.server.models.Match;
import constants.Config;
import java.util.concurrent.*; import java.util.concurrent.*;
/** /**
* Created by loke on 23/06/2017. * Author: Lorenzo Iovino on 23/06/2017.
* Description: Task: Join Timeout
*/ */
public class JoinTimeout implements Callable<Boolean> { public class TimeoutJoin implements Callable<Boolean> {
public final Match match; public final Match match;
public JoinTimeout(Match match) { public TimeoutJoin(Match match) {
this.match = match; this.match = match;
} }
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
try { try {
Thread.currentThread().sleep(7*60*1000); match.joinTimeout = true;
System.out.println("TIMEOUTTTT"); Thread.currentThread().sleep(Config.joinMatchTimeout);
if(match.joinTimeout) { if(match.joinTimeout) {
return false; match.joinTimeout = false;
return true;
} }
else { else {
return true; match.joinTimeout = false;
return false;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -1,16 +1,17 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.models.Match; import com.texttwist.server.models.Match;
import constants.Config;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 27/06/2017. * Author: Lorenzo Iovino on 27/06/2017.
* Description: Task: Match Timeout
*/ */
public class MatchTimeout implements Callable<Boolean> { public class TimeoutMatch implements Callable<Boolean> {
private Match match; private Match match;
public MatchTimeout(Match match) { public TimeoutMatch(Match match) {
this.match = match; this.match = match;
} }
@ -18,12 +19,11 @@ public class MatchTimeout implements Callable<Boolean> {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
try { try {
Thread.currentThread().sleep(5*60*1000); //TODO 5*60*1000 Thread.currentThread().sleep(Config.sendWordsTimeout);
match.setUndefinedScorePlayersToZero();
if(match.matchTimeout) { if(match.matchTimeout) {
System.out.println("SEND BROADCAST BECAUSE TIMEOUT"); match.setUndefinedScorePlayersToZero();
match.sendScores(); new SendFinalScores(match).call();
return true; return true;
} }
return false; return false;

View file

@ -5,14 +5,14 @@ import models.Message;
import javax.swing.*; import javax.swing.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Created by loke on 11/07/2017. * Author: Lorenzo Iovino on 11/07/2017.
* Description: Task: Token Invalid
*/ */
public class TokenInvalid implements Callable<Boolean> { public class TokenInvalid implements Callable<Void> {
private String sender; private String sender;
private ByteBuffer buffer; private ByteBuffer buffer;
private SocketChannel channel; private SocketChannel channel;
@ -24,15 +24,14 @@ public class TokenInvalid implements Callable<Boolean> {
} }
@Override @Override
public Boolean call()throws Exception { public Void call()throws Exception {
System.out.print("TOKEN NON VALIDO"); Server.logger.write("TOKEN INVALID: TOKEN USED BY "+ sender+ " IS NOT VALID");
buffer = ByteBuffer.allocate(1024); Message msg = new Message("TOKEN_NOT_VALID", "", null, new DefaultListModel<>());
Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>());
buffer.clear(); buffer.clear();
byte[] byteMessage = msg.toString().getBytes(); byte[] byteMessage = msg.toString().getBytes();
buffer = ByteBuffer.wrap(byteMessage); buffer = ByteBuffer.wrap(byteMessage);
channel.write(buffer); channel.write(buffer);
return false; return null;
} }
} }

BIN
TwistText.pdf Normal file

Binary file not shown.

BIN
TwistText_JarFiles.zip Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

9820
server.log

File diff suppressed because it is too large Load diff