Compare commits
13 commits
alternativ
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ad9252882 | ||
|
|
bcf684bdf6 | ||
|
|
697d96b322 | ||
|
|
ee230f911c | ||
|
|
8eab4d97c1 | ||
|
|
44a9e43cd4 | ||
|
|
afbd45f51e | ||
|
|
ab307b0a97 | ||
|
|
e1622dfaa1 | ||
|
|
71ff3c4820 | ||
|
|
3305d6500b | ||
|
|
e1b02284b6 | ||
|
|
5117b28e2c |
53 changed files with 1728 additions and 22124 deletions
10
.idea/artifacts/Client_jar.xml
generated
Normal file
10
.idea/artifacts/Client_jar.xml
generated
Normal 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
14
.idea/artifacts/Server_jar.xml
generated
Normal 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
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 |
3
Client/src/META-INF/MANIFEST.MF
Normal file
3
Client/src/META-INF/MANIFEST.MF
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: com.texttwist.client.Main
|
||||
|
||||
|
|
@ -32,8 +32,8 @@ import java.rmi.server.UnicastRemoteObject;
|
|||
*/
|
||||
public class App extends JFrame {
|
||||
|
||||
private static InetSocketAddress clientTCPSocketAddress = new InetSocketAddress(Config.GameServerURI, Config.GameServerPort);
|
||||
public static InetSocketAddress clientUDPSocketAddress = new InetSocketAddress(Config.WordsReceiverServerURI, Config.WordsReceiverServerPort);
|
||||
private static InetSocketAddress clientTCPSocketAddress = new InetSocketAddress(Config.MessageServiceURI, Config.MessageServicePort);
|
||||
public static InetSocketAddress clientUDPSocketAddress = new InetSocketAddress(Config.WordsReceiverServiceURI, Config.WordsReceiverServicePort);
|
||||
private static InetAddress clientMulticastSocketAddress;
|
||||
|
||||
public static AuthService authService;
|
||||
|
|
@ -68,7 +68,7 @@ public class App extends JFrame {
|
|||
logger.write("APP: Font not found!");
|
||||
}
|
||||
|
||||
/*Services*/
|
||||
/*services*/
|
||||
gameService = new GameService();
|
||||
authService = new AuthService();
|
||||
|
||||
|
|
@ -79,10 +79,10 @@ public class App extends JFrame {
|
|||
|
||||
public static void registerForNotifications() throws RemoteException, NotBoundException {
|
||||
|
||||
Registry registry = LocateRegistry.getRegistry(Config.NotificationServerStubPort);
|
||||
Registry registry = LocateRegistry.getRegistry(Config.NotificationServiceStubPort);
|
||||
INotificationClient callbackObj = new NotificationClientService();
|
||||
notificationStub = (INotificationClient) UnicastRemoteObject.exportObject(callbackObj, 0);
|
||||
INotificationServer notificationServer = (INotificationServer) registry.lookup(Config.NotificationServerName);
|
||||
INotificationServer notificationServer = (INotificationServer) registry.lookup(Config.NotificationServiceName);
|
||||
notificationServer.registerForCallback(notificationStub);
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ public class App extends JFrame {
|
|||
public static void openClientMulticastSocket(Integer multicastId){
|
||||
try {
|
||||
App.gameService.setMulticastId(multicastId);
|
||||
clientMulticastSocketAddress = InetAddress.getByName(Config.ScoreMulticastServerURI);
|
||||
clientMulticastSocketAddress = InetAddress.getByName(Config.ScoreMulticastServiceURI);
|
||||
clientMulticast = new MulticastSocket(gameService.multicastId);
|
||||
clientMulticast.joinGroup(clientMulticastSocketAddress);
|
||||
} catch (IOException e) {
|
||||
|
|
@ -109,7 +109,7 @@ public class App extends JFrame {
|
|||
public static void closeClientMulticastSocket(){
|
||||
//Leave group and close multicast socket
|
||||
try {
|
||||
App.clientMulticast.leaveGroup(InetAddress.getByName(Config.ScoreMulticastServerURI));
|
||||
App.clientMulticast.leaveGroup(InetAddress.getByName(Config.ScoreMulticastServiceURI));
|
||||
App.clientMulticast.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ public class HomeController {
|
|||
public Response login(String userName, String password) throws RemoteException, NotBoundException, MalformedURLException {
|
||||
Response res = authService.login(userName,password);
|
||||
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()));
|
||||
}
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.texttwist.client.controllers;
|
||||
|
||||
import com.texttwist.client.App;
|
||||
import com.texttwist.client.tasks.JoinMatch;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
|
|
@ -14,6 +16,6 @@ public class MatchRequestController {
|
|||
}
|
||||
|
||||
public void joinMatch(String matchName){
|
||||
App.gameService.joinMatch(matchName);
|
||||
new JoinMatch(matchName).execute();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.texttwist.client.controllers;
|
||||
|
||||
import com.texttwist.client.tasks.InvitePlayers;
|
||||
|
||||
import javax.swing.*;
|
||||
import static com.texttwist.client.App.gameService;
|
||||
|
||||
|
|
@ -10,6 +12,7 @@ import static com.texttwist.client.App.gameService;
|
|||
public class MatchSetupController {
|
||||
|
||||
public void play(DefaultListModel<String> userNames) {
|
||||
gameService.beginMatch(userNames);
|
||||
new InvitePlayers(userNames).execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ public class GamePage extends Page {
|
|||
return null;
|
||||
}
|
||||
}),
|
||||
Config.timeoutGame
|
||||
Config.gameTimeout
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class MatchSetupPage extends Page{
|
|||
new Callable<Object>() {
|
||||
@Override
|
||||
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);
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,9 @@ import java.rmi.RemoteException;
|
|||
*/
|
||||
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 {
|
||||
try {
|
||||
App.registerForNotifications();
|
||||
} catch (RemoteException e) {
|
||||
App.logger.write("AUTH SERVICE: Can't register for notification");
|
||||
}
|
||||
IAuth auth = (IAuth) Naming.lookup(baseUrl);
|
||||
return auth.login(userName, password);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.texttwist.client.pages.GamePage;
|
|||
import com.texttwist.client.pages.MenuPage;
|
||||
import com.texttwist.client.pages.Page;
|
||||
import com.texttwist.client.tasks.InvitePlayers;
|
||||
import com.texttwist.client.tasks.JoinMatch;
|
||||
import com.texttwist.client.ui.TTDialog;
|
||||
import javafx.util.Pair;
|
||||
import models.Message;
|
||||
|
|
@ -26,9 +27,10 @@ public class GameService {
|
|||
public DefaultListModel<String> letters = new DefaultListModel<>();
|
||||
public DefaultListModel<Pair<String,Integer>> globalRanks = 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);
|
||||
}
|
||||
|
||||
|
|
@ -36,33 +38,6 @@ public class GameService {
|
|||
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(){
|
||||
return App.gameService.letters;
|
||||
}
|
||||
|
|
@ -75,32 +50,6 @@ public class GameService {
|
|||
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(){
|
||||
gameIsStarted = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.texttwist.client.services;
|
||||
|
||||
import com.texttwist.client.App;
|
||||
import com.texttwist.client.tasks.BeginMatch;
|
||||
import interfaces.INotificationClient;
|
||||
import javax.swing.*;
|
||||
import java.rmi.RemoteException;
|
||||
|
|
@ -18,7 +19,7 @@ public class NotificationClientService implements INotificationClient {
|
|||
if(App.session != null) {
|
||||
if (users.contains(App.session.account.userName)) {
|
||||
App.logger.write(userName + " send a invitation!");
|
||||
App.gameService.newMatch(userName);
|
||||
new BeginMatch(userName).execute();
|
||||
} else {
|
||||
App.logger.write("User " + userName + " is slogged");
|
||||
}
|
||||
|
|
|
|||
52
Client/src/com/texttwist/client/tasks/BeginMatch.java
Normal file
52
Client/src/com/texttwist/client/tasks/BeginMatch.java
Normal 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;
|
||||
}
|
||||
}
|
||||
47
Client/src/com/texttwist/client/tasks/JoinMatch.java
Normal file
47
Client/src/com/texttwist/client/tasks/JoinMatch.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -36,8 +36,6 @@ public class SendWords extends SwingWorker<Void,Void> {
|
|||
buffer.flip();
|
||||
|
||||
App.clientUDP.send(buffer, App.clientUDPSocketAddress);
|
||||
|
||||
return null;
|
||||
} catch (UnknownHostException e) {
|
||||
App.logger.write("SEND WORDS: Host address not correct");
|
||||
} catch (IOException e) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
|
|||
@Override
|
||||
public Void doInBackground() {
|
||||
try {
|
||||
App.gameService.isWaiting = true;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
||||
TTDialog loading = new TTDialog("alert", "Waiting for users joins",null,null);
|
||||
buffer.flip();
|
||||
|
|
@ -42,6 +43,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
|
|||
Message msg = Message.toMessage(line);
|
||||
if (msg.message.equals("JOIN_TIMEOUT")) {
|
||||
loading.dispose();
|
||||
App.gameService.isWaiting = false;
|
||||
joinTimeout = true;
|
||||
|
||||
new TTDialog("alert", "TIMEOUT!",
|
||||
|
|
@ -58,6 +60,7 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
|
|||
if (msg.message.equals("MATCH_NOT_AVAILABLE")) {
|
||||
loading.dispose();
|
||||
joinTimeout = true;
|
||||
App.gameService.isWaiting = false;
|
||||
|
||||
new TTDialog("alert", "THE GAME IS NOT MORE AVAILABLE!",
|
||||
new Callable() {
|
||||
|
|
@ -72,9 +75,11 @@ public class WaitForPlayers extends SwingWorker<Void,Void> {
|
|||
|
||||
if (msg.message.equals("GAME_STARTED")) {
|
||||
loading.dispose();
|
||||
App.gameService.isWaiting = false;
|
||||
|
||||
if(msg.data !=null ) {
|
||||
DefaultListModel<String> data = msg.data;
|
||||
|
||||
App.openClientMulticastSocket(Integer.valueOf(data.remove(data.size()-2)));
|
||||
App.gameService.setLetters(msg.data);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -6,24 +6,29 @@ package constants;
|
|||
*/
|
||||
public class Config {
|
||||
|
||||
public static String AuthServerURI = "localhost";
|
||||
public static Integer AuthServerPort = 9999;
|
||||
public static String AuthServiceURI = "localhost";
|
||||
public static Integer AuthServicePort = 9999;
|
||||
|
||||
public static String GameServerURI = "localhost";
|
||||
public static Integer GameServerPort = 10000;
|
||||
public static String MessageServiceURI = "localhost";
|
||||
public static Integer MessageServicePort = 10000;
|
||||
|
||||
public static String WordsReceiverServerURI = "localhost";
|
||||
public static Integer WordsReceiverServerPort = 10001;
|
||||
public static String WordsReceiverServiceURI = "localhost";
|
||||
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 NotificationServerStubPort = 5000;
|
||||
public static String NotificationServerName ="notification";
|
||||
public static int timeoutGame = 120;
|
||||
public static Integer NotificationServicePort = 20000;
|
||||
public static Integer NotificationServiceStubPort = 30000;
|
||||
public static String NotificationServiceName ="notification";
|
||||
|
||||
public static String getAuthServerURI(){
|
||||
return "rmi://".concat(AuthServerURI).concat(":").concat(AuthServerPort.toString());
|
||||
public static String RedisServiceURI = "localhost";
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package interfaces;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
|
|
@ -9,5 +10,6 @@ import java.rmi.RemoteException;
|
|||
*/
|
||||
public interface INotificationServer extends Remote {
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
3
Server/src/META-INF/MANIFEST.MF
Normal file
3
Server/src/META-INF/MANIFEST.MF
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: com.texttwist.server.Main
|
||||
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
package com.texttwist.server;
|
||||
|
||||
import utilities.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 14/06/2017.
|
||||
* Description: Main
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Server ttServer = new Server();
|
||||
new Server();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,92 @@
|
|||
package com.texttwist.server;
|
||||
|
||||
import com.texttwist.server.components.Auth;
|
||||
import com.texttwist.server.components.GameServer;
|
||||
import com.texttwist.server.components.NotificationServer;
|
||||
import com.texttwist.server.models.Dictionary;
|
||||
import com.texttwist.server.services.AuthService;
|
||||
import com.texttwist.server.services.MessageService;
|
||||
import com.texttwist.server.services.NotificationService;
|
||||
import com.texttwist.server.services.ReceiveWordsService;
|
||||
import constants.Config;
|
||||
import interfaces.INotificationServer;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import utilities.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.rmi.AlreadyBoundException;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
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 static NotificationServer notificationServer;
|
||||
public static NotificationService notificationServer;
|
||||
public static JedisPool jedisPool;
|
||||
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 {
|
||||
logger = new Logger(new File("./notificationServer.log"), "Server", true);
|
||||
Server.logger.write("Server starting ...");
|
||||
logger = new Logger(new File("./server.log"), "Server", true);
|
||||
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 {
|
||||
//Definitions of registry for auth
|
||||
Auth auth = new Auth(Config.AuthServerPort);
|
||||
Registry authRegistry = LocateRegistry.createRegistry(auth.serverPort);
|
||||
auth = new AuthService();
|
||||
Registry authRegistry = LocateRegistry.createRegistry(Config.AuthServicePort);
|
||||
authRegistry.bind("auth", auth);
|
||||
|
||||
//Connecting to Redis server on localhost
|
||||
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 (RemoteException e) {
|
||||
Server.logger.write("SERVER: RMI authentication service error (Remote exception)");
|
||||
} 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 ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +1,76 @@
|
|||
package com.texttwist.server.components;
|
||||
|
||||
import models.User;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Created by loke on 18/06/2017.
|
||||
*/
|
||||
public class AccountsManager {
|
||||
|
||||
public List<User> users = Collections.synchronizedList(new ArrayList<User>());
|
||||
|
||||
private static class Holder {
|
||||
static final AccountsManager INSTANCE = new AccountsManager();
|
||||
}
|
||||
|
||||
public static AccountsManager getInstance() {
|
||||
return AccountsManager.Holder.INSTANCE;
|
||||
}
|
||||
|
||||
private AccountsManager(){
|
||||
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);
|
||||
Boolean res = users.add(newUser);
|
||||
JedisService.add("users", newUser);
|
||||
return res;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists(String userName) {
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (i.next().userName.equals(userName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public boolean checkPassword(String userName, String password) {
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
User account = i.next();
|
||||
if (account.userName.equals(userName) && account.password.equals(password)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public User findUser(String userName){
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
User u = i.next();
|
||||
if (u.userName.equals(userName)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int size(){
|
||||
return users.size();
|
||||
}
|
||||
|
||||
}
|
||||
package com.texttwist.server.models;
|
||||
|
||||
import com.texttwist.server.services.JedisService;
|
||||
import models.User;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 18/06/2017.
|
||||
* Description: Accounts
|
||||
*/
|
||||
public class Accounts {
|
||||
|
||||
public List<User> users = Collections.synchronizedList(new ArrayList<User>());
|
||||
|
||||
private static class Holder {
|
||||
static final Accounts INSTANCE = new Accounts();
|
||||
}
|
||||
|
||||
public static Accounts getInstance() {
|
||||
return Accounts.Holder.INSTANCE;
|
||||
}
|
||||
|
||||
private Accounts(){
|
||||
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);
|
||||
Boolean res = users.add(newUser);
|
||||
JedisService.add("users", newUser);
|
||||
return res;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists(String userName) {
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (i.next().userName.equals(userName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public boolean checkPassword(String userName, String password) {
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
User account = i.next();
|
||||
if (account.userName.equals(userName) && account.password.equals(password)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public User findUser(String userName){
|
||||
Iterator<User> i = users.iterator();
|
||||
while (i.hasNext()) {
|
||||
User u = i.next();
|
||||
if (u.userName.equals(userName)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,19 @@
|
|||
package com.texttwist.server.models;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import javax.swing.*;
|
||||
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.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 {
|
||||
|
||||
static DefaultListModel<String> wordList = new DefaultListModel<>();
|
||||
private Random randomGenerator;
|
||||
private static DefaultListModel<String> wordList = new DefaultListModel<>();
|
||||
|
||||
public Dictionary(String dictionaryPath) {
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(new File(dictionaryPath)))) {
|
||||
|
|
@ -25,15 +21,16 @@ public class Dictionary {
|
|||
wordList.addElement(line);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Server.logger.write("DICTIONARY: Dictionary file not found!");
|
||||
} 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){
|
||||
|
||||
randomGenerator = new Random();
|
||||
Random randomGenerator = new Random();
|
||||
int index = randomGenerator.nextInt(wordList.size());
|
||||
String word = wordList.get(index);
|
||||
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){
|
||||
if(word.equals("")){
|
||||
return true;
|
||||
|
|
@ -66,5 +64,4 @@ public class Dictionary {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,59 @@
|
|||
package com.texttwist.server.models;
|
||||
|
||||
import com.texttwist.server.components.GameServer;
|
||||
import com.texttwist.server.tasks.MatchTimeout;
|
||||
import constants.Config;
|
||||
import com.texttwist.server.Server;
|
||||
import com.texttwist.server.services.MessageService;
|
||||
import com.texttwist.server.tasks.TimeoutMatch;
|
||||
import javafx.util.Pair;
|
||||
import models.Message;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
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 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<>());
|
||||
|
||||
//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){
|
||||
for (int i =0; i < players.size(); i++){
|
||||
this.playersStatus.add(new Pair<>(players.get(i), 0));
|
||||
|
|
@ -44,119 +63,86 @@ public class Match {
|
|||
|
||||
this.multicastId = this.generateMulticastId();
|
||||
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){
|
||||
for (int i = 0; i < matches.size(); i++) {
|
||||
if (matches.get(i).matchCreator.equals(matchName)) {
|
||||
return matches.get(i);
|
||||
for (Match match : matches) {
|
||||
if (match.matchCreator.equals(matchName)) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
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){
|
||||
for (int i = 0; i < matches.size(); i++) {
|
||||
if (matches.get(i).matchCreator.equals(matchName)) {
|
||||
return i;
|
||||
}
|
||||
for (int i = 0; i < matches.size(); i++) {
|
||||
if (matches.get(i).matchCreator.equals(matchName)) {
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean isStarted(){
|
||||
return started;
|
||||
}
|
||||
|
||||
public static Match findMatchByPlayer(String player){
|
||||
for (int i = 0; i < activeMatches.size(); i++) {
|
||||
for (int j = 0; j < activeMatches.get(i).playersStatus.size(); j++) {
|
||||
if (activeMatches.get(i).playersStatus.get(j).getKey().equals(player)) {
|
||||
return activeMatches.get(i);
|
||||
public static Match findMatchByPlayerName(String player){
|
||||
for (Match activeMatch : activeMatches) {
|
||||
for (int j = 0; j < activeMatch.playersStatus.size(); j++) {
|
||||
if (activeMatch.playersStatus.get(j).getKey().equals(player)) {
|
||||
return activeMatch;
|
||||
}
|
||||
}
|
||||
/* if (matches.get(i).matchCreator.equals(matchName)) {
|
||||
return i;
|
||||
}*/
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void startGame(){
|
||||
this.started=true;
|
||||
threadPool.submit(new MatchTimeout(this));
|
||||
|
||||
this.started = true;
|
||||
matchTimeoutThread.submit(new TimeoutMatch(this));
|
||||
}
|
||||
|
||||
public void setScore(String player, Integer score){
|
||||
Match m = findMatchByPlayer(player);
|
||||
m.printAll();
|
||||
|
||||
for (int i = 0; i < m.playersScore.size(); i++) {
|
||||
if (m.playersScore.get(i).getKey().equals(player)) {
|
||||
m.playersScore.set(i, new Pair<String, Integer>(player, score));
|
||||
Match m = findMatchByPlayerName(player);
|
||||
if(m!=null) {
|
||||
for (int i = 0; i < m.playersScore.size(); i++) {
|
||||
if (m.playersScore.get(i).getKey().equals(player)) {
|
||||
m.playersScore.set(i, new Pair<>(player, score));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean allPlayersSendedHisScore(){
|
||||
System.out.println(matchCreator);
|
||||
printAll();
|
||||
for (int i = 0; i < playersScore.size(); i++) {
|
||||
if (playersScore.get(i).getValue() == -1) {
|
||||
return false;
|
||||
}
|
||||
for (Pair<String, Integer> player : playersScore) {
|
||||
if (player.getValue() == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUndefinedScorePlayersToZero(){
|
||||
for (int i = 0; i < playersScore.size(); i++) {
|
||||
if (playersScore.get(i).getValue() == -1) {
|
||||
playersScore.set(i, new Pair<String, Integer>(playersScore.get(i).getKey(), 0));
|
||||
}
|
||||
for (int i = 0; i < playersScore.size(); i++) {
|
||||
if (playersScore.get(i).getValue() == -1) {
|
||||
playersScore.set(i, new Pair<>(playersScore.get(i).getKey(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultListModel<String> getMatchPlayersScoreAsStringList(){
|
||||
DefaultListModel<String> l = new DefaultListModel<>();
|
||||
for (int i = 0; i < playersScore.size(); i++) {
|
||||
l.addElement(playersScore.get(i).getKey() + ":" + playersScore.get(i).getValue());
|
||||
}
|
||||
return l;
|
||||
|
||||
DefaultListModel<String> l = new DefaultListModel<>();
|
||||
for (Pair<String, Integer> player : playersScore) {
|
||||
l.addElement(player.getKey() + ":" + player.getValue());
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
private int generateMulticastId(){
|
||||
return GameServer.multicastID++;
|
||||
return Server.multicastId++;
|
||||
}
|
||||
|
||||
public void setLetters(DefaultListModel<String> letters){
|
||||
this.letters = letters;
|
||||
}
|
||||
|
|
|
|||
68
Server/src/com/texttwist/server/models/Sessions.java
Normal file
68
Server/src/com/texttwist/server/models/Sessions.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +1,84 @@
|
|||
package com.texttwist.server.components;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import interfaces.IAuth;
|
||||
import interfaces.INotificationClient;
|
||||
import models.Response;
|
||||
import org.json.simple.JsonObject;
|
||||
import java.math.BigInteger;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static com.texttwist.server.Server.notificationServer;
|
||||
|
||||
/**
|
||||
* Created by loke on 15/06/2017.
|
||||
*/
|
||||
public class Auth extends UnicastRemoteObject implements IAuth {
|
||||
|
||||
private SecureRandom random = new SecureRandom();
|
||||
public int serverPort = 9999;
|
||||
|
||||
|
||||
public Auth(int serverPort) throws RemoteException{
|
||||
this.serverPort=serverPort;
|
||||
Server.logger.write("Auth Service running at "+serverPort+" port...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response register(String userName, String password) throws RemoteException {
|
||||
Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password);
|
||||
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
|
||||
if(AccountsManager.getInstance().register(userName, password)){
|
||||
Server.logger.write("Registration successfull");
|
||||
return new Response("Registration successfull", 200, null);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response login(String userName, String password) throws RemoteException {
|
||||
Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password);
|
||||
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
|
||||
if(AccountsManager.getInstance().exists(userName) && AccountsManager.getInstance().checkPassword(userName, password)) {
|
||||
JsonObject data = new JsonObject();
|
||||
String token = nextSessionId();
|
||||
data.put("token", token);
|
||||
SessionsManager.getInstance().add(userName,token);
|
||||
Server.logger.write("Login successfull");
|
||||
return new Response("Login successfull", 200, data);
|
||||
}
|
||||
}
|
||||
Server.logger.write("Login unsuccessfull");
|
||||
return new Response("Login unsuccessfull", 400, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response logout(String userName, String token, INotificationClient stub) throws RemoteException {
|
||||
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(res) {
|
||||
Server.logger.write("Logout successfull");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SessionsManager.getInstance().remove(userName);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
package com.texttwist.server.services;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import com.texttwist.server.models.Accounts;
|
||||
import com.texttwist.server.models.Sessions;
|
||||
import constants.Config;
|
||||
import interfaces.IAuth;
|
||||
import interfaces.INotificationClient;
|
||||
import models.Response;
|
||||
import org.json.simple.JsonObject;
|
||||
import java.math.BigInteger;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static com.texttwist.server.Server.notificationServer;
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 15/06/2017.
|
||||
* Description: AuthService
|
||||
*/
|
||||
public class AuthService extends UnicastRemoteObject implements IAuth {
|
||||
|
||||
private SecureRandom random = new SecureRandom();
|
||||
|
||||
public AuthService() throws RemoteException{
|
||||
Server.logger.write("AuthService Service running at "+ Config.AuthServicePort +" port...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response register(String userName, String password) throws RemoteException {
|
||||
Server.logger.write("Invoked register with username=" + userName + " AND " + " password=" + password);
|
||||
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
|
||||
if(Accounts.getInstance().register(userName, password)){
|
||||
Server.logger.write("Registration successfull");
|
||||
return new Response("Registration successfull", 200, null);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response login(String userName, String password) throws RemoteException {
|
||||
Server.logger.write("Invoked login with username=" + userName + " AND " + " password=" + password);
|
||||
if ((userName != null && !userName.isEmpty()) && (password != null && !password.equals(""))) {
|
||||
if(Accounts.getInstance().exists(userName) && Accounts.getInstance().checkPassword(userName, password)) {
|
||||
JsonObject data = new JsonObject();
|
||||
String token = nextSessionId();
|
||||
data.put("token", token);
|
||||
Sessions.getInstance().add(userName,token);
|
||||
Server.logger.write("Login successfull");
|
||||
return new Response("Login successfull", 200, data);
|
||||
}
|
||||
}
|
||||
Server.logger.write("Login unsuccessfull");
|
||||
return new Response("Login unsuccessfull", 400, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response logout(String userName, String token, INotificationClient stub) throws RemoteException {
|
||||
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 = Sessions.getInstance().remove(userName);
|
||||
if(res) {
|
||||
Server.logger.write("Logout successfull");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Sessions.getInstance().remove(userName);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.texttwist.server.components;
|
||||
package com.texttwist.server.services;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import models.User;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
|
@ -12,12 +12,14 @@ import java.util.List;
|
|||
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 JedisService(){
|
||||
|
||||
JedisService(){
|
||||
Server.logger.write("Jedis Service running on localhost...");
|
||||
}
|
||||
|
||||
/** Read the object from Base64 string. */
|
||||
|
|
@ -57,11 +59,8 @@ public class JedisService {
|
|||
Jedis jedis = null;
|
||||
List<Serializable> l = new ArrayList<>();
|
||||
try {
|
||||
System.out.println("USER ss");
|
||||
|
||||
jedis = jedisPool.getResource();
|
||||
String usersString = jedis.get(key);
|
||||
System.out.println("USER "+usersString);
|
||||
if(usersString!=null) {
|
||||
String[] lines = usersString.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
|
|
@ -1,138 +1,106 @@
|
|||
|
||||
package com.texttwist.server.components;
|
||||
import com.texttwist.client.App;
|
||||
import com.texttwist.server.Server;
|
||||
import com.texttwist.server.models.Dictionary;
|
||||
import com.texttwist.server.models.Match;
|
||||
import com.texttwist.server.tasks.ReceiveWords;
|
||||
import constants.Config;
|
||||
import models.Message;
|
||||
import utilities.Logger;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static java.nio.channels.SelectionKey.OP_ACCEPT;
|
||||
import static java.nio.channels.SelectionKey.OP_READ;
|
||||
|
||||
public class GameServer implements Runnable{
|
||||
|
||||
private int serverPort;
|
||||
private ThreadProxy proxy;
|
||||
private ReceiveWords wordsReceiver;
|
||||
|
||||
private DatagramChannel datagramChannel;
|
||||
private Selector selector = null;
|
||||
private ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
private String dictionaryPath = "./Server/resources/dictionary";
|
||||
public static Dictionary dict;
|
||||
SocketChannel client;
|
||||
ByteBuffer bufferWords = ByteBuffer.allocate(1024);
|
||||
ByteBuffer bufferMessages = ByteBuffer.allocate(1024);
|
||||
|
||||
|
||||
|
||||
public static List<Match> activeMatches = Collections.synchronizedList(new ArrayList<>());
|
||||
public static Integer multicastID = 4000;
|
||||
|
||||
public GameServer(int port){
|
||||
this.serverPort = port;
|
||||
}
|
||||
|
||||
public void run(){
|
||||
|
||||
dict = new Dictionary(dictionaryPath);
|
||||
try {
|
||||
selector = Selector.open();
|
||||
|
||||
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
|
||||
serverSocketChannel.configureBlocking(false);
|
||||
serverSocketChannel.socket().bind(new InetSocketAddress(serverPort));
|
||||
serverSocketChannel.register(selector, OP_ACCEPT);
|
||||
InetSocketAddress address = new InetSocketAddress(Config.WordsReceiverServerURI,Config.WordsReceiverServerPort);
|
||||
datagramChannel = DatagramChannel.open();
|
||||
datagramChannel.configureBlocking(true);
|
||||
datagramChannel.connect(address);
|
||||
Server.logger.write("GameService Service is running at "+this.serverPort+" port...");
|
||||
|
||||
wordsReceiver = new ReceiveWords(datagramChannel, bufferWords, bufferMessages, client);
|
||||
threadPool.submit(wordsReceiver);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
System.out.println("WAITING FOR MSG");
|
||||
try {
|
||||
selector.select();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
|
||||
while (iter.hasNext()) {
|
||||
bufferMessages = ByteBuffer.allocate(1024);
|
||||
bufferMessages.clear();
|
||||
client = null;
|
||||
SelectionKey key = iter.next();
|
||||
iter.remove();
|
||||
|
||||
try {
|
||||
switch (key.readyOps()) {
|
||||
case OP_ACCEPT:
|
||||
client = ((ServerSocketChannel) key.channel()).accept();
|
||||
client.configureBlocking(false);
|
||||
client.register(selector, OP_READ);
|
||||
break;
|
||||
|
||||
case OP_READ:
|
||||
client = (SocketChannel) key.channel();
|
||||
if (client.read(bufferMessages) != -1) {
|
||||
bufferMessages.flip();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.texttwist.server.services;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import com.texttwist.server.tasks.MessageDispatcher;
|
||||
import com.texttwist.server.models.Dictionary;
|
||||
import constants.Config;
|
||||
import models.Message;
|
||||
import java.net.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import static java.nio.channels.SelectionKey.OP_ACCEPT;
|
||||
import static java.nio.channels.SelectionKey.OP_READ;
|
||||
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 17/06/2017.
|
||||
* Description: Message Service
|
||||
*/
|
||||
public class MessageService implements Runnable{
|
||||
|
||||
private Selector selector = null;
|
||||
private ExecutorService dispatcherPool = Executors.newCachedThreadPool();
|
||||
|
||||
public MessageService()
|
||||
{
|
||||
try {
|
||||
selector = Selector.open();
|
||||
|
||||
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
|
||||
serverSocketChannel.configureBlocking(false);
|
||||
serverSocketChannel.socket().bind(new InetSocketAddress(Config.MessageServicePort));
|
||||
serverSocketChannel.register(selector, OP_ACCEPT);
|
||||
Server.logger.write("Message Service is running at "+Config.MessageServicePort +" port...");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void run(){
|
||||
while (true) {
|
||||
try {
|
||||
selector.select();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
|
||||
while (iter.hasNext()) {
|
||||
ByteBuffer bufferMessages = ByteBuffer.allocate(1024);
|
||||
bufferMessages.clear();
|
||||
SocketChannel client = null;
|
||||
SelectionKey key = iter.next();
|
||||
iter.remove();
|
||||
|
||||
try {
|
||||
switch (key.readyOps()) {
|
||||
case OP_ACCEPT:
|
||||
client = ((ServerSocketChannel) key.channel()).accept();
|
||||
client.configureBlocking(false);
|
||||
client.register(selector, OP_READ);
|
||||
break;
|
||||
|
||||
case OP_READ:
|
||||
client = (SocketChannel) key.channel();
|
||||
if (client.read(bufferMessages) != -1) {
|
||||
bufferMessages.flip();
|
||||
String line = new String(bufferMessages.array(), bufferMessages.position(), bufferMessages.remaining());
|
||||
if (line.startsWith("MESSAGE")) {
|
||||
Message msg = Message.toMessage(line);
|
||||
MessageDispatcher proxy = new MessageDispatcher(msg, client, bufferMessages);
|
||||
dispatcherPool.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +1,54 @@
|
|||
package com.texttwist.server.components;
|
||||
|
||||
import interfaces.INotificationClient;
|
||||
import interfaces.INotificationServer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Created by loke on 19/06/2017.
|
||||
*/
|
||||
public class NotificationServer implements INotificationServer {
|
||||
|
||||
private List<INotificationClient> clients;
|
||||
public NotificationServer() throws RemoteException {
|
||||
super();
|
||||
clients = new ArrayList<>();
|
||||
}
|
||||
|
||||
public synchronized void registerForCallback(INotificationClient clientInterface) throws RemoteException {
|
||||
if(!clients.contains(clientInterface)){
|
||||
clients.add(clientInterface);
|
||||
System.out.println(clientInterface);
|
||||
System.out.println("New client registered");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void unregisterForCallback(INotificationClient client) throws RemoteException {
|
||||
if (clients.remove(client)) {
|
||||
System.out.println("Client unregistered");
|
||||
} else {
|
||||
System.out.println("Unable to unregister client");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized void sendInvitations(String username, DefaultListModel<String> users){
|
||||
Iterator i = clients.iterator();
|
||||
INotificationClient client = null;
|
||||
System.out.println("Starting callbacks");
|
||||
while (i.hasNext()) {
|
||||
client = (INotificationClient) i.next();
|
||||
try {
|
||||
|
||||
System.out.println("SENDING INVITE TO "+users);
|
||||
client.sendInvite(username, users);
|
||||
} catch (RemoteException e) {
|
||||
System.out.println("Sembra down");
|
||||
try {
|
||||
unregisterForCallback(client);
|
||||
} catch (RemoteException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
package com.texttwist.server.services;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import constants.Config;
|
||||
import interfaces.INotificationClient;
|
||||
import interfaces.INotificationServer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 19/06/2017.
|
||||
* Description: Notification Service
|
||||
*/
|
||||
public class NotificationService implements INotificationServer {
|
||||
|
||||
private List<INotificationClient> clients;
|
||||
public NotificationService() throws RemoteException {
|
||||
super();
|
||||
Server.logger.write("Notification Service running at "+ Config.NotificationServicePort +" port...");
|
||||
clients = new ArrayList<>();
|
||||
}
|
||||
|
||||
public synchronized void registerForCallback(INotificationClient clientInterface) throws RemoteException {
|
||||
if(!clients.contains(clientInterface)){
|
||||
clients.add(clientInterface);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void unregisterForCallback(INotificationClient client) throws RemoteException {
|
||||
clients.remove(client);
|
||||
}
|
||||
|
||||
public synchronized void sendInvitations(String username, DefaultListModel<String> users){
|
||||
Iterator i = clients.iterator();
|
||||
INotificationClient client = null;
|
||||
while (i.hasNext()) {
|
||||
client = (INotificationClient) i.next();
|
||||
try {
|
||||
client.sendInvite(username, users);
|
||||
} catch (RemoteException e) {
|
||||
try {
|
||||
unregisterForCallback(client);
|
||||
} catch (RemoteException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
package com.texttwist.server.tasks;
|
||||
|
||||
import com.texttwist.server.components.SessionsManager;
|
||||
import com.texttwist.server.models.Sessions;
|
||||
|
||||
import javax.swing.*;
|
||||
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> {
|
||||
private final DefaultListModel<String> users;
|
||||
|
|
@ -18,7 +19,7 @@ public class CheckOnlineUsers implements Callable<Boolean> {
|
|||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
for(int i = 0; i < users.size(); i++){
|
||||
if(!(SessionsManager.getInstance().exists(users.get(i)))){
|
||||
if(!(Sessions.getInstance().exists(users.get(i)))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,33 @@
|
|||
package com.texttwist.server.tasks;
|
||||
|
||||
import com.texttwist.server.components.AccountsManager;
|
||||
import com.texttwist.server.components.JedisService;
|
||||
import com.texttwist.server.models.Accounts;
|
||||
import com.texttwist.server.services.JedisService;
|
||||
import models.User;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
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 ComputeHighscores(){}
|
||||
|
||||
@Override
|
||||
public DefaultListModel<String> call() throws Exception {
|
||||
DefaultListModel<String> l = new DefaultListModel<>();
|
||||
|
||||
AccountsManager.getInstance().users.sort(new Comparator<User>() {
|
||||
Accounts.getInstance().users.sort(new Comparator<User>() {
|
||||
@Override
|
||||
public int compare(User o1, User o2) {
|
||||
return o2.score.compareTo(o1.score);
|
||||
}
|
||||
});
|
||||
JedisService.removeAll("users");
|
||||
for(int i =0; i< AccountsManager.getInstance().users.size(); i++){
|
||||
l.addElement(AccountsManager.getInstance().users.get(i).userName+":"+AccountsManager.getInstance().users.get(i).score);
|
||||
JedisService.add("users",AccountsManager.getInstance().users.get(i));
|
||||
for(int i = 0; i< Accounts.getInstance().users.size(); i++){
|
||||
l.addElement(Accounts.getInstance().users.get(i).userName+":"+ Accounts.getInstance().users.get(i).score);
|
||||
JedisService.add("users", Accounts.getInstance().users.get(i));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,22 @@
|
|||
package com.texttwist.server.tasks;
|
||||
import com.texttwist.client.App;
|
||||
import com.texttwist.server.components.AccountsManager;
|
||||
import com.texttwist.server.components.JedisService;
|
||||
|
||||
import com.texttwist.server.models.Accounts;
|
||||
import com.texttwist.server.models.Dictionary;
|
||||
import com.texttwist.server.models.Match;
|
||||
import constants.Config;
|
||||
import models.Message;
|
||||
import models.User;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
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 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 DefaultListModel<String> words;
|
||||
public final String sender;
|
||||
private DefaultListModel<String> words;
|
||||
private final String sender;
|
||||
public Match match;
|
||||
public DefaultListModel<String> wordsValid;
|
||||
private DefaultListModel<String> wordsValid = new DefaultListModel<>();
|
||||
|
||||
public ComputeScore(String sender, DefaultListModel<String> words, Match match){
|
||||
this.words = words;
|
||||
|
|
@ -37,36 +26,26 @@ public class ComputeScore implements Callable<Integer> {
|
|||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
wordsValid = new DefaultListModel<>();
|
||||
Integer score = 0;
|
||||
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
if (isValid(words.get(i), match.letters)) {
|
||||
score += words.get(i).length();
|
||||
System.out.println(words.get(i) + " is valid!" + " : " + score );
|
||||
wordsValid.addElement(words.get(i));
|
||||
}
|
||||
//Compute the score depending on the size of the words
|
||||
Integer score = 0;
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
if (isValid(words.get(i), match.letters)) {
|
||||
score += words.get(i).length();
|
||||
wordsValid.addElement(words.get(i));
|
||||
}
|
||||
}
|
||||
match.setScore(sender, score);
|
||||
|
||||
System.out.println(sender +" totalize SCORE = " + score);
|
||||
match.setScore(sender, 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;
|
||||
|
||||
User u = Accounts.getInstance().findUser(sender);
|
||||
u.addScore(score);
|
||||
|
||||
if(match.allPlayersSendedHisScore()) {
|
||||
match.matchTimeout = false;
|
||||
match.setUndefinedScorePlayersToZero();
|
||||
new SendFinalScores(match).call();
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
private Boolean isValid(String word, DefaultListModel<String> letters) {
|
||||
|
|
@ -81,7 +60,6 @@ public class ComputeScore implements Callable<Integer> {
|
|||
if(word.equals("")){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!isCharacterPresent || wordsValid.indexOf(word)!=-1){
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,21 @@
|
|||
package com.texttwist.server.tasks;
|
||||
|
||||
import com.texttwist.server.components.GameServer;
|
||||
import com.texttwist.server.Server;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 GenerateLetters(){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
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++){
|
||||
l.addElement(String.valueOf(word.charAt(i)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@ import javafx.util.Pair;
|
|||
import javax.swing.*;
|
||||
import java.nio.channels.SocketChannel;
|
||||
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 final String matchName;
|
||||
public final String playerName;
|
||||
public final SocketChannel socketChannel;
|
||||
private final String matchName;
|
||||
private final String playerName;
|
||||
private final SocketChannel socketChannel;
|
||||
|
||||
public JoinMatch(String playerName, DefaultListModel<String> matchName, SocketChannel socketChannel) {
|
||||
this.playerName = playerName;
|
||||
|
|
@ -23,32 +23,20 @@ public class JoinMatch implements Callable<Boolean> {
|
|||
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
final Match thisMatch = Match.findMatch(activeMatches, this.matchName);
|
||||
if (thisMatch != null) {
|
||||
for (int j = 0; j < thisMatch.playersStatus.size(); j++) {
|
||||
String name = thisMatch.playersStatus.get(j).getKey();
|
||||
if (name.equals(playerName)) {
|
||||
thisMatch.playersStatus.remove(j);
|
||||
thisMatch.playersStatus.add(new Pair<>(name, 1));
|
||||
thisMatch.playersSocket.remove(j);
|
||||
thisMatch.playersSocket.add(new Pair<>(name, socketChannel));
|
||||
return allJoined(thisMatch);
|
||||
}
|
||||
final Match thisMatch = Match.findMatch(Match.activeMatches, this.matchName);
|
||||
if (thisMatch != null) {
|
||||
for (int j = 0; j < thisMatch.playersStatus.size(); j++) {
|
||||
String name = thisMatch.playersStatus.get(j).getKey();
|
||||
if (name.equals(playerName)) {
|
||||
thisMatch.playersStatus.remove(j);
|
||||
thisMatch.playersStatus.add(new Pair<>(name, 1));
|
||||
thisMatch.playersSocket.remove(j);
|
||||
thisMatch.playersSocket.add(new Pair<>(name, socketChannel));
|
||||
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) {
|
||||
|
|
@ -57,7 +45,7 @@ public class JoinMatch implements Callable<Boolean> {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
match.joinTimeout=false;
|
||||
match.joinTimeout = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,221 +1,203 @@
|
|||
package com.texttwist.server.components;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||
import com.texttwist.client.App;
|
||||
import com.texttwist.server.models.Match;
|
||||
import com.texttwist.server.tasks.*;
|
||||
import constants.Config;
|
||||
import javafx.util.Pair;
|
||||
import models.Message;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static com.texttwist.server.components.GameServer.activeMatches;
|
||||
|
||||
/**
|
||||
* Created by loke on 18/06/2017.
|
||||
*/
|
||||
public class ThreadProxy implements Callable<Boolean> {
|
||||
protected final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
private final Message request;
|
||||
private final SocketChannel socketChannel;
|
||||
private ByteBuffer bufferMessage;
|
||||
boolean matchNotAvailable =false;
|
||||
|
||||
|
||||
ThreadProxy(Message request, SocketChannel socketChannel, ByteBuffer bufferMessage) {
|
||||
this.request = request;
|
||||
this.socketChannel = socketChannel;
|
||||
this.bufferMessage = bufferMessage;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean call() {
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
byte[] byteMessage = null;
|
||||
if(SessionsManager.getInstance().isValidToken(request.token)){
|
||||
switch(request.message){
|
||||
case "START_GAME":
|
||||
Future<Boolean> onlineUsers = threadPool.submit(new CheckOnlineUsers(request.data));
|
||||
try {
|
||||
Boolean usersOnline = onlineUsers.get();
|
||||
if(usersOnline){
|
||||
Future<Boolean> sendInvitations = threadPool.submit(new SendInvitations(request.sender, request.data));
|
||||
try {
|
||||
Boolean invitationSended = sendInvitations.get();
|
||||
if (invitationSended) {
|
||||
|
||||
//Crea nuova partita e attendi i giocatori
|
||||
request.data.addElement(request.sender);
|
||||
final Match match = new Match(request.sender, request.data);
|
||||
match.printAll();
|
||||
|
||||
activeMatches.add(match);
|
||||
|
||||
DefaultListModel<String> matchName = new DefaultListModel<>();
|
||||
matchName.addElement(request.sender);
|
||||
|
||||
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, matchName, socketChannel));
|
||||
Boolean joinMatchRes = joinMatch.get();
|
||||
|
||||
if(!joinMatchRes){
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
//NON FARE NULLA, ASPETTA GLI ALTRI
|
||||
Message message = new Message("INVITES_ALL_SENDED", "", "", new DefaultListModel<>());
|
||||
byteMessage = message.toString().getBytes();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
socketChannel.write(bufferMessage);
|
||||
}
|
||||
|
||||
Future<Boolean> joinTimeout = threadPool.submit(new JoinTimeout(match));
|
||||
joinTimeout.get();
|
||||
if(match.joinTimeout){
|
||||
Future<Boolean> sendMessageJoinTimeout = threadPool.submit(
|
||||
new SendMessageToAllPlayers(match, new Message("JOIN_TIMEOUT", "", "", new DefaultListModel<>()), socketChannel));
|
||||
Boolean sendMessageJoinTimeoutRes = sendMessageJoinTimeout.get();
|
||||
if(!sendMessageJoinTimeoutRes){
|
||||
activeMatches.remove(Match.findMatchIndex(activeMatches, match.matchCreator));
|
||||
return sendMessageJoinTimeoutRes;
|
||||
}
|
||||
} else {
|
||||
System.out.println("TIMEOUT FINITO SENZA EFFETTI");
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
|
||||
Message message = new Message("USER_NOT_ONLINE", "", "", new DefaultListModel<>());
|
||||
byteMessage = new String(message.toString()).getBytes();
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
this.socketChannel.write(bufferMessage);
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
case "FETCH_HIGHSCORES":
|
||||
Future<DefaultListModel<String>> computeHighscores = threadPool.submit(new ComputeHighscores());
|
||||
try {
|
||||
DefaultListModel<String> computeHighscoresRes = computeHighscores.get();
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
Message message = new Message("HIGHSCORES", "", "", computeHighscoresRes);
|
||||
byteMessage = message.toString().getBytes();
|
||||
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
try {
|
||||
String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining());
|
||||
System.out.println("INVIO HIGHSCORES "+ s);
|
||||
socketChannel.write(bufferMessage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
case "JOIN_GAME":
|
||||
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, request.data, socketChannel));
|
||||
try {
|
||||
Match match = Match.findMatch(activeMatches, request.data.get(0));;
|
||||
Boolean joinMatchRes = joinMatch.get();
|
||||
if(joinMatchRes){
|
||||
|
||||
if(!match.joinTimeout) {
|
||||
Future<DefaultListModel<String>> generateLetters = threadPool.submit(new GenerateLetters());
|
||||
match.setLetters(generateLetters.get());
|
||||
match.letters.addElement(String.valueOf(match.multicastId));
|
||||
|
||||
for (int i = 0; i < match.playersSocket.size(); i++) {
|
||||
SocketChannel socketClient = match.playersSocket.get(i).getValue();
|
||||
if (socketClient != null) {
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
Message message = new Message("GAME_STARTED", "", "", match.letters);
|
||||
match.startGame();
|
||||
|
||||
System.out.println("TIMEOUT CANCELLEd");
|
||||
byteMessage = message.toString().getBytes();
|
||||
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
try {
|
||||
String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining());
|
||||
System.out.println("INVIO GAME_STARTED "+ s);
|
||||
socketClient.write(bufferMessage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (matchNotAvailable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(match == null){
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
if (socketChannel != null) {
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>());
|
||||
bufferMessage.clear();
|
||||
byteMessage = msg.toString().getBytes();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
socketChannel.write(bufferMessage);
|
||||
matchNotAvailable = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
package com.texttwist.server.tasks;
|
||||
|
||||
import com.texttwist.server.Server;
|
||||
import com.texttwist.server.models.Sessions;
|
||||
import com.texttwist.server.models.Match;
|
||||
import com.texttwist.server.tasks.*;
|
||||
import models.Message;
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
|
||||
/**
|
||||
* Author: Lorenzo Iovino on 18/06/2017.
|
||||
* Description: Message Dispatcher
|
||||
* */
|
||||
public class MessageDispatcher implements Callable<Boolean> {
|
||||
private final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
private final Message request;
|
||||
private final SocketChannel socketChannel;
|
||||
private ByteBuffer bufferMessage;
|
||||
private boolean matchNotAvailable = false;
|
||||
|
||||
public MessageDispatcher(Message request, SocketChannel socketChannel, ByteBuffer bufferMessage) {
|
||||
this.request = request;
|
||||
this.socketChannel = socketChannel;
|
||||
this.bufferMessage = bufferMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean call() {
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
byte[] byteMessage = null;
|
||||
if(Sessions.getInstance().isValidToken(request.token)){
|
||||
switch(request.message){
|
||||
|
||||
case "START_GAME":
|
||||
Future<Boolean> onlineUsers = threadPool.submit(new CheckOnlineUsers(request.data));
|
||||
try {
|
||||
//Check if invited users are online
|
||||
Boolean usersOnline = onlineUsers.get();
|
||||
if(usersOnline){
|
||||
Future<Boolean> sendInvitations = threadPool.submit(new SendInvitations(request.sender, request.data));
|
||||
Boolean invitationSended = sendInvitations.get();
|
||||
if (invitationSended) {
|
||||
|
||||
//Server create new match
|
||||
request.data.addElement(request.sender);
|
||||
final Match match = new Match(request.sender, request.data);
|
||||
Match.activeMatches.add(match);
|
||||
|
||||
DefaultListModel<String> matchName = new DefaultListModel<>();
|
||||
matchName.addElement(request.sender);
|
||||
|
||||
//Match creator join match
|
||||
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, matchName, socketChannel));
|
||||
Boolean joinMatchRes = joinMatch.get();
|
||||
|
||||
//Notify to the client that invites was sents correctly
|
||||
if(!joinMatchRes){
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
Message message = new Message("INVITES_ALL_SENDED", "", "", new DefaultListModel<>());
|
||||
byteMessage = message.toString().getBytes();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
socketChannel.write(bufferMessage);
|
||||
}
|
||||
|
||||
//Starts to wait until all player joins
|
||||
Future<Boolean> joinTimeout = threadPool.submit(new TimeoutJoin(match));
|
||||
Boolean joinTimeoutRes = joinTimeout.get();
|
||||
//If joinTimeoutRes==true timeout happen, need to notify to all waiting clients
|
||||
if(joinTimeoutRes){
|
||||
Future<Boolean> sendMessageToAllPlayers = threadPool.submit(
|
||||
new SendMessageToAllPlayers(match,
|
||||
new Message("JOIN_TIMEOUT", "", "", new DefaultListModel<>()), socketChannel));
|
||||
Boolean sendMessageToAllPlayersRes = sendMessageToAllPlayers.get();
|
||||
if(!sendMessageToAllPlayersRes){
|
||||
Match.activeMatches.remove(Match.findMatchIndex(Match.activeMatches, match.matchCreator));
|
||||
return sendMessageToAllPlayersRes;
|
||||
}
|
||||
} else {
|
||||
//All done, all player joined
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Some user in the list is not online
|
||||
Message message = new Message("USER_NOT_ONLINE", "", "", new DefaultListModel<>());
|
||||
byteMessage = message.toString().getBytes();
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
this.socketChannel.write(bufferMessage);
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - START GAME: InterruptedException");
|
||||
} catch (ExecutionException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - START GAME: ExecutionException");
|
||||
} catch (IOException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - START GAME: IOException");
|
||||
}
|
||||
|
||||
case "FETCH_HIGHSCORES":
|
||||
//Fetch hisghscore and send back to client
|
||||
Future<DefaultListModel<String>> computeHighscores = threadPool.submit(new ComputeHighscores());
|
||||
try {
|
||||
DefaultListModel<String> computeHighscoresRes = computeHighscores.get();
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
Message message = new Message("HIGHSCORES", "", "", computeHighscoresRes);
|
||||
byteMessage = message.toString().getBytes();
|
||||
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
try {
|
||||
socketChannel.write(bufferMessage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
} catch (InterruptedException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - FETCH HIGHSCORES: InterruptedException");
|
||||
} catch (ExecutionException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - FETCH HIGHSCORES: ExecutionException");
|
||||
}
|
||||
|
||||
case "JOIN_GAME":
|
||||
//An user joined the game
|
||||
Future<Boolean> joinMatch = threadPool.submit(new JoinMatch(request.sender, request.data, socketChannel));
|
||||
try {
|
||||
Match match = Match.findMatch(Match.activeMatches, request.data.get(0));;
|
||||
Boolean joinMatchRes = joinMatch.get();
|
||||
|
||||
//If joinMatchRes=true start the game! Because all player joined
|
||||
if(joinMatchRes){
|
||||
|
||||
//If match not fired join timeout, notify all player that game is started
|
||||
if(!match.joinTimeout) {
|
||||
|
||||
//Generate letters to send to clients
|
||||
Future<DefaultListModel<String>> generateLetters = threadPool.submit(new GenerateLetters());
|
||||
match.setLetters(generateLetters.get());
|
||||
match.letters.addElement(String.valueOf(match.multicastId));
|
||||
|
||||
for (int i = 0; i < match.playersSocket.size(); i++) {
|
||||
SocketChannel socketClient = match.playersSocket.get(i).getValue();
|
||||
if (socketClient != null) {
|
||||
bufferMessage.clear();
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
Message message = new Message("GAME_STARTED", "", "", match.letters);
|
||||
match.startGame();
|
||||
byteMessage = message.toString().getBytes();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
try {
|
||||
String s = new String(bufferMessage.array(), bufferMessage.position(), bufferMessage.remaining());
|
||||
socketClient.write(bufferMessage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchNotAvailable) {
|
||||
matchNotAvailable = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Match doesn't exist more because a timeout happen
|
||||
if(match == null){
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
|
||||
if (socketChannel != null) {
|
||||
bufferMessage = ByteBuffer.allocate(1024);
|
||||
Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>());
|
||||
bufferMessage.clear();
|
||||
byteMessage = msg.toString().getBytes();
|
||||
bufferMessage = ByteBuffer.wrap(byteMessage);
|
||||
socketChannel.write(bufferMessage);
|
||||
matchNotAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: InterruptedException");
|
||||
} catch (ExecutionException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: ExecutionException");
|
||||
} catch (IOException e) {
|
||||
Server.logger.write("MESSAGE DISPATCHER - JOIN GAME: IOException");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//If token is invalid, return error message to client
|
||||
threadPool.submit(new TokenInvalid(request.sender, socketChannel, bufferMessage));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
41
Server/src/com/texttwist/server/tasks/SendFinalScores.java
Normal file
41
Server/src/com/texttwist/server/tasks/SendFinalScores.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
package com.texttwist.server.tasks;
|
||||
|
||||
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 java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
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> {
|
||||
private DefaultListModel<String> users;
|
||||
|
|
@ -27,15 +20,10 @@ public class SendInvitations implements Callable<Boolean> {
|
|||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
try {
|
||||
System.out.println("INVIA INVITO A" + users);
|
||||
|
||||
Server.notificationServer.sendInvitations(sender, users);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Eccezione" + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,21 +2,21 @@ package com.texttwist.server.tasks;
|
|||
|
||||
import com.texttwist.server.models.Match;
|
||||
import models.Message;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
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 final Match match;
|
||||
public final Message message;
|
||||
public SocketChannel socketChannel;
|
||||
private final Message message;
|
||||
private SocketChannel socketChannel;
|
||||
|
||||
public SendMessageToAllPlayers(Match match, Message message, SocketChannel socketChannel){
|
||||
this.match = match;
|
||||
this.message = message;
|
||||
|
|
@ -36,10 +36,8 @@ public class SendMessageToAllPlayers implements Callable<Boolean> {
|
|||
buffer = ByteBuffer.wrap(byteMessage);
|
||||
socketChannel.write(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,34 @@
|
|||
package com.texttwist.server.tasks;
|
||||
import com.texttwist.server.models.Match;
|
||||
import constants.Config;
|
||||
|
||||
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 JoinTimeout(Match match) {
|
||||
public TimeoutJoin(Match match) {
|
||||
this.match = match;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
try {
|
||||
Thread.currentThread().sleep(7*60*1000);
|
||||
System.out.println("TIMEOUTTTT");
|
||||
match.joinTimeout = true;
|
||||
Thread.currentThread().sleep(Config.joinMatchTimeout);
|
||||
|
||||
if(match.joinTimeout) {
|
||||
return false;
|
||||
match.joinTimeout = false;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
match.joinTimeout = false;
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
37
Server/src/com/texttwist/server/tasks/TimeoutMatch.java
Normal file
37
Server/src/com/texttwist/server/tasks/TimeoutMatch.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -5,14 +5,14 @@ import models.Message;
|
|||
|
||||
import javax.swing.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
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 ByteBuffer buffer;
|
||||
private SocketChannel channel;
|
||||
|
|
@ -24,15 +24,14 @@ public class TokenInvalid implements Callable<Boolean> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean call()throws Exception {
|
||||
System.out.print("TOKEN NON VALIDO");
|
||||
buffer = ByteBuffer.allocate(1024);
|
||||
Message msg = new Message("MATCH_NOT_AVAILABLE", "", null, new DefaultListModel<>());
|
||||
public Void call()throws Exception {
|
||||
Server.logger.write("TOKEN INVALID: TOKEN USED BY "+ sender+ " IS NOT VALID");
|
||||
Message msg = new Message("TOKEN_NOT_VALID", "", null, new DefaultListModel<>());
|
||||
buffer.clear();
|
||||
byte[] byteMessage = msg.toString().getBytes();
|
||||
buffer = ByteBuffer.wrap(byteMessage);
|
||||
channel.write(buffer);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
TwistText.pdf
Normal file
BIN
TwistText.pdf
Normal file
Binary file not shown.
BIN
TwistText_JarFiles.zip
Normal file
BIN
TwistText_JarFiles.zip
Normal file
Binary file not shown.
9134
client_1.log
9134
client_1.log
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
9820
server.log
9820
server.log
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue