GamePool / Game room added
This commit is contained in:
parent
ccc87d57f4
commit
094bebb7cb
8
pom.xml
8
pom.xml
@ -44,6 +44,14 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
|
||||
|
24
src/main/java/com/alterdekim/game/WebSocketConfig.java
Normal file
24
src/main/java/com/alterdekim/game/WebSocketConfig.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
@ -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<LongPollResultSingle> 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<RoomPlayer> players) {
|
||||
players.forEach(p -> {
|
||||
LongPollConfig lc = map.get(p.getUserId());
|
||||
List<GameRedirect> gr = lc.getGameRedirect();
|
||||
gr.add(new GameRedirect(roomId));
|
||||
lc.setGameRedirect(gr);
|
||||
map.put(p.getUserId(), lc);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<UserResult> friends_online;
|
||||
private Long lastRequest;
|
||||
private List<GameInvite> invites;
|
||||
private List<GameRedirect> 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<>();
|
||||
}
|
||||
}
|
||||
|
@ -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<Long, GameRoom> games = new ConcurrentHashMap<>();
|
||||
|
||||
@Scheduled(fixedRate = 1000)
|
||||
private void refreshRooms() {
|
||||
roomService.getAllActive()
|
||||
.forEach(r -> {
|
||||
if( roomPlayerService.findByRoomId(r.getId()).size() != r.getPlayerCount().intValue() ) return;
|
||||
List<RoomPlayer> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<RoomPlayer> players;
|
||||
|
||||
private ConcurrentHashMap<Long, WebSocketSession> socks;
|
||||
|
||||
public GameRoom(List<RoomPlayer> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,5 +5,6 @@ public enum LongPollResultType {
|
||||
ChatResult,
|
||||
RoomResult,
|
||||
FriendResult,
|
||||
InviteResult
|
||||
InviteResult,
|
||||
Redirect
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
16
src/main/java/com/alterdekim/game/dto/GameField.java
Normal file
16
src/main/java/com/alterdekim/game/dto/GameField.java
Normal file
@ -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;
|
||||
}
|
10
src/main/java/com/alterdekim/game/dto/GameRedirect.java
Normal file
10
src/main/java/com/alterdekim/game/dto/GameRedirect.java
Normal file
@ -0,0 +1,10 @@
|
||||
package com.alterdekim.game.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class GameRedirect {
|
||||
private Long roomId;
|
||||
}
|
@ -22,6 +22,11 @@ public interface RoomPlayerRepository extends JpaRepository<RoomPlayer, Long> {
|
||||
@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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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<Message<?>> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) {
|
||||
return AuthorityAuthorizationManager.hasAnyAuthority("ROLE_ADMIN");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -35,4 +35,8 @@ public class RoomServiceImpl implements RoomService {
|
||||
public void clearEmptyRooms() {
|
||||
roomRepository.clearEmptyRooms();
|
||||
}
|
||||
|
||||
public void removeRoom(Long roomId) {
|
||||
roomRepository.deleteById(roomId);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.alterdekim.game.websocket.message;
|
||||
|
||||
public interface IWebSocketMessage {
|
||||
}
|
25
src/main/resources/static/javascript/game.js
Normal file
25
src/main/resources/static/javascript/game.js
Normal file
@ -0,0 +1,25 @@
|
||||
const player_html = '<div class="player" th:data-pid="${p.id}" onClick="drop(this)"><p class="timeout"></p><p class="nickname" th:text="${p.name}"></p><p class="money" th:text="${p.money}"></p><div class="dropbox" style="display: none"></div> <!-- margin-top: -35px; --></div>';
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8"></meta>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="stylesheet" href="/static/css/game.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
<title>Монополия онлайн</title>
|
||||
<link rel="shortcut icon" type="image/png" href="../static/images/favicon.ico"/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js" integrity="sha512-iKDtgDyTHjAitUDdLljGhenhPwrbBfqTKWO1mkhSFH3A7blITC9MhYon6SjnMhp4o0rADGw9yAC6EW4t5a4K3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<title th:text="${title} ? ${title} : 'Nosedive'"></title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/static/images/favicon.ico">
|
||||
<api-tag th:data-access-token="${auth_obj.accessToken}" th:data-uid="${auth_obj.uid}" th:data-room-id="${roomId}"></api-tag>
|
||||
<div id="contract_field" style="display: none">
|
||||
<div style="display: inline-flex;">
|
||||
<div class="contract_image" style="margin-left: 10px"><img src="../static/images/mitsubishi.png" style="width: 55px;"></div>
|
||||
@ -26,14 +29,12 @@
|
||||
<div class="wrapper" style="width: 100%; height: 100%">
|
||||
<div class="game">
|
||||
<div class="players">
|
||||
<th:block th:each="p: ${players}">
|
||||
<div class="player" th:data-pid="${p.id}" onClick="drop(this)">
|
||||
<p class="timeout"></p>
|
||||
<p class="nickname" th:text="${p.name}"></p>
|
||||
<p class="money" th:text="${p.money}"></p>
|
||||
<div class="dropbox" style="display: none"></div> <!-- margin-top: -35px; -->
|
||||
</div>
|
||||
</th:block>
|
||||
<!--<div class="player" th:data-pid="${p.id}" onClick="drop(this)">
|
||||
<p class="timeout"></p>
|
||||
<p class="nickname" th:text="${p.name}"></p>
|
||||
<p class="money" th:text="${p.money}"></p>
|
||||
<div class="dropbox" style="display: none"></div> margin-top: -35px;
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="table_center">
|
||||
@ -212,61 +213,90 @@
|
||||
<div class="chip purple" data-trow=0 data-tcol=0></div>
|
||||
<div class="chip orange" data-trow=0 data-tcol=0></div>
|
||||
<!-- </div> -->
|
||||
<div class="up"><div class="board_field corner"><img src="../static/images/start.png" style="width: 100%; height: 100%;" /></div></div>
|
||||
<div class="up">
|
||||
<div class="board_field corner">
|
||||
<img src="../static/images/start.png" style="width: 100%; height: 100%;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<th:block th:each="f: ${fields_up}">
|
||||
<div th:data-fid="${f.uid}" class="board_field" th:style="grid-column: @{${f.id}}"> <!-- 2 + -->
|
||||
<div class="cost" th:text="${f.cost}"></div>
|
||||
<!--<th:block th:each="ft: ${fields_top}">
|
||||
<div th:data-fid="${ft.uid}" class="board_field" th:style="@{grid-column: {id}(id=${ft.id})}"> --> <!-- 2 + -->
|
||||
<!-- <div class="cost" th:text="${ft.cost}"></div>
|
||||
<div class="fh">
|
||||
<div class="iconH">
|
||||
<img th:src="${f.img}" class="vertImg">
|
||||
<img th:src="${ft.img}" class="vertImg">
|
||||
</div>
|
||||
<div class="stars">
|
||||
<span class="_star" th:text="${f.stars}"></span>
|
||||
<span class="_star" th:text="${ft.stars}"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block>
|
||||
</th:block>-->
|
||||
|
||||
<div class="up" style="grid-column: 11"><div class="board_field corner"><img src="../static/images/injail.png" style="width: 100%; height: 100%;" /></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/lacoste.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/mitsubishi.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/vw.png" class="horImg"></div></div><div class="stars hstars"><span class="_star _hstar"></span></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/mcdonalds.svg" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/apple.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/vw.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/macdonalds.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/nike.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 11"><div class="rcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/pepsi.png" class="horImg"></div><div class="stars hstars"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field corner" style="grid-column: 11"><img src="../static/images/parking.png" style="width:100%; height:100%;" /></div>
|
||||
<div class="board_field" style="grid-column: 2; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/nike.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 3; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/mitsubishi.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 4; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/peugeot.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 5; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/vw.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 6; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/linux.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 7; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/apple.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 8; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/burger_king.svg" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 9; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/lacoste.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field" style="grid-column: 10; grid-row: 11;"><div class="fh"><div class="iconH"><img src="../static/images/pepsi.png" class="vertImg"></div><div class="stars"><span class="_star _vstar"></span></div></div><div class="cost">0</div></div>
|
||||
<div class="board_field corner" style="grid-column: 1; grid-row: 11"><img src="../static/images/gotojail.png" style="width: 100%; height: 100%;" /></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 10;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/peugeot.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 9;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/apple.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 8;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/linux.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 7;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/macdonalds.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 6;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/pepsi.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 5;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/burger_king.svg" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 4;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/mitsubishi.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 3;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/adidas.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="board_field" style="grid-column: 1; grid-row: 2;"><div class="lcost">0</div><div class="fv"><div class="iconV"><img src="../static/images/lacoste.png" class="horImg"></div><div class="stars hstars _hhstar"><span class="_star _hstar"></span></div></div></div>
|
||||
<div class="up" style="grid-column: 11">
|
||||
<div class="board_field corner">
|
||||
<img src="../static/images/injail.png" style="width: 100%; height: 100%;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<th:block th:each="fr: ${fields_right}">
|
||||
<div class="board_field" style="grid-column: 11">
|
||||
<div class="rcost" th:text="${fr.cost}"></div>
|
||||
<div class="fv">
|
||||
<div class="iconV">
|
||||
<img th:src="${fr.img}" class="horImg">
|
||||
</div>
|
||||
<div class="stars hstars">
|
||||
<span class="_star _hstar" th:text="${fr.stars}"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block> -->
|
||||
|
||||
<div class="board_field corner" style="grid-column: 11">
|
||||
<img src="../static/images/parking.png" style="width:100%; height:100%;" />
|
||||
</div>
|
||||
|
||||
<!-- <th:block th:each="fb: ${fields_bottom}">
|
||||
<div class="board_field" th:style="@{grid-row: 11; grid-column: {id}(id=${fb.id})}"> --> <!-- 2 + --> <!--
|
||||
<div class="fh">
|
||||
<div class="iconH">
|
||||
<img class="vertImg" th:src="${fb.img}">
|
||||
</div>
|
||||
<div class="stars">
|
||||
<span class="_star _vstar" th:text="${fb.stars}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cost" th:text="${fb.cost}"></div>
|
||||
</div>
|
||||
</th:block> -->
|
||||
|
||||
|
||||
<div class="board_field corner" style="grid-column: 1; grid-row: 11">
|
||||
<img src="../static/images/gotojail.png" style="width: 100%; height: 100%;" />
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<th:block th:each="fl: ${fields_left}">
|
||||
<div class="board_field" th:style="@{grid-column: 1; grid-row: {id}(id=${fl.id})}">--> <!-- start from 10, go to 2 --> <!--
|
||||
<div class="lcost" th:text="${fl.cost}"></div>
|
||||
<div class="fv">
|
||||
<div class="iconV">
|
||||
<img th:src="${fl.img}" class="horImg">
|
||||
</div>
|
||||
<div class="stars hstars _hhstar">
|
||||
<span class="_star _hstar" th:text="${fl.stars}"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<footer>
|
||||
<script type="text/javascript" src="/games/cookie.js"></script>
|
||||
<script type="text/javascript" src="/games/db.js"></script>
|
||||
<script type="text/javascript" src="/games/methods.js"></script>
|
||||
<script type="text/javascript" src="game.js"></script>
|
||||
<script type="text/javascript" src="/static/javascript/game.js"></script>
|
||||
<script type="text/javascript" src="/static/javascript/scale.js"></script>
|
||||
</footer>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user