diff options
Diffstat (limited to 'api/src')
| -rw-r--r-- | api/src/main/java/akkamon/api/AkkamonSession.java | 12 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/App.java | 46 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/EventSocket.java | 31 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/MessagingEngine.java | 117 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/models/Event.java | 14 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/models/GameState.java | 33 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/models/Player.java | 13 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/models/Position.java | 11 | ||||
| -rw-r--r-- | api/src/main/java/akkamon/api/models/User.java | 11 | ||||
| -rw-r--r-- | api/src/test/java/akkamon/api/EventSocketTest.java | 7 | ||||
| -rw-r--r-- | api/src/test/java/akkamon/api/MessagingEngineTest.java | 7 |
11 files changed, 288 insertions, 14 deletions
diff --git a/api/src/main/java/akkamon/api/AkkamonSession.java b/api/src/main/java/akkamon/api/AkkamonSession.java new file mode 100644 index 0000000..217c8d8 --- /dev/null +++ b/api/src/main/java/akkamon/api/AkkamonSession.java @@ -0,0 +1,12 @@ +package akkamon.api; + +import akkamon.api.models.User; + +public interface AkkamonSession { + + void receiveGameState(String gameState); + + void disconnect(int statusCode, String message); + + void setCurrentUser(User user); +} diff --git a/api/src/main/java/akkamon/api/App.java b/api/src/main/java/akkamon/api/App.java index bc462d0..989562b 100644 --- a/api/src/main/java/akkamon/api/App.java +++ b/api/src/main/java/akkamon/api/App.java @@ -3,21 +3,18 @@ package akkamon.api; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.glassfish.jersey.servlet.ServletContainer; public class App { public static void main(String[] args) { - Server server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(8080); - server.addConnector(connector); + Server server = startServer(8080); + ServletContextHandler context = createStatefulContext(server); - // application "context" ? - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/"); - server.setHandler(context); // websocket behaviour // Configure specific websocket behavior @@ -30,8 +27,13 @@ public class App { wsContainer.addMapping("/", EventSocket.class); }); + // registerServlets(context); + try { server.start(); + System.out.println("Started server."); + System.out.println("Listening on http://localhost:8080/"); + System.out.println("Press CTRL+C to exit."); server.join(); } catch (Throwable t) { @@ -39,4 +41,32 @@ public class App { } } + + private static ServletContextHandler createStatefulContext(Server server) { + ServletContextHandler context = + new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + server.setHandler(context); + return context; + } + + private static Server startServer(int port) { + Server server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(port); + server.addConnector(connector); + return server; + } + + private static void registerServlets(ServletContextHandler context) { + // Use the Jersey framework to translate the classes in the + // mancala.api package to server endpoints (servlets). + // For example, the StartMancala class will become an endpoint at + // http://localost:8080/mancala/api/start + ServletHolder serverHolder = context.addServlet(JettyWebSocketServlet.class, "/"); + serverHolder.setInitOrder(1); + serverHolder.setInitParameter("jersey.config.server.provider.packages", + "akkamon.api"); + } + } diff --git a/api/src/main/java/akkamon/api/EventSocket.java b/api/src/main/java/akkamon/api/EventSocket.java index 1c7bafc..5a2693e 100644 --- a/api/src/main/java/akkamon/api/EventSocket.java +++ b/api/src/main/java/akkamon/api/EventSocket.java @@ -1,16 +1,18 @@ package akkamon.api; -import java.util.Locale; +import java.io.IOException; import java.util.concurrent.CountDownLatch; +import akkamon.api.models.User; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.StatusCode; -public class EventSocket extends WebSocketAdapter { +public class EventSocket extends WebSocketAdapter implements AkkamonSession { private final CountDownLatch closureLatch = new CountDownLatch(1); + public User user; + @Override public void onWebSocketConnect(Session sess) { @@ -23,10 +25,8 @@ public class EventSocket extends WebSocketAdapter { { super.onWebSocketText(message); System.out.println("Received TEXT message: " + message); + MessagingEngine.getInstance().incoming(this, message); - if (message.toLowerCase(Locale.US).contains("bye")) { - getSession().close(StatusCode.NORMAL, "Thanks"); - } } @Override @@ -49,4 +49,23 @@ public class EventSocket extends WebSocketAdapter { System.out.println("Awaiting closure from remote"); closureLatch.await(); } + + @Override + public void receiveGameState(String gameState) { + try { + getRemote().sendString(gameState); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void disconnect(int statusCode, String message) { + getSession().close(statusCode, message); + } + + @Override + public void setCurrentUser(User user) { + this.user = user; + } } diff --git a/api/src/main/java/akkamon/api/MessagingEngine.java b/api/src/main/java/akkamon/api/MessagingEngine.java new file mode 100644 index 0000000..a3cff1d --- /dev/null +++ b/api/src/main/java/akkamon/api/MessagingEngine.java @@ -0,0 +1,117 @@ +package akkamon.api; + +import akkamon.api.models.*; +import akkamon.domain.AkkamonImpl; +import akkamon.domain.Trainer; +import com.google.gson.Gson; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class MessagingEngine { + + private HashMap<String, AkkamonSession> akkamonSessions = new HashMap<>(); + private static MessagingEngine instance; + private Gson gson = new Gson(); + + public static MessagingEngine getInstance() { + if (instance == null) { + instance = new MessagingEngine(); + return instance; + } + return instance; + } + + public MessagingEngine() { + ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); + executor.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + emitGameState(); + } + }, 0, 200, TimeUnit.MILLISECONDS); + + } + + void emitGameState() { + HashMap<String, Trainer> trainers = AkkamonImpl.getInstance().getDummyTrainersCollection(); + + if (akkamonSessions.size() == 1) { + AkkamonSession session = akkamonSessions.get("Ash"); + + GameState gameState = new GameState(); + // dummy + gameState.setCurrentPlayer("Ash", trainers); + + Event event = new Event("updatePos", gameState); + + session.receiveGameState(gson.toJson(event)); + + } else if (akkamonSessions.size() == 2) { + for (String name: akkamonSessions.keySet()) { + AkkamonSession session = akkamonSessions.get(name); + + GameState gameState = new GameState(); + // dummy + gameState.setCurrentPlayer(name, trainers); + gameState.setRemotePlayers(trainers); + + Event event = new Event("updatePos", gameState); + + session.receiveGameState(gson.toJson(event)); + } + } + + // for (Map.Entry<User, AkkamonSession> sess: akkamonSessions.entrySet()) { + + // User user = sess.getKey(); + // AkkamonSession session = sess.getValue(); + + // GameState gameState = new GameState(); + // // dummy + // gameState.setCurrentPlayer(user.name, trainers); + + // session.receiveGameState(gson.toJson(gameState)); + // } + } + + void incoming(AkkamonSession session, String message) { + Event event = gson.fromJson(message, Event.class); + switch (event.type) { + case "login": + login(session, event.user); + break; + case "posUpdate": + updatePositions(event.gameState); + break; + } + } + + private void updatePositions(GameState gameState) { + Player current = gameState.currentPlayer; + if (gameState.currentPlayer != null) { + AkkamonImpl.getInstance().updateTrainerPosition(current.name, current.position.x, current.position.y); + } + } + + private void login(AkkamonSession session, User user) { + if (user == null) { + session.disconnect(401, "Give username and password"); + } + System.out.println("Currrent connections: " + akkamonSessions.size()); + if (akkamonSessions.size() == 0) { + akkamonSessions.put("Ash", session); + System.out.println("After adding ash!: " + akkamonSessions.size()); + session.setCurrentUser(new User("Ash", "")); + } else if (akkamonSessions.size() == 1) { + akkamonSessions.put("Misty", session); + session.setCurrentUser(new User("Misty", "")); + } + AkkamonImpl.getInstance().newPlayerConnected(user.name, user.password); + System.out.println("Emitting gameState!"); + emitGameState(); + } + +} diff --git a/api/src/main/java/akkamon/api/models/Event.java b/api/src/main/java/akkamon/api/models/Event.java new file mode 100644 index 0000000..50fc849 --- /dev/null +++ b/api/src/main/java/akkamon/api/models/Event.java @@ -0,0 +1,14 @@ +package akkamon.api.models; + +import org.eclipse.jetty.server.Authentication; + +public class Event { + public String type; + public GameState gameState; + public User user; + + public Event(String type, GameState gameState) { + this.type = type; + this.gameState = gameState; + } +} diff --git a/api/src/main/java/akkamon/api/models/GameState.java b/api/src/main/java/akkamon/api/models/GameState.java new file mode 100644 index 0000000..b303d24 --- /dev/null +++ b/api/src/main/java/akkamon/api/models/GameState.java @@ -0,0 +1,33 @@ +package akkamon.api.models; + +import akkamon.domain.Trainer; + +import java.util.HashMap; +import java.util.Map; + +public class GameState { + public Player currentPlayer; + public HashMap<String, Player> remotePlayers; + + + public void setCurrentPlayer(String name, HashMap<String, Trainer> trainers) { + Trainer trainer = trainers.get(name); + Position position = new Position(trainer.getX(), trainer.getY()); + currentPlayer = new Player(name, position); + } + + public void setRemotePlayers(HashMap<String, Trainer> trainers) { + for (Map.Entry<String, Trainer> trainer: trainers.entrySet()) { + if (trainer.getValue().getName().equals(currentPlayer.name)) { + continue; + } + + String name = trainer.getKey(); + Trainer obj = trainer.getValue(); + remotePlayers.put(name, new Player(name, new Position( + obj.getX(), + obj.getY() + ))); + } + } +} diff --git a/api/src/main/java/akkamon/api/models/Player.java b/api/src/main/java/akkamon/api/models/Player.java new file mode 100644 index 0000000..3aebb4d --- /dev/null +++ b/api/src/main/java/akkamon/api/models/Player.java @@ -0,0 +1,13 @@ +package akkamon.api.models; + +import java.util.HashMap; + +public class Player { + public String name; + public Position position; + + public Player(String name, Position position) { + this.name = name; + this.position = position; + } +} diff --git a/api/src/main/java/akkamon/api/models/Position.java b/api/src/main/java/akkamon/api/models/Position.java new file mode 100644 index 0000000..abe11dd --- /dev/null +++ b/api/src/main/java/akkamon/api/models/Position.java @@ -0,0 +1,11 @@ +package akkamon.api.models; + +public class Position { + public int x; + public int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } +} diff --git a/api/src/main/java/akkamon/api/models/User.java b/api/src/main/java/akkamon/api/models/User.java new file mode 100644 index 0000000..5f26ea0 --- /dev/null +++ b/api/src/main/java/akkamon/api/models/User.java @@ -0,0 +1,11 @@ +package akkamon.api.models; + +public class User { + public String name; + public String password; + + public User(String name, String password) { + this.name = name; + this.password = password; + } +} diff --git a/api/src/test/java/akkamon/api/EventSocketTest.java b/api/src/test/java/akkamon/api/EventSocketTest.java new file mode 100644 index 0000000..e9a6cc0 --- /dev/null +++ b/api/src/test/java/akkamon/api/EventSocketTest.java @@ -0,0 +1,7 @@ +package akkamon.api; + +import static org.junit.jupiter.api.Assertions.*; + +class EventSocketTest { + +}
\ No newline at end of file diff --git a/api/src/test/java/akkamon/api/MessagingEngineTest.java b/api/src/test/java/akkamon/api/MessagingEngineTest.java new file mode 100644 index 0000000..97d556c --- /dev/null +++ b/api/src/test/java/akkamon/api/MessagingEngineTest.java @@ -0,0 +1,7 @@ +package akkamon.api; + +import static org.junit.jupiter.api.Assertions.*; + +class MessagingEngineTest { + +}
\ No newline at end of file |
