Compare commits

...
Sign in to create a new pull request.

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
53 changed files with 1728 additions and 22124 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>

1285
.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

@ -141,7 +141,7 @@ public class GamePage extends Page {
return null; return null;
} }
}), }),
Config.timeoutGame Config.gameTimeout
); );
} }
} }

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,24 +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 = 5000; public static Integer NotificationServiceStubPort = 30000;
public static String NotificationServerName ="notification"; public static String NotificationServiceName ="notification";
public static int timeoutGame = 120;
public static String getAuthServerURI(){ public static String RedisServiceURI = "localhost";
return "rmi://".concat(AuthServerURI).concat(":").concat(AuthServerPort.toString());
public static int gameTimeout = 120; //2 minuti in sec
public static int joinMatchTimeout = 7*1000*60; //7 minuti in millisec
public static int sendWordsTimeout = 5*1000*60; //5 minuti in millisec
public static String getAuthServiceURI(){
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,13 +1,12 @@
package com.texttwist.server; package com.texttwist.server;
import utilities.Logger;
import java.io.File;
import java.io.IOException; import java.io.IOException;
/**
* Author: Lorenzo Iovino on 14/06/2017.
* Description: Main
*/
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
Server ttServer = new Server(); new Server();
} }
} }

View file

@ -1,65 +1,92 @@
package com.texttwist.server; package com.texttwist.server;
import com.texttwist.server.components.Auth; import com.texttwist.server.models.Dictionary;
import com.texttwist.server.components.GameServer; import com.texttwist.server.services.AuthService;
import com.texttwist.server.components.NotificationServer; import com.texttwist.server.services.MessageService;
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.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
import utilities.Logger; import utilities.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.rmi.AlreadyBoundException; import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry; import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject; import java.rmi.server.UnicastRemoteObject;
/** /**
* Created by loke on 15/06/2017. * Author: Lorenzo Iovino on 15/06/2017.
* Description: Server. Initialize all services.
*/ */
public class Server { public class Server {
public static NotificationServer notificationServer; public static NotificationService notificationServer;
public static JedisPool jedisPool; public static JedisPool jedisPool;
public static Logger logger; public static Logger logger;
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("Server starting ..."); Server.logger.write("Services starting ...");
startAuthService();
startJedisService();
startMessageService();
startWordsReceiverService();
startNotificationService();
//Start services dict = new Dictionary(dictionaryPath);
Server.logger.write("Services started correctly ...");
}
private void startAuthService(){
//Starting Auth service based on RMI
try { try {
//Definitions of registry for auth auth = new AuthService();
Auth auth = new Auth(Config.AuthServerPort); Registry authRegistry = LocateRegistry.createRegistry(Config.AuthServicePort);
Registry authRegistry = LocateRegistry.createRegistry(auth.serverPort);
authRegistry.bind("auth", auth); authRegistry.bind("auth", auth);
} catch (RemoteException e) {
//Connecting to Redis server on localhost Server.logger.write("SERVER: RMI authentication service error (Remote exception)");
jedisPool = new JedisPool(new JedisPoolConfig(), "localhost");
GameServer gameServer = new GameServer(Config.GameServerPort);
new Thread(gameServer).start();
try {
/*registrazione presso il registry */
notificationServer = new NotificationServer();
INotificationServer stub = (INotificationServer) UnicastRemoteObject.exportObject(notificationServer, Config.NotificationServerPort);
LocateRegistry.createRegistry(Config.NotificationServerStubPort);
Registry notificationRegistry = LocateRegistry.getRegistry(Config.NotificationServerStubPort);
notificationRegistry.bind(Config.NotificationServerName, stub);
} catch (Exception e) {
System.out.println("Eccezione" + e);
}
Server.logger.write("Server started");
} catch (AlreadyBoundException e) { } catch (AlreadyBoundException e) {
e.printStackTrace(); Server.logger.write("SERVER: RMI authentication service can't use this port because is busy ");
} }
} }
private void startJedisService(){
//Starting Jedis pool for Redis connection
jedisPool = new JedisPool(new JedisPoolConfig(), Config.RedisServiceURI);
}
private void startMessageService(){
//Starting the Message service based on TCP
new Thread(new MessageService()).start();
}
private void startWordsReceiverService(){
//Starting the Receive Words service based on UDP
new Thread(new ReceiveWordsService()).start();
}
private void startNotificationService(){
//Starting Notification service based on RMI
try {
notificationServer = new NotificationService();
INotificationServer stub = (INotificationServer) UnicastRemoteObject.exportObject(notificationServer, Config.NotificationServicePort);
LocateRegistry.createRegistry(Config.NotificationServiceStubPort);
Registry notificationRegistry = LocateRegistry.getRegistry(Config.NotificationServiceStubPort);
notificationRegistry.bind(Config.NotificationServiceName, stub);
} catch (RemoteException e) {
Server.logger.write("SERVER: RMI notification service error (Remote exception)");
} catch (AlreadyBoundException e) {
Server.logger.write("SERVER: RMI notification service can't use this port because is busy ");
}
}
} }

View file

@ -1,88 +0,0 @@
package com.texttwist.server.components;
import interfaces.INotificationClient;
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 SessionsManager {
private List<Session> sessions = Collections.synchronizedList(new ArrayList<Session>());
private static class Holder {
static final SessionsManager INSTANCE = new SessionsManager();
}
public static SessionsManager getInstance() {
return Holder.INSTANCE;
}
private SessionsManager(){}
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,79 +1,76 @@
package com.texttwist.server.components; package com.texttwist.server.models;
import models.User; import com.texttwist.server.services.JedisService;
import java.io.Serializable; import models.User;
import java.util.*; import java.io.Serializable;
import java.util.*;
/**
* Created by loke on 18/06/2017. /**
*/ * Author: Lorenzo Iovino on 18/06/2017.
public class AccountsManager { * Description: Accounts
*/
public List<User> users = Collections.synchronizedList(new ArrayList<User>()); public class Accounts {
private static class Holder { public List<User> users = Collections.synchronizedList(new ArrayList<User>());
static final AccountsManager INSTANCE = new AccountsManager();
} private static class Holder {
static final Accounts INSTANCE = new Accounts();
public static AccountsManager getInstance() { }
return AccountsManager.Holder.INSTANCE;
} public static Accounts getInstance() {
return Accounts.Holder.INSTANCE;
private AccountsManager(){ }
List<Serializable> l = JedisService.get("users");
for(int i=0; i<l.size(); i++) { private Accounts(){
users.add((User) l.get(i)); List<Serializable> l = JedisService.get("users");
} for(int i=0; i<l.size(); i++) {
} users.add((User) l.get(i));
}
public boolean register(String userName, String password) { }
if(!exists(userName)){
User newUser = new User(userName, password,0); public boolean register(String userName, String password) {
Boolean res = users.add(newUser); if(!exists(userName)){
JedisService.add("users", newUser); User newUser = new User(userName, password,0);
return res; Boolean res = users.add(newUser);
} else { JedisService.add("users", newUser);
return false; return res;
} } else {
} return false;
}
public boolean exists(String userName) { }
Iterator<User> i = users.iterator();
while (i.hasNext()) { public boolean exists(String userName) {
if (i.next().userName.equals(userName)) { Iterator<User> i = users.iterator();
return true; while (i.hasNext()) {
} if (i.next().userName.equals(userName)) {
} return true;
return false; }
}
} return false;
public boolean checkPassword(String userName, String password) { }
Iterator<User> i = users.iterator();
while (i.hasNext()) { public boolean checkPassword(String userName, String password) {
User account = i.next(); Iterator<User> i = users.iterator();
if (account.userName.equals(userName) && account.password.equals(password)) { while (i.hasNext()) {
return true; User account = i.next();
} if (account.userName.equals(userName) && account.password.equals(password)) {
} return true;
return false; }
}
} return false;
public User findUser(String userName){ }
Iterator<User> i = users.iterator();
while (i.hasNext()) { public User findUser(String userName){
User u = i.next(); Iterator<User> i = users.iterator();
if (u.userName.equals(userName)) { while (i.hasNext()) {
return u; User u = i.next();
} if (u.userName.equals(userName)) {
} return u;
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,40 +1,59 @@
package com.texttwist.server.models; package com.texttwist.server.models;
import com.texttwist.server.components.GameServer; import com.texttwist.server.Server;
import com.texttwist.server.tasks.MatchTimeout; import com.texttwist.server.services.MessageService;
import constants.Config; import com.texttwist.server.tasks.TimeoutMatch;
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.Callable;
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.components.GameServer.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));
@ -44,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 GameServer.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,83 +1,84 @@
package com.texttwist.server.components; package com.texttwist.server.services;
import com.texttwist.server.Server; import com.texttwist.server.Server;
import interfaces.IAuth; import com.texttwist.server.models.Accounts;
import interfaces.INotificationClient; import com.texttwist.server.models.Sessions;
import models.Response; import constants.Config;
import org.json.simple.JsonObject; import interfaces.IAuth;
import java.math.BigInteger; import interfaces.INotificationClient;
import java.rmi.RemoteException; import models.Response;
import java.rmi.server.UnicastRemoteObject; import org.json.simple.JsonObject;
import java.security.SecureRandom; import java.math.BigInteger;
import java.rmi.RemoteException;
import static com.texttwist.server.Server.notificationServer; import java.rmi.server.UnicastRemoteObject;
import java.security.SecureRandom;
/**
* Created by loke on 15/06/2017. import static com.texttwist.server.Server.notificationServer;
*/
public class Auth extends UnicastRemoteObject implements IAuth { /**
* Author: Lorenzo Iovino on 15/06/2017.
private SecureRandom random = new SecureRandom(); * Description: AuthService
public int serverPort = 9999; */
public class AuthService extends UnicastRemoteObject implements IAuth {
public Auth(int serverPort) throws RemoteException{ private SecureRandom random = new SecureRandom();
this.serverPort=serverPort;
Server.logger.write("Auth Service running at "+serverPort+" port..."); public AuthService() throws RemoteException{
} Server.logger.write("AuthService Service running at "+ Config.AuthServicePort +" port...");
}
@Override
public Response register(String userName, String password) throws RemoteException { @Override
Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password); public Response register(String userName, String password) throws RemoteException {
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) { Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password);
if(AccountsManager.getInstance().register(userName, password)){ if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
Server.logger.write("Registration successfull"); if(Accounts.getInstance().register(userName, password)){
return new Response("Registration successfull", 200, null); Server.logger.write("Registration successfull");
} else { return new Response("Registration successfull", 200, null);
Server.logger.write("Registration unsuccessfull"); } else {
return new Response("<html><center>Registration unsuccessfull: <br/> Username exist!</center></html>", 400, null); Server.logger.write("Registration unsuccessfull");
} return new Response("<html><center>Registration unsuccessfull: <br/> Username exist!</center></html>", 400, null);
} }
return new Response("<html><center>Registration unsuccessfull! <br/> All fields are mandatories</center></html>", 400, null); }
} return new Response("<html><center>Registration unsuccessfull! <br/> All fields are mandatories</center></html>", 400, null);
}
@Override
public Response login(String userName, String password) throws RemoteException { @Override
Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password); public Response login(String userName, String password) throws RemoteException {
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) { Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password);
if(AccountsManager.getInstance().exists(userName) && AccountsManager.getInstance().checkPassword(userName, password)) { if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
JsonObject data = new JsonObject(); if(Accounts.getInstance().exists(userName) && Accounts.getInstance().checkPassword(userName, password)) {
String token = nextSessionId(); JsonObject data = new JsonObject();
data.put("token", token); String token = nextSessionId();
SessionsManager.getInstance().add(userName,token); data.put("token", token);
Server.logger.write("Login successfull"); Sessions.getInstance().add(userName,token);
return new Response("Login successfull", 200, data); Server.logger.write("Login successfull");
} return new Response("Login successfull", 200, data);
} }
Server.logger.write("Login unsuccessfull"); }
return new Response("Login unsuccessfull", 400, null); Server.logger.write("Login unsuccessfull");
} return new Response("Login unsuccessfull", 400, null);
}
@Override
public Response logout(String userName, String token, INotificationClient stub) throws RemoteException { @Override
Server.logger.write("Invoked logout with username=" + userName + " AND " + " token=" + token); public Response logout(String userName, String token, INotificationClient stub) throws RemoteException {
notificationServer.unregisterForCallback(stub); Server.logger.write("Invoked logout with username=" + userName + " AND " + " token=" + token);
notificationServer.unregisterForCallback(stub);
if ((userName != null && !userName.isEmpty()) && (token != null && !token.isEmpty())) {
boolean res = SessionsManager.getInstance().remove(userName); if ((userName != null && !userName.isEmpty()) && (token != null && !token.isEmpty())) {
if(res) { boolean res = Sessions.getInstance().remove(userName);
Server.logger.write("Logout successfull"); if(res) {
Server.logger.write("Logout successfull");
}
} }
}
SessionsManager.getInstance().remove(userName);
Server.logger.write("Logout successfull (but something gone wrong)"); Sessions.getInstance().remove(userName);
return new Response("Logout successfull (but something gone wrong)", 200, null); Server.logger.write("Logout successfull (but something gone wrong)");
} return new Response("Logout successfull (but something gone wrong)", 200, null);
}
public String nextSessionId() {
return new BigInteger(130, random).toString(32); public String nextSessionId() {
} return new BigInteger(130, random).toString(32);
}
}
}

View file

@ -1,10 +1,10 @@
package com.texttwist.server.components; 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;
import java.io.*; import java.io.*;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
@ -12,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. */
@ -57,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,138 +1,106 @@
package com.texttwist.server.services;
package com.texttwist.server.components;
import com.texttwist.client.App; 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 constants.Config;
import com.texttwist.server.tasks.ReceiveWords; import models.Message;
import constants.Config; import java.net.*;
import models.Message; import java.io.IOException;
import utilities.Logger; import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.net.*; import java.util.Iterator;
import java.io.IOException; import java.util.concurrent.ExecutorService;
import java.nio.ByteBuffer; import java.util.concurrent.Executors;
import java.nio.channels.*; import static java.nio.channels.SelectionKey.OP_ACCEPT;
import java.util.ArrayList; import static java.nio.channels.SelectionKey.OP_READ;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; /**
import java.util.concurrent.ExecutorService; * Author: Lorenzo Iovino on 17/06/2017.
import java.util.concurrent.Executors; * Description: Message Service
*/
import static java.nio.channels.SelectionKey.OP_ACCEPT; public class MessageService implements Runnable{
import static java.nio.channels.SelectionKey.OP_READ;
private Selector selector = null;
public class GameServer implements Runnable{ private ExecutorService dispatcherPool = Executors.newCachedThreadPool();
private int serverPort; public MessageService()
private ThreadProxy proxy; {
private ReceiveWords wordsReceiver; try {
selector = Selector.open();
private DatagramChannel datagramChannel;
private Selector selector = null; ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
private ExecutorService threadPool = Executors.newCachedThreadPool(); serverSocketChannel.configureBlocking(false);
private String dictionaryPath = "./Server/resources/dictionary"; serverSocketChannel.socket().bind(new InetSocketAddress(Config.MessageServicePort));
public static Dictionary dict; serverSocketChannel.register(selector, OP_ACCEPT);
SocketChannel client; Server.logger.write("Message Service is running at "+Config.MessageServicePort +" port...");
ByteBuffer bufferWords = ByteBuffer.allocate(1024);
ByteBuffer bufferMessages = ByteBuffer.allocate(1024); } catch (IOException e) {
e.printStackTrace();
}
}
public static List<Match> activeMatches = Collections.synchronizedList(new ArrayList<>());
public static Integer multicastID = 4000; public void run(){
while (true) {
public GameServer(int port){ try {
this.serverPort = port; selector.select();
} } catch (IOException e) {
e.printStackTrace();
public void run(){ }
dict = new Dictionary(dictionaryPath); Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
try { while (iter.hasNext()) {
selector = Selector.open(); ByteBuffer bufferMessages = ByteBuffer.allocate(1024);
bufferMessages.clear();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); SocketChannel client = null;
serverSocketChannel.configureBlocking(false); SelectionKey key = iter.next();
serverSocketChannel.socket().bind(new InetSocketAddress(serverPort)); iter.remove();
serverSocketChannel.register(selector, OP_ACCEPT);
InetSocketAddress address = new InetSocketAddress(Config.WordsReceiverServerURI,Config.WordsReceiverServerPort); try {
datagramChannel = DatagramChannel.open(); switch (key.readyOps()) {
datagramChannel.configureBlocking(true); case OP_ACCEPT:
datagramChannel.connect(address); client = ((ServerSocketChannel) key.channel()).accept();
Server.logger.write("GameService Service is running at "+this.serverPort+" port..."); client.configureBlocking(false);
client.register(selector, OP_READ);
wordsReceiver = new ReceiveWords(datagramChannel, bufferWords, bufferMessages, client); break;
threadPool.submit(wordsReceiver);
case OP_READ:
} catch (IOException e) { client = (SocketChannel) key.channel();
e.printStackTrace(); if (client.read(bufferMessages) != -1) {
} bufferMessages.flip();
String line = new String(bufferMessages.array(), bufferMessages.position(), bufferMessages.remaining());
while (true) { if (line.startsWith("MESSAGE")) {
System.out.println("WAITING FOR MSG"); Message msg = Message.toMessage(line);
try { MessageDispatcher proxy = new MessageDispatcher(msg, client, bufferMessages);
selector.select(); dispatcherPool.submit(proxy);
} catch (IOException e) { }
e.printStackTrace();
} if (line.startsWith("CLOSE")) {
client.close();
Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); } else if (line.startsWith("QUIT")) {
while (iter.hasNext()) { for (SelectionKey k : selector.keys()) {
bufferMessages = ByteBuffer.allocate(1024); k.cancel();
bufferMessages.clear(); k.channel().close();
client = null; }
SelectionKey key = iter.next(); selector.close();
iter.remove(); return;
}
try { } else {
switch (key.readyOps()) { key.cancel();
case OP_ACCEPT: }
client = ((ServerSocketChannel) key.channel()).accept(); break;
client.configureBlocking(false); default:
client.register(selector, OP_READ); break;
break; }
} catch (IOException e) {
case OP_READ: try {
client = (SocketChannel) key.channel(); client.close();
if (client.read(bufferMessages) != -1) { } catch (IOException e1) {
bufferMessages.flip(); e1.printStackTrace();
String line = new String(bufferMessages.array(), bufferMessages.position(), bufferMessages.remaining()); }
System.out.println(line); }
if (line.startsWith("MESSAGE")) { }
SessionsManager.getInstance().printAll(); }
Message msg = Message.toMessage(line); }
proxy = new ThreadProxy(msg, client, bufferMessages);
threadPool.submit(proxy);
}
if (line.startsWith("CLOSE")) {
client.close();
} else if (line.startsWith("QUIT")) {
for (SelectionKey k : selector.keys()) {
k.cancel();
k.channel().close();
}
selector.close();
return;
}
} else {
key.cancel();
}
break;
default:
break;
}
} catch (IOException e) {
try {
client.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
} }

View file

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

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,12 +1,13 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.components.SessionsManager; 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(!(SessionsManager.getInstance().exists(users.get(i)))){ if(!(Sessions.getInstance().exists(users.get(i)))){
return false; return false;
} }
} }

View file

@ -1,36 +1,33 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.components.AccountsManager; import com.texttwist.server.models.Accounts;
import com.texttwist.server.components.JedisService; import com.texttwist.server.services.JedisService;
import models.User; import models.User;
import javax.swing.*; import javax.swing.*;
import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
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<>();
AccountsManager.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< AccountsManager.getInstance().users.size(); i++){ for(int i = 0; i< Accounts.getInstance().users.size(); i++){
l.addElement(AccountsManager.getInstance().users.get(i).userName+":"+AccountsManager.getInstance().users.get(i).score); l.addElement(Accounts.getInstance().users.get(i).userName+":"+ Accounts.getInstance().users.get(i).score);
JedisService.add("users",AccountsManager.getInstance().users.get(i)); JedisService.add("users", Accounts.getInstance().users.get(i));
} }
return l; return l;
} }

View file

@ -1,33 +1,22 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.client.App;
import com.texttwist.server.components.AccountsManager; import com.texttwist.server.models.Accounts;
import com.texttwist.server.components.JedisService;
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 constants.Config;
import models.Message;
import models.User; import models.User;
import redis.clients.jedis.Jedis;
import javax.swing.*; import javax.swing.*;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import static com.texttwist.server.components.GameServer.activeMatches;
/** /**
* 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;
@ -37,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 = AccountsManager.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) {
@ -81,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,29 +1,21 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.components.GameServer; import com.texttwist.server.Server;
import javax.swing.*; import javax.swing.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.*;
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 = GameServer.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.components.GameServer.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,45 +0,0 @@
package com.texttwist.server.tasks;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.texttwist.server.models.Match;
import constants.Config;
import models.Message;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.concurrent.Callable;
import static com.texttwist.server.components.GameServer.activeMatches;
/**
* Created by loke on 27/06/2017.
*/
public class MatchTimeout implements Callable<Boolean> {
private Match match;
public MatchTimeout(Match match) {
this.match = match;
}
@Override
public Boolean call() throws Exception {
try {
Thread.currentThread().sleep(5*60*1000); //TODO 5*60*1000
match.setUndefinedScorePlayersToZero();
if(match.matchTimeout) {
System.out.println("SEND BROADCAST BECAUSE TIMEOUT");
match.sendScores();
return true;
}
return false;
} catch (InterruptedException e) {
return false;
}
}
}

View file

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

View file

@ -1,71 +0,0 @@
package com.texttwist.server.tasks;
import com.texttwist.server.components.SessionsManager;
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(SessionsManager.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,19 +1,12 @@
package com.texttwist.server.tasks; package com.texttwist.server.tasks;
import com.texttwist.server.Server; import com.texttwist.server.Server;
import com.texttwist.server.components.NotificationServer;
import com.texttwist.server.components.SessionsManager;
import constants.Config;
import interfaces.INotificationServer;
import javax.swing.*; import javax.swing.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
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;
@ -27,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

@ -0,0 +1,37 @@
package com.texttwist.server.tasks;
import com.texttwist.server.models.Match;
import constants.Config;
import java.util.concurrent.Callable;
/**
* Author: Lorenzo Iovino on 27/06/2017.
* Description: Task: Match Timeout
*/
public class TimeoutMatch implements Callable<Boolean> {
private Match match;
public TimeoutMatch(Match match) {
this.match = match;
}
@Override
public Boolean call() throws Exception {
try {
Thread.currentThread().sleep(Config.sendWordsTimeout);
if(match.matchTimeout) {
match.setUndefinedScorePlayersToZero();
new SendFinalScores(match).call();
return true;
}
return false;
} catch (InterruptedException e) {
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