Skip to content

Commit fd8a8ea

Browse files
committed
Fixed incorrect player disconnection #8, refactored managers communications
1 parent ecf91ae commit fd8a8ea

13 files changed

Lines changed: 137 additions & 41 deletions

File tree

example/src/main/resources/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ room:
66
loopRate: 50
77
initDelay: 1
88
startDelay: 5000
9-
endDelay: 12000
9+
endDelay: 120000

orbital-core/src/main/java/io/github/tfkfan/orbital/core/OrbitalBuilderImpl.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,15 @@ public OrbitalBuilderImpl withConfig(OrbitalConfig orbitalConfig) {
5555
return this;
5656
}
5757

58-
public OrbitalBuilderImpl withConfig(String fullPath) {
59-
configSupplier = () -> loadLocalConfig(fullPath).map(cnf -> new Pair<>(cnf, cnf.mapTo(OrbitalConfig.class)));
58+
public <C extends OrbitalConfig> OrbitalBuilderImpl withConfig(String fullPath, Class<C> configClazz) {
59+
configSupplier = () -> loadLocalConfig(fullPath).map(cnf -> new Pair<>(cnf, cnf.mapTo(configClazz)));
6060
return this;
6161
}
6262

63+
public OrbitalBuilderImpl withConfig(String fullPath) {
64+
return withConfig(fullPath, OrbitalConfig.class);
65+
}
66+
6367
public OrbitalBuilderImpl withLocalConfig() {
6468
return withConfig(DEFAULT_CONFIG_PATH);
6569
}

orbital-core/src/main/java/io/github/tfkfan/orbital/core/configuration/Fields.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public interface Fields {
77
String roomType = "roomType";
88
String sessions = "sessions";
99
String sessionId = "sessionId";
10+
String success = "success";
1011
String admin = "admin";
1112
String initialData = "initialData";
1213
String type = "type";
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package io.github.tfkfan.orbital.core.manager;
22

3+
import io.vertx.core.Vertx;
34
import lombok.extern.slf4j.Slf4j;
45

56
@Slf4j
67
public abstract class BaseGatewayManager extends BaseManager implements GatewayManager {
78
protected final MatchmakerManager matchmakerManager;
89

9-
public BaseGatewayManager(MatchmakerManager matchmakerManager) {
10+
protected BaseGatewayManager(Vertx vertx,MatchmakerManager matchmakerManager) {
11+
super(vertx);
1012
this.matchmakerManager = matchmakerManager;
1113
}
1214
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,56 @@
11
package io.github.tfkfan.orbital.core.manager;
22

3+
import io.github.tfkfan.orbital.core.configuration.Constants;
4+
import io.github.tfkfan.orbital.core.configuration.Fields;
5+
import io.github.tfkfan.orbital.core.room.RoomType;
6+
import io.github.tfkfan.orbital.core.shared.ActionType;
7+
import io.vertx.core.Future;
8+
import io.vertx.core.Vertx;
9+
import io.vertx.core.eventbus.EventBus;
10+
import io.vertx.core.eventbus.Message;
11+
import io.vertx.core.json.JsonArray;
12+
import io.vertx.core.json.JsonObject;
13+
14+
import java.util.Objects;
15+
import java.util.UUID;
16+
17+
import static io.github.tfkfan.orbital.core.verticle.BaseVerticle.defaults;
18+
319
public abstract class BaseManager implements Manager {
20+
protected final Vertx vertx;
21+
protected final EventBus eventBus;
22+
23+
protected BaseManager(Vertx vertx) {
24+
this.vertx = vertx;
25+
eventBus = vertx.eventBus();
26+
}
27+
28+
public Future<Message<JsonObject>> requestRoomManagementEvent(final UUID roomId,
29+
final ActionType actionType,
30+
final RoomType roomType,
31+
final JsonArray userSessions) {
32+
return eventBus.request(Constants.ROOM_VERTICAL_CHANNEL, makeData(roomId, actionType, roomType, userSessions), defaults());
33+
}
34+
35+
public void publishRoomManagementEvent(final UUID roomId,
36+
final ActionType actionType,
37+
final RoomType roomType,
38+
final JsonArray userSessions) {
39+
eventBus.publish(Constants.ROOM_VERTICAL_CHANNEL, makeData(roomId, actionType, roomType, userSessions), defaults());
40+
}
41+
42+
private JsonObject makeData(final UUID roomId,
43+
final ActionType actionType,
44+
final RoomType roomType,
45+
final JsonArray userSessions) {
46+
final JsonObject data = new JsonObject()
47+
.put(Fields.action, actionType)
48+
.put(Fields.roomId, roomId.toString())
49+
.put(Fields.sessions, userSessions);
50+
51+
if (Objects.nonNull(roomType))
52+
data.put(Fields.roomType, roomType.toString());
53+
54+
return data;
55+
}
456
}

orbital-core/src/main/java/io/github/tfkfan/orbital/core/manager/BaseMatchmakerManager.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,35 @@
66
import io.github.tfkfan.orbital.core.configuration.props.RoomConfig;
77
import io.github.tfkfan.orbital.core.event.*;
88
import io.github.tfkfan.orbital.core.network.message.Message;
9+
import io.github.tfkfan.orbital.core.room.GameRoom;
910
import io.github.tfkfan.orbital.core.room.RoomType;
1011
import io.github.tfkfan.orbital.core.route.MessageRoute;
1112
import io.github.tfkfan.orbital.core.session.GatewaySession;
1213
import io.github.tfkfan.orbital.core.shared.ActionType;
1314
import io.github.tfkfan.orbital.core.shared.UniqueQueue;
15+
import io.vertx.core.Future;
1416
import io.vertx.core.Vertx;
15-
import io.vertx.core.eventbus.DeliveryOptions;
1617
import io.vertx.core.eventbus.EventBus;
1718
import io.vertx.core.json.JsonArray;
1819
import io.vertx.core.json.JsonObject;
1920
import lombok.extern.slf4j.Slf4j;
2021

2122
import java.util.Collections;
2223
import java.util.List;
24+
import java.util.Objects;
2325
import java.util.UUID;
2426
import java.util.stream.Collectors;
2527

28+
import static io.github.tfkfan.orbital.core.verticle.BaseVerticle.defaults;
29+
2630
@Slf4j
2731
public abstract class BaseMatchmakerManager extends BaseManager implements MatchmakerManager {
28-
protected final Vertx vertx;
29-
protected final EventBus eventBus;
3032
protected final RoomConfig roomConfig;
3133
private final UniqueQueue<GameRoomJoinEvent> playersQueue = new UniqueQueue<>();
3234

33-
public BaseMatchmakerManager(RoomConfig roomConfig) {
35+
public BaseMatchmakerManager(Vertx vertx, RoomConfig roomConfig) {
36+
super(vertx);
3437
this.roomConfig = roomConfig;
35-
vertx = Vertx.currentContext().owner();
36-
eventBus = vertx.eventBus();
3738
initConsumers();
3839
}
3940

@@ -47,6 +48,9 @@ protected void initConsumers() {
4748
@Override
4849
public void onDisconnect(GatewaySession data) {
4950
playersQueue.removeIf(e -> e.getSession().getId().equals(data.getId()));
51+
publishRoomManagementEvent(data.getRoomKey(), ActionType.PLAYER_DISCONNECT, null, new JsonArray(
52+
Collections.singletonList(new JsonObject().put(Fields.sessionId, data.getId()))
53+
));
5054
}
5155

5256
@Override
@@ -66,7 +70,7 @@ protected void onJoin(GameRoomJoinEvent joinEvent) {
6670
}
6771

6872
protected void handleJoinTraining(final GameRoomJoinEvent joinEvent) {
69-
newRoomEvent(newRoomId(), RoomType.TRAINING, Collections.singletonList(joinEvent));
73+
requestRoomManagementCreateEvent(newRoomId(), RoomType.TRAINING, Collections.singletonList(joinEvent));
7074
}
7175

7276
protected void handleJoin(final RoomType roomType, final GameRoomJoinEvent joinEvent) {
@@ -77,27 +81,20 @@ protected void handleJoin(final RoomType roomType, final GameRoomJoinEvent joinE
7781
if (playersQueue.size() < roomConfig.getMaxPlayers())
7882
return;
7983

80-
newRoomEvent(newRoomId(), roomType, playersQueue.chunk(roomConfig.getMaxPlayers()));
84+
requestRoomManagementCreateEvent(newRoomId(), roomType, playersQueue.chunk(roomConfig.getMaxPlayers()));
8185
}
8286

8387
private UUID newRoomId() {
8488
return UUID.randomUUID();
8589
}
8690

87-
protected void newRoomEvent(final UUID roomId, final RoomType roomType, final List<GameRoomJoinEvent> userSessions) {
88-
eventBus.sender(Constants.ROOM_VERTICAL_CHANNEL, new DeliveryOptions()
89-
.setLocalOnly(true)
90-
.setSendTimeout(1000))
91-
.write(new JsonObject()
92-
.put(Fields.action, ActionType.NEW_ROOM)
93-
.put(Fields.roomId, roomId.toString())
94-
.put(Fields.roomType, roomType.toString())
95-
.put(Fields.sessions, new JsonArray(userSessions.stream().map(e ->
96-
new JsonObject()
97-
.put(Fields.sessionId, e.getSession().getId())
98-
.put(Fields.admin, e.getSession().isAdmin())
99-
.put(Fields.initialData, e.getData()))
100-
.collect(Collectors.toList()))))
91+
protected void requestRoomManagementCreateEvent(final UUID roomId, final RoomType roomType, List<GameRoomJoinEvent> userSessions) {
92+
requestRoomManagementEvent(roomId, ActionType.NEW_ROOM, roomType, new JsonArray(userSessions.stream().map(e ->
93+
new JsonObject()
94+
.put(Fields.sessionId, e.getSession().getId())
95+
.put(Fields.admin, e.getSession().isAdmin())
96+
.put(Fields.initialData, e.getData()))
97+
.collect(Collectors.toList())))
10198
.onSuccess(t -> userSessions.forEach(it -> it.getSession().setRoomKey(roomId)))
10299
.onFailure(t -> {
103100
log.error("Room verticle {} failed to join", roomId, t);

orbital-core/src/main/java/io/github/tfkfan/orbital/core/manager/WebSocketManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
import io.vertx.core.Handler;
44
import io.vertx.core.http.ServerWebSocket;
55

6-
public interface WebSocketManager extends GatewayManager, Handler<ServerWebSocket>,Manager {
6+
public interface WebSocketManager extends GatewayManager, Handler<ServerWebSocket>, Manager {
77
}

orbital-core/src/main/java/io/github/tfkfan/orbital/core/manager/impl/GameManagerImpl.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,38 @@ public GameManagerImpl(String verticleId,
5555
}
5656

5757
protected void onMessage(Message<JsonObject> message) {
58-
log.info("Received a message to room {} : {}", verticleId, message.body().encode());
58+
log.info("Received a message at room verticle {} : {}", verticleId, message.body().encode());
5959
final JsonObject json = message.body();
6060
final String rawAction = json.getString(Fields.action);
61-
if (rawAction != null) {
62-
ActionType actionType = ActionType.valueOf(rawAction);
63-
if (actionType.equals(ActionType.NEW_ROOM)) {
61+
if (rawAction != null)
62+
onRoom(ActionType.valueOf(rawAction), message, json);
63+
}
64+
65+
protected void onRoom(ActionType actionType, Message<JsonObject> message, JsonObject json) {
66+
switch (actionType) {
67+
case NEW_ROOM -> {
6468
final S gameState = gameStateFactory.get();
6569
final RoomType roomType = RoomType.valueOf(json.getString(Fields.roomType));
6670
final UUID roomId = UUID.fromString(json.getString(Fields.roomId));
67-
final GameRoom room = createRoom(roomId, roomType, gameState, json.getJsonArray(Fields.sessions));
71+
final GameRoom room = onNewRoom(roomId, roomType, gameState, json.getJsonArray(Fields.sessions));
6872
room.onStart();
6973
}
74+
case PLAYER_DISCONNECT -> {
75+
final List<String> sessionsIds = json.getJsonArray(Fields.sessions).stream().map(it -> ((JsonObject) it).getString(Fields.sessionId)).toList();
76+
sessionsIds.forEach(sessionId -> {
77+
try {
78+
final PlayerSession session = playerSessionsMap.remove(sessionId);
79+
if (session != null)
80+
session.getPlayer().getGameRoom().onDisconnect(session);
81+
} catch (Exception ignored) {
82+
}
83+
});
84+
}
7085
}
86+
message.reply(new JsonObject().put(Fields.success, true));
7187
}
7288

73-
protected GameRoom createRoom(final UUID roomId, final RoomType roomType, final S gameState, JsonArray playersSessions) {
89+
protected GameRoom onNewRoom(final UUID roomId, final RoomType roomType, final S gameState, JsonArray playersSessions) {
7490
validatePlayersCount(roomType, playersSessions, roomId);
7591

7692
final GameRoom room = gameRoomFactory.createGameRoom(verticleId, roomId, roomType,

orbital-core/src/main/java/io/github/tfkfan/orbital/core/manager/impl/MatchmakerManagerImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
import io.github.tfkfan.orbital.core.configuration.props.RoomConfig;
44
import io.github.tfkfan.orbital.core.manager.BaseMatchmakerManager;
5+
import io.vertx.core.Vertx;
56
import lombok.extern.slf4j.Slf4j;
67

78
@Slf4j
89
public class MatchmakerManagerImpl extends BaseMatchmakerManager {
910
public MatchmakerManagerImpl(RoomConfig roomConfig) {
10-
super(roomConfig);
11+
super(Vertx.currentContext().owner(), roomConfig);
1112
}
1213
}

orbital-core/src/main/java/io/github/tfkfan/orbital/core/manager/impl/WebSocketManagerImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020

2121
@Slf4j
2222
public class WebSocketManagerImpl extends BaseGatewayManager implements WebSocketManager {
23-
protected final Vertx vertx = Vertx.currentContext().owner();
2423
protected final RouteProcessor routeProcessor;
2524

2625
public WebSocketManagerImpl(MatchmakerManager matchmakerManager) {
27-
super(matchmakerManager);
26+
super(Vertx.currentContext().owner(), matchmakerManager);
2827
this.routeProcessor = new RouteProcessor(matchmakerManager);
2928
}
3029

@@ -74,7 +73,7 @@ private void onMessage(GatewaySession userSession, JsonObject message) {
7473

7574
@Override
7675
public void broadcast(MessageType type, String message) {
77-
log.error("broadcast not implemented yet");
76+
broadcast(type.getType(), message);
7877
}
7978

8079
@Override
@@ -89,6 +88,7 @@ public void broadcast(int messageType, Object content) {
8988

9089
@Override
9190
public void broadcast(Function<Session, JsonObject> messageFunction) {
91+
9292
}
9393

9494
@Override

0 commit comments

Comments
 (0)