From 094bebb7cbe2e1841a86e88a4c028632b9b4194d Mon Sep 17 00:00:00 2001 From: alterdekim Date: Fri, 1 Mar 2024 23:57:37 +0300 Subject: [PATCH] GamePool / Game room added --- pom.xml | 8 ++ .../com/alterdekim/game/WebSocketConfig.java | 24 ++++ .../alterdekim/game/component/LongPoll.java | 22 ++- .../game/component/LongPollConfig.java | 16 ++- .../game/component/game/GamePool.java | 70 +++++++++ .../game/component/game/GameRoom.java | 42 ++++++ .../component/result/LongPollResultType.java | 3 +- .../game/controller/APIController.java | 4 +- .../game/controller/GameController.java | 34 +++++ .../game/controller/StaticController.java | 5 - .../com/alterdekim/game/dto/GameField.java | 16 +++ .../com/alterdekim/game/dto/GameRedirect.java | 10 ++ .../game/repository/RoomPlayerRepository.java | 5 + .../game/security/SpringSecurity.java | 1 + .../security/WebSocketSecurityConfig.java | 19 +++ .../game/service/RoomPlayerServiceImpl.java | 4 + .../game/service/RoomServiceImpl.java | 4 + .../java/com/alterdekim/game/util/Hash.java | 3 +- .../game/websocket/WebSocketHandler.java | 32 +++++ .../game/websocket/message/BasicMessage.java | 17 +++ .../websocket/message/IWebSocketMessage.java | 4 + src/main/resources/static/javascript/game.js | 25 ++++ src/main/resources/static/javascript/games.js | 9 ++ src/main/resources/templates/game.html | 134 +++++++++++------- 24 files changed, 447 insertions(+), 64 deletions(-) create mode 100644 src/main/java/com/alterdekim/game/WebSocketConfig.java create mode 100644 src/main/java/com/alterdekim/game/component/game/GamePool.java create mode 100644 src/main/java/com/alterdekim/game/component/game/GameRoom.java create mode 100644 src/main/java/com/alterdekim/game/controller/GameController.java create mode 100644 src/main/java/com/alterdekim/game/dto/GameField.java create mode 100644 src/main/java/com/alterdekim/game/dto/GameRedirect.java create mode 100644 src/main/java/com/alterdekim/game/security/WebSocketSecurityConfig.java create mode 100644 src/main/java/com/alterdekim/game/websocket/WebSocketHandler.java create mode 100644 src/main/java/com/alterdekim/game/websocket/message/BasicMessage.java create mode 100644 src/main/java/com/alterdekim/game/websocket/message/IWebSocketMessage.java create mode 100644 src/main/resources/static/javascript/game.js diff --git a/pom.xml b/pom.xml index 5711a5f..68fd002 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,14 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.security + spring-security-messaging + org.thymeleaf.extras thymeleaf-extras-springsecurity6 diff --git a/src/main/java/com/alterdekim/game/WebSocketConfig.java b/src/main/java/com/alterdekim/game/WebSocketConfig.java new file mode 100644 index 0000000..ea29151 --- /dev/null +++ b/src/main/java/com/alterdekim/game/WebSocketConfig.java @@ -0,0 +1,24 @@ +package com.alterdekim.game; + +import com.alterdekim.game.component.game.GamePool; +import com.alterdekim.game.websocket.WebSocketHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.*; + +@Configuration +@EnableWebSocket +@ComponentScan("com.alterdekim.game.component.game") +public class WebSocketConfig implements WebSocketConfigurer { + + @Autowired + private GamePool gamePool; + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(new WebSocketHandler(gamePool), "/websocket") + .setAllowedOriginPatterns("*") + .withSockJS(); + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/game/component/LongPoll.java b/src/main/java/com/alterdekim/game/component/LongPoll.java index 7a8bbe7..0148c28 100644 --- a/src/main/java/com/alterdekim/game/component/LongPoll.java +++ b/src/main/java/com/alterdekim/game/component/LongPoll.java @@ -8,6 +8,7 @@ import com.alterdekim.game.component.result.LongPollResult; import com.alterdekim.game.component.result.LongPollResultSingle; import com.alterdekim.game.component.result.LongPollResultType; import com.alterdekim.game.dto.*; +import com.alterdekim.game.entities.RoomPlayer; import com.alterdekim.game.service.*; import com.alterdekim.game.util.Hash; import lombok.Getter; @@ -69,14 +70,20 @@ public class LongPoll { }); getLongPollingQueue().forEach(longPollingSession -> { try { - if( !map.containsKey(longPollingSession.getUserId())) map.put(longPollingSession.getUserId(), new LongPollConfig(0L,new ArrayList<>(), 0, Hash.rnd(), new ArrayList<>(), System.currentTimeMillis(), new ArrayList<>())); + if( !map.containsKey(longPollingSession.getUserId())) map.put(longPollingSession.getUserId(), new LongPollConfig(0L)); LongPollConfig config = map.get(longPollingSession.getUserId()); LongPollResult result = process(longPollingSession.getUserId(), config); config.setSession_pass(config.getSession_pass()+1); - if( !result.getResultWithType(LongPollResultType.InviteResult, InviteResult.class).isEmpty() || !result.getResultWithType(LongPollResultType.FriendResult, FriendResult.class).isEmpty() || !result.getResultWithType(LongPollResultType.RoomResult, RoomResultV2.class).isEmpty() || !result.getResultWithType(LongPollResultType.ChatResult, ChatResult.class).isEmpty() || config.getSession_pass() >= iterations) { + if( !config.getGameRedirect().isEmpty() || + !result.getResultWithType(LongPollResultType.InviteResult, InviteResult.class).isEmpty() || + !result.getResultWithType(LongPollResultType.FriendResult, FriendResult.class).isEmpty() || + !result.getResultWithType(LongPollResultType.RoomResult, RoomResultV2.class).isEmpty() || + !result.getResultWithType(LongPollResultType.ChatResult, ChatResult.class).isEmpty() || + config.getSession_pass() >= iterations) { longPollingSession.getDeferredResult().setResult(result); config.setSession_pass(0); config.setInvites(new ArrayList<>()); + config.setGameRedirect(new ArrayList<>()); } map.put(longPollingSession.getUserId(), config); } catch (Exception e) { @@ -89,8 +96,19 @@ public class LongPoll { private LongPollResult process(Long userId, LongPollConfig config) { List result = new ArrayList<>(); result.add(new LongPollResultSingle<>(LongPollResultType.OnlineUsers, Arrays.asList(map.size()))); + result.add(new LongPollResultSingle<>(LongPollResultType.Redirect, config.getGameRedirect())); processors.forEach(p -> result.add(p.process(config, userId))); result.add(new LongPollResultSingle<>(LongPollResultType.InviteResult, config.getInvites().stream().map(i -> new InviteResult(i.getRoomId(), i.getUserId(), i.getUsername())).collect(Collectors.toList()))); return new LongPollResult(result); } + + public void notifyPlayers(Long roomId, List players) { + players.forEach(p -> { + LongPollConfig lc = map.get(p.getUserId()); + List gr = lc.getGameRedirect(); + gr.add(new GameRedirect(roomId)); + lc.setGameRedirect(gr); + map.put(p.getUserId(), lc); + }); + } } diff --git a/src/main/java/com/alterdekim/game/component/LongPollConfig.java b/src/main/java/com/alterdekim/game/component/LongPollConfig.java index 2686f6a..7b665c7 100644 --- a/src/main/java/com/alterdekim/game/component/LongPollConfig.java +++ b/src/main/java/com/alterdekim/game/component/LongPollConfig.java @@ -1,16 +1,18 @@ package com.alterdekim.game.component; import com.alterdekim.game.dto.GameInvite; +import com.alterdekim.game.dto.GameRedirect; import com.alterdekim.game.dto.RoomResult; import com.alterdekim.game.dto.UserResult; +import com.alterdekim.game.util.Hash; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.ArrayList; import java.util.List; -@NoArgsConstructor @AllArgsConstructor @Getter @Setter @@ -22,4 +24,16 @@ public class LongPollConfig { private List friends_online; private Long lastRequest; private List invites; + private List gameRedirect; + + public LongPollConfig(Long last_chat_id) { + this.last_chat_id = last_chat_id; + this.rooms = new ArrayList<>(); + this.session_pass = 0; + this.poll_token = Hash.rnd(); + this.friends_online = new ArrayList<>(); + this.lastRequest = System.currentTimeMillis(); + this.invites = new ArrayList<>(); + this.gameRedirect = new ArrayList<>(); + } } diff --git a/src/main/java/com/alterdekim/game/component/game/GamePool.java b/src/main/java/com/alterdekim/game/component/game/GamePool.java new file mode 100644 index 0000000..9f5f557 --- /dev/null +++ b/src/main/java/com/alterdekim/game/component/game/GamePool.java @@ -0,0 +1,70 @@ +package com.alterdekim.game.component.game; + +import com.alterdekim.game.component.LongPoll; +import com.alterdekim.game.entities.RoomPlayer; +import com.alterdekim.game.entities.User; +import com.alterdekim.game.service.RoomPlayerServiceImpl; +import com.alterdekim.game.service.RoomServiceImpl; +import com.alterdekim.game.service.UserServiceImpl; +import com.alterdekim.game.util.Hash; +import com.alterdekim.game.websocket.message.BasicMessage; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketSession; + +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@Component +public class GamePool { + + @Autowired + private LongPoll longPoll; + + @Autowired + private UserServiceImpl userService; + + @Autowired + private RoomServiceImpl roomService; + + @Autowired + private RoomPlayerServiceImpl roomPlayerService; + + private ConcurrentHashMap games = new ConcurrentHashMap<>(); + + @Scheduled(fixedRate = 1000) + private void refreshRooms() { + roomService.getAllActive() + .forEach(r -> { + if( roomPlayerService.findByRoomId(r.getId()).size() != r.getPlayerCount().intValue() ) return; + List players = roomPlayerService.findByRoomId(r.getId()); + roomPlayerService.removeByRoomId(r.getId()); + roomService.removeRoom(r.getId()); + games.put(r.getId(), new GameRoom(players)); + longPoll.notifyPlayers(r.getId(), players); + }); + } + + public void receiveMessage(String message, WebSocketSession session) { + try { + message = message.substring(message.indexOf("{")); + BasicMessage pm = new ObjectMapper().readValue(message, BasicMessage.class); + User u = userService.findById(pm.getUid()); + if (u == null || !games.containsKey(pm.getRoomId())) return; + if (!Hash.sha256((u.getId() + u.getUsername() + u.getPassword() + pm.getRoomId()).getBytes()).equals(pm.getAccessToken())) + return; + games.get(pm.getRoomId()).receiveMessage(pm, session); + } catch (JsonProcessingException | NoSuchAlgorithmException e) { + log.error(e.getMessage(), e); + } catch (StringIndexOutOfBoundsException e) { + //log.error(e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/alterdekim/game/component/game/GameRoom.java b/src/main/java/com/alterdekim/game/component/game/GameRoom.java new file mode 100644 index 0000000..42ee0de --- /dev/null +++ b/src/main/java/com/alterdekim/game/component/game/GameRoom.java @@ -0,0 +1,42 @@ +package com.alterdekim.game.component.game; + +import com.alterdekim.game.entities.RoomPlayer; +import com.alterdekim.game.websocket.message.BasicMessage; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class GameRoom { + + @Getter + private List players; + + private ConcurrentHashMap socks; + + public GameRoom(List players) { + this.players = players; + this.socks = new ConcurrentHashMap<>(); + } + + public void receiveMessage(BasicMessage message, WebSocketSession session) { + if(players.stream().noneMatch(p -> p.getUserId().longValue() == message.getUid().longValue())) return; + socks.put(message.getUid(), session); + log.info("GOT MESSAGE " + message.getUid() + " " + message.getAccessToken() + " " + message.getBody()); + this.sendMessage(message.getUid()); + } + + private void sendMessage(Long userId) { + try { + if (socks.get(userId).isOpen()) + socks.get(userId).sendMessage(new TextMessage("HEY!")); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/alterdekim/game/component/result/LongPollResultType.java b/src/main/java/com/alterdekim/game/component/result/LongPollResultType.java index 7efbbf0..5aceae2 100644 --- a/src/main/java/com/alterdekim/game/component/result/LongPollResultType.java +++ b/src/main/java/com/alterdekim/game/component/result/LongPollResultType.java @@ -5,5 +5,6 @@ public enum LongPollResultType { ChatResult, RoomResult, FriendResult, - InviteResult + InviteResult, + Redirect } diff --git a/src/main/java/com/alterdekim/game/controller/APIController.java b/src/main/java/com/alterdekim/game/controller/APIController.java index d136f26..e55e556 100644 --- a/src/main/java/com/alterdekim/game/controller/APIController.java +++ b/src/main/java/com/alterdekim/game/controller/APIController.java @@ -207,7 +207,7 @@ public class APIController { if( longPoll.getMap().containsKey(userId) ){ LongPollConfig c = longPoll.getMap().get(userId); if( !c.getPoll_token().equals(poll_token) ) { - c = new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>()); + c = new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>(), new ArrayList<>()); longPoll.getLongPollingQueue().removeIf(q -> q.getUserId().longValue() == userId.longValue()); } c.setRooms(rooms); @@ -217,7 +217,7 @@ public class APIController { c.setLastRequest(System.currentTimeMillis()); longPoll.getMap().put(userId, c); } else { - longPoll.getMap().put(userId, new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>())); + longPoll.getMap().put(userId, new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>(), new ArrayList<>())); } longPoll.getLongPollingQueue().add(new LongPollingSession(userId, deferredResult)); return deferredResult; diff --git a/src/main/java/com/alterdekim/game/controller/GameController.java b/src/main/java/com/alterdekim/game/controller/GameController.java new file mode 100644 index 0000000..68ee476 --- /dev/null +++ b/src/main/java/com/alterdekim/game/controller/GameController.java @@ -0,0 +1,34 @@ +package com.alterdekim.game.controller; + +import com.alterdekim.game.dto.AuthApiObject; +import com.alterdekim.game.entities.User; +import com.alterdekim.game.service.UserServiceImpl; +import com.alterdekim.game.util.AuthenticationUtil; +import com.alterdekim.game.util.Hash; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Slf4j +@Controller +public class GameController { + + @Autowired + private UserServiceImpl userService; + + @GetMapping("/game") + public String gamePage(Model model, @RequestParam("id") Long roomId) { + model.addAttribute("roomId", roomId); + try { + User u = AuthenticationUtil.authProfile(model, userService); + String apiKey = Hash.sha256((u.getId() + u.getUsername() + u.getPassword() + roomId).getBytes()); + model.addAttribute("auth_obj", new AuthApiObject(apiKey, u.getId(), Hash.rnd())); + } catch ( Exception e ) { + log.error(e.getMessage(), e); + } + return "game"; + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/game/controller/StaticController.java b/src/main/java/com/alterdekim/game/controller/StaticController.java index 2634c2d..095ae79 100644 --- a/src/main/java/com/alterdekim/game/controller/StaticController.java +++ b/src/main/java/com/alterdekim/game/controller/StaticController.java @@ -48,11 +48,6 @@ public class StaticController { return "rules"; } - @GetMapping("/game") - public String gamePage(Model model) { - return "game"; - } - @GetMapping("/games") public String gamesPage(Model model) { try { diff --git a/src/main/java/com/alterdekim/game/dto/GameField.java b/src/main/java/com/alterdekim/game/dto/GameField.java new file mode 100644 index 0000000..ac19d79 --- /dev/null +++ b/src/main/java/com/alterdekim/game/dto/GameField.java @@ -0,0 +1,16 @@ +package com.alterdekim.game.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class GameField { + private Long uid; + private Integer id; + private String cost; + private String img; + private String stars; +} diff --git a/src/main/java/com/alterdekim/game/dto/GameRedirect.java b/src/main/java/com/alterdekim/game/dto/GameRedirect.java new file mode 100644 index 0000000..37f05e9 --- /dev/null +++ b/src/main/java/com/alterdekim/game/dto/GameRedirect.java @@ -0,0 +1,10 @@ +package com.alterdekim.game.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class GameRedirect { + private Long roomId; +} diff --git a/src/main/java/com/alterdekim/game/repository/RoomPlayerRepository.java b/src/main/java/com/alterdekim/game/repository/RoomPlayerRepository.java index a9b6b7e..5c700fe 100644 --- a/src/main/java/com/alterdekim/game/repository/RoomPlayerRepository.java +++ b/src/main/java/com/alterdekim/game/repository/RoomPlayerRepository.java @@ -22,6 +22,11 @@ public interface RoomPlayerRepository extends JpaRepository { @Query(value = "DELETE FROM RoomPlayer r WHERE r.userId = :userId") void deleteAllByUserId(@Param("userId") Long userId); + @Transactional + @Modifying + @Query(value = "DELETE FROM RoomPlayer r WHERE r.roomId = :roomId") + void removeByRoomId(@Param("roomId") Long roomId); + @Query(value = "SELECT r.roomId FROM RoomPlayer r WHERE r.userId = :userId ORDER BY r.roomId ASC LIMIT 1") Long hasUserId(@Param("userId") Long userId); } diff --git a/src/main/java/com/alterdekim/game/security/SpringSecurity.java b/src/main/java/com/alterdekim/game/security/SpringSecurity.java index 71aa712..b3dc692 100644 --- a/src/main/java/com/alterdekim/game/security/SpringSecurity.java +++ b/src/main/java/com/alterdekim/game/security/SpringSecurity.java @@ -42,6 +42,7 @@ public class SpringSecurity { .requestMatchers("/friends").hasAnyAuthority("ROLE_ADMIN") .requestMatchers("/followers").hasAnyAuthority("ROLE_ADMIN") .requestMatchers("/settings").hasAnyAuthority("ROLE_ADMIN") + .requestMatchers("/websocket/**").hasAnyAuthority("ROLE_ADMIN") .requestMatchers("/static/**").permitAll() .requestMatchers("/access-denied").permitAll() .requestMatchers("/signup").permitAll() diff --git a/src/main/java/com/alterdekim/game/security/WebSocketSecurityConfig.java b/src/main/java/com/alterdekim/game/security/WebSocketSecurityConfig.java new file mode 100644 index 0000000..31ba5ae --- /dev/null +++ b/src/main/java/com/alterdekim/game/security/WebSocketSecurityConfig.java @@ -0,0 +1,19 @@ +package com.alterdekim.game.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.security.authorization.AuthorityAuthorizationManager; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; + +@Configuration +@EnableWebSocketSecurity +public class WebSocketSecurityConfig { + + @Bean + AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { + return AuthorityAuthorizationManager.hasAnyAuthority("ROLE_ADMIN"); + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/game/service/RoomPlayerServiceImpl.java b/src/main/java/com/alterdekim/game/service/RoomPlayerServiceImpl.java index 9da5f63..82ce01a 100644 --- a/src/main/java/com/alterdekim/game/service/RoomPlayerServiceImpl.java +++ b/src/main/java/com/alterdekim/game/service/RoomPlayerServiceImpl.java @@ -36,4 +36,8 @@ public class RoomPlayerServiceImpl implements RoomPlayerService{ public Long hasUserId(Long userId) { return repository.hasUserId(userId); } + + public void removeByRoomId(Long roomId) { + repository.removeByRoomId(roomId); + } } diff --git a/src/main/java/com/alterdekim/game/service/RoomServiceImpl.java b/src/main/java/com/alterdekim/game/service/RoomServiceImpl.java index 1a58589..649ba66 100644 --- a/src/main/java/com/alterdekim/game/service/RoomServiceImpl.java +++ b/src/main/java/com/alterdekim/game/service/RoomServiceImpl.java @@ -35,4 +35,8 @@ public class RoomServiceImpl implements RoomService { public void clearEmptyRooms() { roomRepository.clearEmptyRooms(); } + + public void removeRoom(Long roomId) { + roomRepository.deleteById(roomId); + } } diff --git a/src/main/java/com/alterdekim/game/util/Hash.java b/src/main/java/com/alterdekim/game/util/Hash.java index adf7696..78df4b4 100644 --- a/src/main/java/com/alterdekim/game/util/Hash.java +++ b/src/main/java/com/alterdekim/game/util/Hash.java @@ -1,12 +1,13 @@ package com.alterdekim.game.util; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; public class Hash { - public static String sha256( byte[] b ) throws Exception { + public static String sha256( byte[] b ) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); return bytesToHex(digest.digest(b)); } diff --git a/src/main/java/com/alterdekim/game/websocket/WebSocketHandler.java b/src/main/java/com/alterdekim/game/websocket/WebSocketHandler.java new file mode 100644 index 0000000..d092e20 --- /dev/null +++ b/src/main/java/com/alterdekim/game/websocket/WebSocketHandler.java @@ -0,0 +1,32 @@ +package com.alterdekim.game.websocket; + +import com.alterdekim.game.component.game.GamePool; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +import java.io.IOException; + +@Slf4j +@AllArgsConstructor +public class WebSocketHandler extends TextWebSocketHandler { + + private GamePool gamePool; + + @Override + public void handleMessage(WebSocketSession session, WebSocketMessage message) { + String receivedMessage = (String) message.getPayload(); + gamePool.receiveMessage(receivedMessage, session); + } + @Override + public void afterConnectionEstablished(WebSocketSession session) { + // Perform actions when a new WebSocket connection is established + } + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { + // Perform actions when a WebSocket connection is closed + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/game/websocket/message/BasicMessage.java b/src/main/java/com/alterdekim/game/websocket/message/BasicMessage.java new file mode 100644 index 0000000..4f46dbd --- /dev/null +++ b/src/main/java/com/alterdekim/game/websocket/message/BasicMessage.java @@ -0,0 +1,17 @@ +package com.alterdekim.game.websocket.message; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class BasicMessage { + private Long roomId; + private String accessToken; + private Long uid; + private String body; +} diff --git a/src/main/java/com/alterdekim/game/websocket/message/IWebSocketMessage.java b/src/main/java/com/alterdekim/game/websocket/message/IWebSocketMessage.java new file mode 100644 index 0000000..71e7ebb --- /dev/null +++ b/src/main/java/com/alterdekim/game/websocket/message/IWebSocketMessage.java @@ -0,0 +1,4 @@ +package com.alterdekim.game.websocket.message; + +public interface IWebSocketMessage { +} diff --git a/src/main/resources/static/javascript/game.js b/src/main/resources/static/javascript/game.js new file mode 100644 index 0000000..3a7aeea --- /dev/null +++ b/src/main/resources/static/javascript/game.js @@ -0,0 +1,25 @@ +const player_html = '

'; + +var stompClient = null; + +function disconnect() { + if (stompClient !== null) { + stompClient.disconnect(); + } + console.log("Disconnected"); +} + +function sendMessage(message) { + stompClient.send("/", {}, JSON.stringify({'body': JSON.stringify(message), 'accessToken': $("api-tag").attr("data-access-token"), 'uid': $("api-tag").attr("data-uid"), 'roomId': $("api-tag").attr("data-room-id")})); +} + +$(document).ready(function() { + var socket = new SockJS('/websocket'); + stompClient = Stomp.over(socket); + stompClient.connect({}, function (frame) { + console.log('Connected: ' + frame); + stompClient.subscribe('/', function (message) { + //showMessage(JSON.parse(message.body).content); + }); + }); +}); \ No newline at end of file diff --git a/src/main/resources/static/javascript/games.js b/src/main/resources/static/javascript/games.js index d7c8337..1de1e7b 100644 --- a/src/main/resources/static/javascript/games.js +++ b/src/main/resources/static/javascript/games.js @@ -61,6 +61,12 @@ function takeInviteMessage(obj) { }); } +function takeRedirect(reds) { + for( let i = 0; i < reds.length; i++ ) { + window.location.assign("/game?id=" + reds[i].roomId); + } +} + function successPolling(data) { console.log(data); data = data.result; @@ -89,6 +95,9 @@ function successPolling(data) { case "InviteResult": invites = res.array; break; + case "Redirect": + takeRedirect(res.array); + break; } } diff --git a/src/main/resources/templates/game.html b/src/main/resources/templates/game.html index 41179e6..c69c8ce 100644 --- a/src/main/resources/templates/game.html +++ b/src/main/resources/templates/game.html @@ -1,11 +1,14 @@ - + - Монополия онлайн - + + + + +