LongPoll rewritten
This commit is contained in:
parent
9b6c3d525d
commit
c19bba5930
@ -1,23 +1,24 @@
|
||||
package com.alterdekim.game.component;
|
||||
|
||||
import com.alterdekim.game.component.processors.ChatProcessor;
|
||||
import com.alterdekim.game.component.processors.FriendProcessor;
|
||||
import com.alterdekim.game.component.processors.Processor;
|
||||
import com.alterdekim.game.component.processors.RoomProcessor;
|
||||
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.Chat;
|
||||
import com.alterdekim.game.entities.Room;
|
||||
import com.alterdekim.game.entities.RoomPlayer;
|
||||
import com.alterdekim.game.entities.User;
|
||||
import com.alterdekim.game.service.*;
|
||||
import com.alterdekim.game.util.Hash;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -33,6 +34,8 @@ public class LongPoll {
|
||||
private final BlockingQueue<LongPollingSession> longPollingQueue = new ArrayBlockingQueue<>(100);
|
||||
private final ConcurrentHashMap<Long, LongPollConfig> map = new ConcurrentHashMap<>();
|
||||
|
||||
private final List<Processor> processors = new ArrayList<>();
|
||||
|
||||
@Autowired
|
||||
private UserServiceImpl userService;
|
||||
|
||||
@ -48,28 +51,32 @@ public class LongPoll {
|
||||
@Autowired
|
||||
private FriendServiceImpl friendService;
|
||||
|
||||
public LongPoll() {
|
||||
processors.addAll(Arrays.asList(new ChatProcessor(this), new FriendProcessor(this), new RoomProcessor(this)));
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 3000)
|
||||
private void longPoll() {
|
||||
getLongPollingQueue().removeIf(e -> e.getDeferredResult().isSetOrExpired());
|
||||
roomService.clearEmptyRooms();
|
||||
getMap().keySet().forEach(k -> {
|
||||
if( (System.currentTimeMillis() - getMap().get(k).getLastRequest()) >= 60000 ) getMap().remove(k);
|
||||
if( (System.currentTimeMillis() - getMap().get(k).getLastRequest()) >= 55000 ) getMap().remove(k);
|
||||
});
|
||||
roomService.getAll().forEach(r -> {
|
||||
roomPlayerService.findByRoomId(r.getId()).stream()
|
||||
.filter(p -> !map.containsKey(p.getUserId()))
|
||||
.forEach(p -> roomPlayerService.leaveByUserId(p.getUserId()));
|
||||
});
|
||||
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<>()));
|
||||
LongPollConfig config = map.get(longPollingSession.getUserId());
|
||||
LongPollResult result = process(longPollingSession.getUserId(), config);
|
||||
if( !result.getRooms().isEmpty() )
|
||||
config.setRooms(result.getRooms().stream().filter(r -> r.getAction() == RoomResultState.ADD_CHANGE).map(r -> new RoomResult(r.getId(), r.getPlayerCount(), r.getPlayers())).collect(Collectors.toList()));
|
||||
if( !result.getFriends().isEmpty() )
|
||||
config.setFriends_online(result.getFriends().stream().filter(r -> r.getAction() == FriendState.ADD).map(r -> new UserResult(r.getId(), r.getUsername())).collect(Collectors.toList()));
|
||||
|
||||
config.setSession_pass(config.getSession_pass()+1);
|
||||
|
||||
if( !result.getInvites().isEmpty() || !result.getFriends().isEmpty() || !result.getRooms().isEmpty() || !result.getMessages().isEmpty() || config.getSession_pass() >= iterations) {
|
||||
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) {
|
||||
longPollingSession.getDeferredResult().setResult(result);
|
||||
config.setSession_pass(0);
|
||||
config.setInvites(new ArrayList<>());
|
||||
}
|
||||
map.put(longPollingSession.getUserId(), config);
|
||||
} catch (Exception e) {
|
||||
@ -80,156 +87,10 @@ public class LongPoll {
|
||||
}
|
||||
|
||||
private LongPollResult process(Long userId, LongPollConfig config) {
|
||||
Integer onlineCount = map.size();
|
||||
List<Chat> results;
|
||||
List<UserResult> users = new ArrayList<>();
|
||||
List<RoomResult> clientRooms = config.getRooms();
|
||||
List<RoomResultV2> roomResults = new ArrayList<>();
|
||||
List<UserResult> clientFriends = config.getFriends_online();
|
||||
List<FriendResult> friendsResult = new ArrayList<>();
|
||||
|
||||
results = chatService.getAfterLastChatId(config.getLast_chat_id());
|
||||
|
||||
// Chat part
|
||||
if( !results.isEmpty() ) {
|
||||
users = results.stream()
|
||||
.map(Chat::getUserId)
|
||||
.distinct()
|
||||
.map(l -> userService.findById(l))
|
||||
.map(u -> new UserResult(u.getId(), u.getUsername()))
|
||||
.collect(Collectors.toList());
|
||||
results = results.stream().peek(c -> {
|
||||
String message = c.getMessage();
|
||||
for (int i = 0; i < message.length(); i++) {
|
||||
if (message.charAt(i) == '@') {
|
||||
int u = message.substring(i).indexOf(' ') + i;
|
||||
String username = message.substring(i + 1, u);
|
||||
User user = userService.findByUsername(username);
|
||||
if (user != null) {
|
||||
Long uid = user.getId();
|
||||
message = message.substring(0, i) + "<a href=\"/profile/" + uid + "\" class=\"chat-history-user\"><span class=\"_nick\">" + username + "</span></a>" + message.substring(u + 1);
|
||||
} else {
|
||||
message = message.substring(0, i) + username + message.substring(u + 1);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
c.setMessage(message);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Rooms part
|
||||
if( !clientRooms.isEmpty() ) {
|
||||
List<RoomResult> rooms = roomService.getAllActive().stream()
|
||||
.map( r -> new RoomResult(r.getId(), r.getPlayerCount(), roomPlayerService.findByRoomId(r.getId()).stream()
|
||||
.map(p -> userService.findById(p.getUserId()))
|
||||
.map(p -> new UserResult(p.getId(), p.getUsername()))
|
||||
.collect(Collectors.toList())))
|
||||
.collect(Collectors.toList());
|
||||
if( !isEqualListRoom(rooms, clientRooms) ) {
|
||||
List<RoomResult> rr = new ArrayList<>(rooms);
|
||||
List<RoomResultV2> resultV2List = new ArrayList<>();
|
||||
for( RoomResult r : clientRooms ) {
|
||||
if( rooms.stream().noneMatch(t -> t.getId().longValue() == r.getId().longValue()) ) {
|
||||
resultV2List.add(new RoomResultV2(RoomResultState.REMOVE, r.getId(), r.getPlayerCount(), r.getPlayers()));
|
||||
} else {
|
||||
RoomResult r1 = rooms.stream().filter( t -> t.getId().longValue() == r.getId().longValue()).findFirst().get();
|
||||
if( !isEqual(r, r1) ) {
|
||||
resultV2List.add(new RoomResultV2(RoomResultState.ADD_CHANGE, r1.getId(), r1.getPlayerCount(), r1.getPlayers()));
|
||||
}
|
||||
rr.remove(r1);
|
||||
}
|
||||
}
|
||||
for( RoomResult r : rr ) {
|
||||
resultV2List.add(new RoomResultV2(RoomResultState.ADD_CHANGE, r.getId(), r.getPlayerCount(), r.getPlayers()));
|
||||
}
|
||||
roomResults = resultV2List.stream().sorted(Comparator.comparingLong(RoomResultV2::getId)).collect(Collectors.toList());
|
||||
} else {
|
||||
roomResults = new ArrayList<>();
|
||||
}
|
||||
} else {
|
||||
List<Room> rooms = roomService.getAllActive();
|
||||
roomResults = rooms.stream()
|
||||
.map( r -> new RoomResultV2(RoomResultState.ADD_CHANGE, r.getId(), r.getPlayerCount(), roomPlayerService.findByRoomId(r.getId()).stream()
|
||||
.map(p -> userService.findById(p.getUserId()))
|
||||
.map(p -> new UserResult(p.getId(), p.getUsername()))
|
||||
.collect(Collectors.toList())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Friends part
|
||||
if( !clientFriends.isEmpty() ) {
|
||||
List<UserResult> userResults = friendService.getFriendsOfUserId(userId)
|
||||
.stream()
|
||||
.map(id -> userService.findById(id))
|
||||
.map(u -> new UserResult(u.getId(), u.getUsername()))
|
||||
.filter(f -> getMap().keySet().stream().anyMatch(l -> l.longValue() == f.getId().longValue()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if( !isEqualListUser(userResults, clientFriends) ) {
|
||||
List<UserResult> urr = new ArrayList<>(userResults);
|
||||
List<FriendResult> fr = new ArrayList<>();
|
||||
for( UserResult r : clientFriends ) {
|
||||
if( userResults.stream().noneMatch(t -> t.getId().longValue() == r.getId().longValue()) ) {
|
||||
fr.add(new FriendResult(FriendState.REMOVE, r.getId(), r.getUsername()));
|
||||
} else {
|
||||
UserResult r1 = userResults.stream().filter( t -> t.getId().longValue() == r.getId().longValue()).findFirst().get();
|
||||
if( !isEqualUser(r, r1) ) {
|
||||
fr.add(new FriendResult(FriendState.ADD, r1.getId(), r1.getUsername()));
|
||||
}
|
||||
urr.remove(r1);
|
||||
}
|
||||
}
|
||||
for( UserResult r : urr ) {
|
||||
fr.add(new FriendResult(FriendState.ADD, r.getId(), r.getUsername()));
|
||||
}
|
||||
friendsResult = fr.stream().sorted(Comparator.comparingLong(FriendResult::getId)).collect(Collectors.toList());
|
||||
} else {
|
||||
friendsResult = new ArrayList<>();
|
||||
}
|
||||
} else {
|
||||
friendsResult = friendService.getFriendsOfUserId(userId)
|
||||
.stream()
|
||||
.map(id -> userService.findById(id))
|
||||
.filter(f -> getMap().keySet().stream().anyMatch(l -> l.longValue() == f.getId().longValue()))
|
||||
.map(f -> new FriendResult(FriendState.ADD, f.getId(), f.getUsername()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return new LongPollResult(onlineCount, results, users, roomResults, friendsResult, config.getInvites().stream().map(i -> new InviteResult(i.getRoomId(), i.getUserId(), i.getUsername())).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private Boolean isEqual(RoomResult r1, RoomResult r2) {
|
||||
return r1.getId().longValue() == r2.getId().longValue() &&
|
||||
r1.getPlayerCount().intValue() == r2.getPlayerCount().intValue() &&
|
||||
isEqualListUser(r1.getPlayers(), r2.getPlayers());
|
||||
}
|
||||
|
||||
private Boolean isEqualUser(UserResult r1, UserResult r2) {
|
||||
return r1.getId().longValue() == r2.getId().longValue() &&
|
||||
r1.getUsername().equals(r2.getUsername());
|
||||
}
|
||||
|
||||
private Boolean isEqualListRoom(List<RoomResult> r1, List<RoomResult> r2) {
|
||||
r1 = r1.stream().sorted(Comparator.comparingLong(RoomResult::getId)).collect(Collectors.toList());
|
||||
r2 = r2.stream().sorted(Comparator.comparingLong(RoomResult::getId)).collect(Collectors.toList());
|
||||
if( r1.size() != r2.size() ) return false;
|
||||
for( int i = 0; i < r1.size(); i++ ) {
|
||||
if( !isEqual(r1.get(i), r2.get(i)) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Boolean isEqualListUser(List<UserResult> r1, List<UserResult> r2) {
|
||||
r1 = r1.stream().sorted(Comparator.comparingLong(UserResult::getId)).collect(Collectors.toList());
|
||||
r2 = r2.stream().sorted(Comparator.comparingLong(UserResult::getId)).collect(Collectors.toList());
|
||||
if( r1.size() != r2.size() ) return false;
|
||||
for( int i = 0; i < r1.size(); i++ ) {
|
||||
if( r1.get(i).getId().longValue() != r2.get(i).getId().longValue() ||
|
||||
!r1.get(i).getUsername().equals(r2.get(i).getUsername()) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
List<LongPollResultSingle> result = new ArrayList<>();
|
||||
result.add(new LongPollResultSingle<>(LongPollResultType.OnlineUsers, Arrays.asList(map.size())));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.alterdekim.game.component;
|
||||
|
||||
import com.alterdekim.game.dto.LongPollResult;
|
||||
import com.alterdekim.game.component.result.LongPollResult;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.alterdekim.game.component.processors;
|
||||
|
||||
import com.alterdekim.game.component.LongPoll;
|
||||
import com.alterdekim.game.component.LongPollConfig;
|
||||
import com.alterdekim.game.component.result.LongPollResultSingle;
|
||||
import com.alterdekim.game.component.result.LongPollResultType;
|
||||
import com.alterdekim.game.dto.ChatResult;
|
||||
import com.alterdekim.game.dto.UserResult;
|
||||
import com.alterdekim.game.entities.Chat;
|
||||
import com.alterdekim.game.service.ChatServiceImpl;
|
||||
import com.alterdekim.game.service.UserServiceImpl;
|
||||
import com.alterdekim.game.util.StringUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ChatProcessor extends Processor<ChatResult> {
|
||||
|
||||
public ChatProcessor(LongPoll longPoll) {
|
||||
super(LongPollResultType.ChatResult, longPoll);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongPollResultSingle<ChatResult> process(LongPollConfig config, Long userId) {
|
||||
List<Chat> results = getParent().getChatService().getAfterLastChatId(config.getLast_chat_id());
|
||||
|
||||
if( results.isEmpty() ) return new LongPollResultSingle<>(getType(), new ArrayList<>());
|
||||
|
||||
return new LongPollResultSingle<>(getType(), results.stream()
|
||||
.peek(c -> c.setMessage(StringUtil.escapeTags(getParent().getUserService(), c.getMessage())))
|
||||
.map(c -> new ChatResult(c, new UserResult( c.getUserId(), getParent().getUserService().findById(c.getUserId()).getUsername())))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.alterdekim.game.component.processors;
|
||||
|
||||
import com.alterdekim.game.component.LongPoll;
|
||||
import com.alterdekim.game.component.LongPollConfig;
|
||||
import com.alterdekim.game.component.result.LongPollResultSingle;
|
||||
import com.alterdekim.game.component.result.LongPollResultType;
|
||||
import com.alterdekim.game.dto.FriendResult;
|
||||
import com.alterdekim.game.dto.FriendState;
|
||||
import com.alterdekim.game.dto.UserResult;
|
||||
import com.alterdekim.game.service.FriendServiceImpl;
|
||||
import com.alterdekim.game.service.UserServiceImpl;
|
||||
import com.alterdekim.game.util.ListUtil;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FriendProcessor extends Processor<FriendResult> {
|
||||
|
||||
public FriendProcessor(LongPoll parent) {
|
||||
super(LongPollResultType.FriendResult, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongPollResultSingle<FriendResult> process(LongPollConfig config, Long userId) {
|
||||
List<UserResult> clientFriends = config.getFriends_online();
|
||||
|
||||
if( !clientFriends.isEmpty() ) return new LongPollResultSingle<>(getType(), rearrangeFriends(clientFriends, userId));
|
||||
|
||||
return new LongPollResultSingle<>(getType(), friends2Users(getParent().getFriendService().getFriendsOfUserId(userId))
|
||||
.stream()
|
||||
.map(f -> new FriendResult(FriendState.ADD, f.getId(), f.getUsername()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private List<FriendResult> rearrangeFriends(List<UserResult> clientFriends, Long userId) {
|
||||
List<UserResult> userResults = friends2Users(getParent().getFriendService().getFriendsOfUserId(userId));
|
||||
|
||||
if(ListUtil.isEqualListUser(userResults, clientFriends) ) return new ArrayList<>();
|
||||
|
||||
List<UserResult> urr = new ArrayList<>(userResults);
|
||||
List<FriendResult> fr = new ArrayList<>();
|
||||
for( UserResult r : clientFriends ) {
|
||||
if( userResults.stream().noneMatch(t -> t.getId().longValue() == r.getId().longValue()) ) {
|
||||
fr.add(new FriendResult(FriendState.REMOVE, r.getId(), r.getUsername()));
|
||||
continue;
|
||||
}
|
||||
UserResult r1 = userResults.stream().filter( t -> t.getId().longValue() == r.getId().longValue()).findFirst().get();
|
||||
if( !r.equals(r1) ) {
|
||||
fr.add(new FriendResult(FriendState.ADD, r1.getId(), r1.getUsername()));
|
||||
}
|
||||
urr.remove(r1);
|
||||
}
|
||||
urr.forEach(r -> fr.add(new FriendResult(FriendState.ADD, r.getId(), r.getUsername())));
|
||||
return fr.stream().sorted(Comparator.comparingLong(FriendResult::getId)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<UserResult> friends2Users(List<Long> friendIds) {
|
||||
return friendIds.stream()
|
||||
.map(id -> getParent().getUserService().findById(id))
|
||||
.map(u -> new UserResult(u.getId(), u.getUsername()))
|
||||
.filter(f -> getParent().getMap().keySet().stream().anyMatch(l -> l.longValue() == f.getId().longValue()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.alterdekim.game.component.processors;
|
||||
|
||||
import com.alterdekim.game.component.LongPoll;
|
||||
import com.alterdekim.game.component.LongPollConfig;
|
||||
import com.alterdekim.game.component.result.LongPollResultSingle;
|
||||
import com.alterdekim.game.component.result.LongPollResultType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class Processor<T> {
|
||||
private LongPollResultType type;
|
||||
private LongPoll parent;
|
||||
|
||||
public abstract LongPollResultSingle<T> process(LongPollConfig config, Long userId);
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.alterdekim.game.component.processors;
|
||||
|
||||
import com.alterdekim.game.component.LongPoll;
|
||||
import com.alterdekim.game.component.LongPollConfig;
|
||||
import com.alterdekim.game.component.result.LongPollResultSingle;
|
||||
import com.alterdekim.game.component.result.LongPollResultType;
|
||||
import com.alterdekim.game.dto.RoomResult;
|
||||
import com.alterdekim.game.dto.RoomResultState;
|
||||
import com.alterdekim.game.dto.RoomResultV2;
|
||||
import com.alterdekim.game.dto.UserResult;
|
||||
import com.alterdekim.game.entities.Room;
|
||||
import com.alterdekim.game.service.RoomPlayerService;
|
||||
import com.alterdekim.game.service.RoomPlayerServiceImpl;
|
||||
import com.alterdekim.game.service.RoomServiceImpl;
|
||||
import com.alterdekim.game.service.UserServiceImpl;
|
||||
import com.alterdekim.game.util.ListUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RoomProcessor extends Processor<RoomResultV2> {
|
||||
|
||||
public RoomProcessor(LongPoll longPoll) {
|
||||
super(LongPollResultType.RoomResult, longPoll);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongPollResultSingle<RoomResultV2> process(LongPollConfig config, Long userId) {
|
||||
List<RoomResult> clientRooms = config.getRooms();
|
||||
|
||||
if( clientRooms.isEmpty() ) return new LongPollResultSingle<>(getType(), roomToRoomResult2AddChange(getParent().getRoomService().getAllActive()));
|
||||
|
||||
List<RoomResult> rooms = roomToRoomResult(getParent().getRoomService().getAllActive());
|
||||
|
||||
if( ListUtil.isEqualListRoom(rooms, clientRooms) ) return new LongPollResultSingle<>(getType(), new ArrayList<>());
|
||||
|
||||
List<RoomResult> rr = new ArrayList<>(rooms);
|
||||
List<RoomResultV2> resultV2List = new ArrayList<>();
|
||||
|
||||
for( RoomResult r : clientRooms ) {
|
||||
if( rooms.stream().noneMatch(t -> t.getId().longValue() == r.getId().longValue()) ) {
|
||||
resultV2List.add(new RoomResultV2(RoomResultState.REMOVE, r.getId(), r.getPlayerCount(), r.getPlayers()));
|
||||
continue;
|
||||
}
|
||||
|
||||
RoomResult r1 = rooms.stream().filter( t -> t.getId().longValue() == r.getId().longValue()).findFirst().get();
|
||||
if( !r.equals(r1) ) {
|
||||
resultV2List.add(new RoomResultV2(RoomResultState.ADD_CHANGE, r1.getId(), r1.getPlayerCount(), r1.getPlayers()));
|
||||
}
|
||||
rr.remove(r1);
|
||||
}
|
||||
|
||||
rr.forEach(r -> resultV2List.add(new RoomResultV2(RoomResultState.ADD_CHANGE, r.getId(), r.getPlayerCount(), r.getPlayers())));
|
||||
|
||||
return new LongPollResultSingle<>(getType(), resultV2List.stream().sorted(Comparator.comparingLong(RoomResultV2::getId)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private List<RoomResult> roomToRoomResult(List<Room> rooms) {
|
||||
return rooms.stream()
|
||||
.map( r -> new RoomResult(r.getId(), r.getPlayerCount(), getParent().getRoomPlayerService().findByRoomId(r.getId()).stream()
|
||||
.map(p -> getParent().getUserService().findById(p.getUserId()))
|
||||
.map(p -> new UserResult(p.getId(), p.getUsername()))
|
||||
.collect(Collectors.toList())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<RoomResultV2> roomToRoomResult2AddChange(List<Room> rooms) {
|
||||
return rooms.stream()
|
||||
.map( r -> new RoomResultV2(RoomResultState.ADD_CHANGE, r.getId(), r.getPlayerCount(), getParent().getRoomPlayerService().findByRoomId(r.getId()).stream()
|
||||
.map(p -> getParent().getUserService().findById(p.getUserId()))
|
||||
.map(p -> new UserResult(p.getId(), p.getUsername()))
|
||||
.collect(Collectors.toList())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.alterdekim.game.component.result;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
public class LongPollResult {
|
||||
private List<LongPollResultSingle> result;
|
||||
|
||||
public <T> List<T> getResultWithType(LongPollResultType type, T elementClass) {
|
||||
return (List<T>) result.stream().filter(r -> r.getType() == type).findFirst().get().getArray();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.alterdekim.game.component.result;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class LongPollResultSingle<T> {
|
||||
private LongPollResultType type;
|
||||
private List<T> array;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.alterdekim.game.component.result;
|
||||
|
||||
public enum LongPollResultType {
|
||||
OnlineUsers,
|
||||
ChatResult,
|
||||
RoomResult,
|
||||
FriendResult,
|
||||
InviteResult
|
||||
}
|
@ -4,12 +4,16 @@ package com.alterdekim.game.controller;
|
||||
import com.alterdekim.game.component.LongPoll;
|
||||
import com.alterdekim.game.component.LongPollConfig;
|
||||
import com.alterdekim.game.component.LongPollingSession;
|
||||
import com.alterdekim.game.component.result.LongPollResult;
|
||||
import com.alterdekim.game.dto.*;
|
||||
import com.alterdekim.game.entities.Chat;
|
||||
import com.alterdekim.game.entities.Room;
|
||||
import com.alterdekim.game.entities.User;
|
||||
import com.alterdekim.game.service.*;
|
||||
import com.alterdekim.game.util.Hash;
|
||||
import com.alterdekim.game.util.StringUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -55,34 +59,12 @@ public class APIController {
|
||||
private FriendServiceImpl friendService;
|
||||
|
||||
@GetMapping("/api/v1/chat/history/{count}/")
|
||||
public ResponseEntity<ChatResult> chatList(@PathVariable Integer count ) {
|
||||
public ResponseEntity<List<ChatResult>> chatList(@PathVariable Integer count ) {
|
||||
List<Chat> results = chatService.getLastChats(count);
|
||||
results = results.stream().map( c -> {
|
||||
String message = c.getMessage();
|
||||
for( int i = 0; i < message.length(); i++ ) {
|
||||
if( message.charAt(i) == '@' ) {
|
||||
int u = message.substring(i).indexOf(' ') + i;
|
||||
String username = message.substring(i+1, u);
|
||||
User user = userService.findByUsername(username);
|
||||
if( user != null ) {
|
||||
Long uid = user.getId();
|
||||
message = message.substring(0, i) + "<a href=\"/profile/" + uid + "\" class=\"chat-history-user\"><span class=\"_nick\">" + username + "</span></a>" + message.substring(u + 1);
|
||||
} else {
|
||||
message = message.substring(0, i) + username + message.substring(u + 1);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
c.setMessage(message);
|
||||
return c;
|
||||
}).collect(Collectors.toList());
|
||||
List<UserResult> users = results.stream()
|
||||
.map(Chat::getUserId)
|
||||
.distinct()
|
||||
.map( l -> userService.findById(l) )
|
||||
.map( u -> new UserResult(u.getId(), u.getUsername()) )
|
||||
.collect(Collectors.toList());
|
||||
return ResponseEntity.ok(new ChatResult(results, users));
|
||||
return ResponseEntity.ok(results.stream()
|
||||
.peek(c -> c.setMessage(StringUtil.escapeTags(userService, c.getMessage())))
|
||||
.map(c -> new ChatResult(c, new UserResult( c.getUserId(), userService.findById(c.getUserId()).getUsername())))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@GetMapping("/api/v1/market/banners/{lang}/")
|
||||
@ -126,7 +108,7 @@ public class APIController {
|
||||
|
||||
@PostMapping("/api/v1/rooms/create/")
|
||||
public ResponseEntity<String> createRoom( @RequestParam("is_private") Boolean is_private,
|
||||
@RequestParam("players_count") Integer players_count) {
|
||||
@RequestParam("players_count") Integer players_count ) {
|
||||
if( !(players_count >= 2 && players_count <= 5) ) return ResponseEntity.badRequest().build();
|
||||
Long id = roomService.createRoom(new Room(players_count, is_private, "0"));
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
@ -136,6 +118,16 @@ public class APIController {
|
||||
return ResponseEntity.accepted().build();
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/rooms/join/")
|
||||
public ResponseEntity<String> joinRoom( @RequestParam("room_id") Long roomId ) {
|
||||
if( !roomService.findById(roomId).isPresent() ) return ResponseEntity.badRequest().build();
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
Long userId = userService.findByUsername(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername()).getId();
|
||||
roomPlayerService.leaveByUserId(userId);
|
||||
roomPlayerService.joinRoom(roomId, userId);
|
||||
return ResponseEntity.accepted().build();
|
||||
}
|
||||
|
||||
@PostMapping("/api/v1/rooms/invite/")
|
||||
public ResponseEntity<String> inviteToRoom( @RequestParam("friend_id") Long friend_id ) {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
@ -160,7 +152,9 @@ public class APIController {
|
||||
public DeferredResult<LongPollResult> getNotify(@RequestParam("last_chat_id") Long last_chat_id,
|
||||
@RequestParam("accessToken") String accessToken,
|
||||
@RequestParam("uid") Long userId,
|
||||
@RequestParam("poll_token") String poll_token) {
|
||||
@RequestParam("poll_token") String poll_token,
|
||||
@RequestParam("rids") String rooms_str,
|
||||
@RequestParam("fids") String friends_str) {
|
||||
try {
|
||||
User u = userService.findById(userId);
|
||||
if (u == null) return null;
|
||||
@ -171,18 +165,28 @@ public class APIController {
|
||||
}
|
||||
if( poll_token.length() != 32 ) return null;
|
||||
final DeferredResult<LongPollResult> deferredResult = new DeferredResult<>();
|
||||
List<RoomResult> rooms = new ArrayList<>();
|
||||
List<UserResult> friends = new ArrayList<>();
|
||||
try {
|
||||
rooms = new ObjectMapper().readValue(rooms_str, new TypeReference<List<RoomResult>>() {});
|
||||
friends = new ObjectMapper().readValue(friends_str, new TypeReference<List<UserResult>>() {});
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
if( longPoll.getMap().containsKey(userId) ){
|
||||
LongPollConfig c = longPoll.getMap().get(userId);
|
||||
if( !c.getPoll_token().equals(poll_token) ) {
|
||||
c = new LongPollConfig(last_chat_id, new ArrayList<>(), 0, poll_token, new ArrayList<>(), System.currentTimeMillis(), new ArrayList<>());
|
||||
c = new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>());
|
||||
longPoll.getLongPollingQueue().removeIf(q -> q.getUserId().longValue() == userId.longValue());
|
||||
}
|
||||
c.setRooms(rooms);
|
||||
c.setFriends_online(friends);
|
||||
c.setLast_chat_id(last_chat_id);
|
||||
c.setSession_pass(0);
|
||||
c.setLastRequest(System.currentTimeMillis());
|
||||
longPoll.getMap().put(userId, c);
|
||||
} else {
|
||||
longPoll.getMap().put(userId, new LongPollConfig(last_chat_id, new ArrayList<>(), 0, poll_token, new ArrayList<>(), System.currentTimeMillis(), new ArrayList<>()));
|
||||
longPoll.getMap().put(userId, new LongPollConfig(last_chat_id, rooms, 0, poll_token, friends, System.currentTimeMillis(), new ArrayList<>()));
|
||||
}
|
||||
longPoll.getLongPollingQueue().add(new LongPollingSession(userId, deferredResult));
|
||||
return deferredResult;
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.alterdekim.game.controller;
|
||||
|
||||
import com.alterdekim.game.entities.Image;
|
||||
import com.alterdekim.game.repository.ImageRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
@RestController
|
||||
class ImageController {
|
||||
|
||||
@Autowired
|
||||
ImageRepository imageRepository;
|
||||
|
||||
@PostMapping(value = "/image/upload/")
|
||||
private Long uploadImage(@RequestParam MultipartFile multipartImage) throws Exception {
|
||||
Image dbImage = new Image();
|
||||
dbImage.setContent(multipartImage.getBytes());
|
||||
return imageRepository.save(dbImage)
|
||||
.getId();
|
||||
}
|
||||
|
||||
@GetMapping(value = "/image/store/{imageId}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
Resource downloadImage(@PathVariable Long imageId) {
|
||||
byte[] image = imageRepository.findById(imageId)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND))
|
||||
.getContent();
|
||||
|
||||
return new ByteArrayResource(image);
|
||||
}
|
||||
}
|
@ -11,6 +11,6 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
public class ChatResult {
|
||||
private List<Chat> messages;
|
||||
private List<UserResult> users;
|
||||
private Chat message;
|
||||
private UserResult user;
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
package com.alterdekim.game.dto;
|
||||
|
||||
import com.alterdekim.game.entities.Chat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
public class LongPollResult {
|
||||
private Integer onlineCount;
|
||||
private List<Chat> messages;
|
||||
private List<UserResult> users;
|
||||
private List<RoomResultV2> rooms;
|
||||
private List<FriendResult> friends;
|
||||
private List<InviteResult> invites;
|
||||
}
|
@ -3,6 +3,7 @@ package com.alterdekim.game.dto;
|
||||
import com.alterdekim.game.entities.Room;
|
||||
import com.alterdekim.game.entities.RoomPlayer;
|
||||
import com.alterdekim.game.entities.User;
|
||||
import com.alterdekim.game.util.ListUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -16,4 +17,10 @@ public class RoomResult {
|
||||
private Long id;
|
||||
private Integer playerCount;
|
||||
private List<UserResult> players;
|
||||
|
||||
public boolean equals(RoomResult r2) {
|
||||
return this.getId().longValue() == r2.getId().longValue() &&
|
||||
this.getPlayerCount().intValue() == r2.getPlayerCount().intValue() &&
|
||||
ListUtil.isEqualListUser(this.getPlayers(), r2.getPlayers());
|
||||
}
|
||||
}
|
||||
|
@ -10,4 +10,9 @@ import lombok.NoArgsConstructor;
|
||||
public class UserResult {
|
||||
private Long id;
|
||||
private String username;
|
||||
|
||||
public boolean equals(UserResult r2) {
|
||||
return this.getId().longValue() == r2.getId().longValue() &&
|
||||
this.getUsername().equals(r2.getUsername());
|
||||
}
|
||||
}
|
||||
|
25
src/main/java/com/alterdekim/game/entities/Image.java
Normal file
25
src/main/java/com/alterdekim/game/entities/Image.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.alterdekim.game.entities;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
public class Image {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
@Lob
|
||||
byte[] content;
|
||||
}
|
@ -28,6 +28,9 @@ public class User {
|
||||
@Column(nullable=false)
|
||||
private String password;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Long avatarId;
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
|
||||
@JoinTable(
|
||||
name="users_roles",
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.alterdekim.game.repository;
|
||||
|
||||
import com.alterdekim.game.entities.Image;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ImageRepository extends JpaRepository<Image, Long> {}
|
@ -34,6 +34,7 @@ public class SpringSecurity {
|
||||
.authorizeHttpRequests((authorize) ->
|
||||
authorize
|
||||
.requestMatchers("/async/**").permitAll()
|
||||
.requestMatchers("/image/**").hasAnyAuthority("ROLE_ADMIN")
|
||||
.requestMatchers("/game").hasAnyAuthority("ROLE_ADMIN")
|
||||
.requestMatchers("/games").hasAnyAuthority("ROLE_ADMIN")
|
||||
.requestMatchers("/profile/**").hasAnyAuthority("ROLE_ADMIN")
|
||||
|
33
src/main/java/com/alterdekim/game/util/ListUtil.java
Normal file
33
src/main/java/com/alterdekim/game/util/ListUtil.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.alterdekim.game.util;
|
||||
|
||||
import com.alterdekim.game.dto.RoomResult;
|
||||
import com.alterdekim.game.dto.UserResult;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ListUtil {
|
||||
public static Boolean isEqualListRoom(List<RoomResult> r1, List<RoomResult> r2) {
|
||||
r1 = r1.stream().sorted(Comparator.comparingLong(RoomResult::getId)).collect(Collectors.toList());
|
||||
r2 = r2.stream().sorted(Comparator.comparingLong(RoomResult::getId)).collect(Collectors.toList());
|
||||
if( r1.size() != r2.size() ) return false;
|
||||
for( int i = 0; i < r1.size(); i++ ) {
|
||||
if( !r1.get(i).equals(r2.get(i)) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Boolean isEqualListUser(List<UserResult> r1, List<UserResult> r2) {
|
||||
r1 = r1.stream().sorted(Comparator.comparingLong(UserResult::getId)).collect(Collectors.toList());
|
||||
r2 = r2.stream().sorted(Comparator.comparingLong(UserResult::getId)).collect(Collectors.toList());
|
||||
if( r1.size() != r2.size() ) return false;
|
||||
for( int i = 0; i < r1.size(); i++ ) {
|
||||
if( r1.get(i).getId().longValue() != r2.get(i).getId().longValue() ||
|
||||
!r1.get(i).getUsername().equals(r2.get(i).getUsername()) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
24
src/main/java/com/alterdekim/game/util/StringUtil.java
Normal file
24
src/main/java/com/alterdekim/game/util/StringUtil.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.alterdekim.game.util;
|
||||
|
||||
import com.alterdekim.game.entities.User;
|
||||
import com.alterdekim.game.service.UserServiceImpl;
|
||||
|
||||
public class StringUtil {
|
||||
public static String escapeTags(UserServiceImpl userService, String message) {
|
||||
for (int i = 0; i < message.length(); i++) {
|
||||
if (message.charAt(i) == '@') {
|
||||
int u = message.substring(i).indexOf(' ') + i;
|
||||
String username = message.substring(i + 1, u);
|
||||
User user = userService.findByUsername(username);
|
||||
if (user != null) {
|
||||
Long uid = user.getId();
|
||||
message = message.substring(0, i) + "<a href=\"/profile/" + uid + "\" class=\"chat-history-user\"><span class=\"_nick\">" + username + "</span></a>" + message.substring(u + 1);
|
||||
} else {
|
||||
message = message.substring(0, i) + username + message.substring(u + 1);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
var isPollingActive = true;
|
||||
|
||||
var last_chat_id = 0;
|
||||
var rids = [];
|
||||
var fids = [];
|
||||
|
||||
function createRoom() {
|
||||
let isprivate = $("#flexSwitchCheckDefault").is(':checked');
|
||||
let playerscnt = $("#players-count-range").val();
|
||||
@ -21,27 +25,74 @@ function sendInviteMessage(uid) {
|
||||
method: "POST",
|
||||
data: {
|
||||
friend_id: uid
|
||||
},
|
||||
statusCode: {
|
||||
400: function() {
|
||||
$(".toast-container").append('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"><div class="toast-header"><img src="/static/images/favicon.ico" width="16" height="16" class="rounded me-2" alt="Nosedive"><strong class="me-auto">Nosedive</strong><small class="text-body-secondary">just now</small><button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button></div><div class="toast-body">Can\'t send invite.</div></div>');
|
||||
bootstrap.Toast.getOrCreateInstance($(".toast").last()).show();
|
||||
},
|
||||
200: function() {
|
||||
$(".toast-container").append('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"><div class="toast-header"><img src="/static/images/favicon.ico" width="16" height="16" class="rounded me-2" alt="Nosedive"><strong class="me-auto">Nosedive</strong><small class="text-body-secondary">just now</small><button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button></div><div class="toast-body">Successfully sent invite.</div></div>');
|
||||
bootstrap.Toast.getOrCreateInstance($(".toast").last()).show();
|
||||
}
|
||||
}
|
||||
}).done(function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
function joinRoom(obj) {
|
||||
let roomId = $(obj).attr("data-room-id");
|
||||
$.ajax({
|
||||
url: "/api/v1/rooms/join/",
|
||||
data: {
|
||||
room_id: roomId
|
||||
},
|
||||
method: "POST"
|
||||
});
|
||||
}
|
||||
|
||||
function takeInviteMessage(obj) {
|
||||
// attr data-roomId
|
||||
}
|
||||
|
||||
function successPolling(data) {
|
||||
console.log(data);
|
||||
let onlineCount = data.onlineCount;
|
||||
data = data.result;
|
||||
|
||||
let onlineCount = 0;
|
||||
let messages = [];
|
||||
let friends = [];
|
||||
let rooms = [];
|
||||
let invites = [];
|
||||
|
||||
for(let i = 0; i < data.length; i++ ) {
|
||||
let res = data[i];
|
||||
switch(res.type) {
|
||||
case "OnlineUsers":
|
||||
onlineCount = res.array[0];
|
||||
break;
|
||||
case "ChatResult":
|
||||
messages = res.array;
|
||||
break;
|
||||
case "FriendResult":
|
||||
friends = res.array;
|
||||
break;
|
||||
case "RoomResult":
|
||||
rooms = res.array;
|
||||
break;
|
||||
case "InviteResult":
|
||||
invites = res.array;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$(".chat-title").find("span").html(onlineCount + " online");
|
||||
let messages = data.messages;
|
||||
let users = data.users;
|
||||
let rooms = data.rooms;
|
||||
let friends = data.friends;
|
||||
if( messages.length > 0 ) {
|
||||
last_chat_id = messages[0].id;
|
||||
}
|
||||
for( let i = 0; i < messages.length; i++ ) {
|
||||
let obj = messages[i];
|
||||
let obj = messages[i].message;
|
||||
let time = parseTime(obj.createdAt);
|
||||
let username = findUser(users, obj.userId).username;
|
||||
let username = messages[i].user.username;
|
||||
let userid = obj.userId;
|
||||
let msgtext = obj.message;
|
||||
let html = '<div class="chat-history-one"><div class="chat-history-info"><span class="time">'+time+'</span><ion-icon name="arrow-undo-outline" class="reply-button" data-userid="'+userid+'" data-username="'+username+'" onClick="replyButtonClicked(this)"></ion-icon></div><span><span class="chat-history-text chat-history-content-message"><span class="formatter"><a href="/profile/'+userid+'" class="chat-history-user"><span class="_nick">'+username+'</span></a><ion-icon name="remove-outline"></ion-icon><span>'+msgtext+'</span></span></span></span></div>';
|
||||
@ -50,13 +101,20 @@ function successPolling(data) {
|
||||
for( let i = 0; i < rooms.length; i++ ) {
|
||||
let room = rooms[i];
|
||||
if( room.action == 'ADD_CHANGE' ) {
|
||||
for( let u = 0; u < rids.length; u++ ) {
|
||||
if( rids[u].id == room.id ) {
|
||||
rids.splice(u, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rids.push({id: room.id, playerCount: room.playerCount, players: room.players});
|
||||
let room_p_html = '';
|
||||
for( let u = 0; u < room.players.length; u++ ) {
|
||||
let room_player = room.players[u];
|
||||
room_p_html += '<div class="games-room-one-body-members-one"><div class="games-room-one-body-members-one-avatar" style="background-image: url("https://i.dogecdn.wtf/7lurfckMFrYXm4gf");"><a href="/profile/'+room_player.id+'"></a><div class="_online"></div></div><div class="games-room-one-body-members-one-nick"><a href="/profile/'+room_player.id+'">'+room_player.username+'</a></div></div>';
|
||||
}
|
||||
for( let u = 0; u < (room.playerCount - room.players.length); u++ ) {
|
||||
room_p_html += '<div class="games-room-one-body-members-one _slot_join"><div class="games-room-one-body-members-one-avatar"><ion-icon name="add-outline" style="color: #656d78;"></ion-icon></div><div class="games-room-one-body-members-one-nick"><span>Join</span></div></div>';
|
||||
room_p_html += '<div data-room-id="'+room.id+'" onclick="joinRoom(this)" class="games-room-one-body-members-one _slot_join"><div class="games-room-one-body-members-one-avatar"><ion-icon name="add-outline" style="color: #656d78;"></ion-icon></div><div class="games-room-one-body-members-one-nick"><span>Join</span></div></div>';
|
||||
}
|
||||
let room_html = '<div class="games-room-one" data-room-id="'+room.id+'"><div class="games-room-one-body"><div class="games-room-one-body-head"><div class="games-room-one-body-head-info"><div class="_type"><div>Game</div></div></div><div class="games-room-one-body-head-actions"></div></div><div class="games-room-one-body-members">'+room_p_html+'</div></div></div>';
|
||||
let has_element = false;
|
||||
@ -70,6 +128,12 @@ function successPolling(data) {
|
||||
$(".rooms-list").append(room_html);
|
||||
}
|
||||
} else if( room.action == 'REMOVE' ) {
|
||||
for( let u = 0; u < rids.length; u++ ) {
|
||||
if( rids[u].id == room.id ) {
|
||||
rids.splice(u, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$(".games-room-one").each(function() {
|
||||
if( $(this).attr("data-room-id") == room.id ) {
|
||||
$(this).remove();
|
||||
@ -80,9 +144,22 @@ function successPolling(data) {
|
||||
for( let i = 0; i < friends.length; i++ ) {
|
||||
let friend = friends[i];
|
||||
if( friend.action == 'ADD' ) {
|
||||
for( let u = 0; u < fids.length; u++ ) {
|
||||
if( fids[u].id == friend.id ) {
|
||||
fids.splice(u, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fids.push({id: friend.id, username: friend.username});
|
||||
let fr_html = '<div class="friend-one" data-friend-id="'+friend.id+'"><a href="/profile/'+friend.id+'" class="navbar-btn"><img class="navbar-profile-img" src="https://avatars.githubusercontent.com/u/102559365?v=4"></a><span>'+friend.username+'</span><ion-icon onClick="sendInviteMessage('+friend.id+')" name="person-add-outline" role="img" class="md hydrated"></ion-icon></div>';
|
||||
$(".friends-online-list").append(fr_html);
|
||||
} else if( friend.action == 'REMOVE' ) {
|
||||
for( let u = 0; u < fids.length; u++ ) {
|
||||
if( fids[u].id == friend.id ) {
|
||||
fids.splice(u, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$(".friend-one").each(function() {
|
||||
if( $(this).attr("data-friend-id") == friend.id ) {
|
||||
$(this).remove();
|
||||
@ -91,6 +168,12 @@ function successPolling(data) {
|
||||
}
|
||||
}
|
||||
|
||||
for( let i = 0; i < invites.length; i++ ) {
|
||||
let _i = invites[i];
|
||||
$(".toast-container").append('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"><div class="toast-header"><img src="/static/images/favicon.ico" width="16" height="16" class="rounded me-2" alt="Nosedive"><strong class="me-auto">Nosedive</strong><small class="text-body-secondary">just now</small><button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button></div><div class="toast-body">'+_i.username+' invites you into Nosedive room.<div class="mt-2 pt-2 border-top"><button type="button" class="btn btn-primary btn-sm" data-roomId="'+_i.roomId+'" onclick="takeInviteMessage(this)">Take invite</button><button style="margin-left: 5px;" type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="toast">Close</button></div></div></div>');
|
||||
bootstrap.Toast.getOrCreateInstance($(".toast").last()).show();
|
||||
}
|
||||
|
||||
if( friends.length > 0 ) {
|
||||
$(".friends-online-list").css("display", "");
|
||||
$("#friends_list").find(".block-content").css("display", "none");
|
||||
@ -118,6 +201,8 @@ function pollServer() {
|
||||
last_chat_id: last_chat_id,
|
||||
accessToken: accessToken,
|
||||
poll_token: poll_token,
|
||||
rids: JSON.stringify(rids),
|
||||
fids: JSON.stringify(fids),
|
||||
uid: uid
|
||||
},
|
||||
method: "POST"
|
||||
@ -141,16 +226,6 @@ $.fn.pressEnter = function(fn) {
|
||||
});
|
||||
};
|
||||
|
||||
var last_chat_id = 0;
|
||||
|
||||
function findUser(users, id) {
|
||||
for( let i = 0; i < users.length; i++ ) {
|
||||
if( users[i].id == id ) {
|
||||
return users[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseTime(unix_timestamp) {
|
||||
var date = new Date(unix_timestamp * 1000);
|
||||
var hours = "0" + date.getHours();
|
||||
@ -188,15 +263,14 @@ $(document).ready(function() {
|
||||
method: "GET"
|
||||
}).done(function(data) {
|
||||
console.log(data);
|
||||
let messages = data.messages;
|
||||
let users = data.users;
|
||||
let messages = data;
|
||||
if( messages.length > 0 ) {
|
||||
last_chat_id = messages[0].id;
|
||||
last_chat_id = messages[0].message.id;
|
||||
}
|
||||
for( let i = messages.length-1; i >= 0; i-- ) {
|
||||
let obj = messages[i];
|
||||
let obj = messages[i].message;
|
||||
let time = parseTime(obj.createdAt);
|
||||
let username = findUser(users, obj.userId).username;
|
||||
let username = messages[i].user.username;
|
||||
let userid = obj.userId;
|
||||
let msgtext = obj.message;
|
||||
let html = '<div class="chat-history-one"><div class="chat-history-info"><span class="time">'+time+'</span><ion-icon name="arrow-undo-outline" class="reply-button" data-userid="'+userid+'" data-username="'+username+'" onClick="replyButtonClicked(this)"></ion-icon></div><span><span class="chat-history-text chat-history-content-message"><span class="formatter"><a href="/profile/'+userid+'" class="chat-history-user"><span class="_nick">'+username+'</span></a><ion-icon name="remove-outline"></ion-icon><span>'+msgtext+'</span></span></span></span></div>';
|
||||
|
@ -37,6 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||
<div class="grid mt-5">
|
||||
<div class="g-col-4">
|
||||
<div class="block" id="missions_list">
|
||||
|
Loading…
x
Reference in New Issue
Block a user