Skip to content

Commit 66b24b3

Browse files
committed
Squashed 'framework/core/' changes from de20e8b4..4c42c858
4c42c858 Merge pull request #59 from congcoi123/develop 5f353735 refactor: minor changes 0f3c86a0 Merge pull request #60 from congcoi123/feature/SP-X_Enhance_Java_Docs 00a041fd docs: minor change 18f4fd23 docs: fix java-docs and minor issues 851c074d docs(SP-X): enhance java-docs 3ac971c9 fix: minor issue 656dd95b fix: unable to start server 2ddc385e feat: add channels 0dd17fd2 fix: revert changes on allocating byte buffers 2569a576 fix: datagram channel cache should be used to write messages 2b48a310 feat: it no longer supports multiple UDP ports, instead the cache size will be used git-subtree-dir: framework/core git-subtree-split: 4c42c8587933022a29dca846a0218838b99b8991
1 parent 692d21a commit 66b24b3

338 files changed

Lines changed: 4023 additions & 853 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@
7272
## 0.6.2 2025-05-11 Feature release
7373
- Fixed several issues related to concurrency
7474
- Allowed dynamically declaring behaviors for packets processing with annotations
75+
76+
## 0.6.3 2025-06-01 Feature release
77+
- Fixed several bugs
78+
- Stopped supporting multiple UDP ports, instead it is using datagram channel cache to enhance performance
79+
- New feature and events added: Channel which allows broadcasting to subscribed players
80+

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License
22

3-
Copyright (c) 2016-2023 kong <congcoi123@gmail.com>
3+
Copyright (c) 2016-2025 kong <congcoi123@gmail.com>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ EventAccessDatagramChannelRequestValidation
4545
EventAccessDatagramChannelRequestValidationResult
4646
EventAccessKcpChannelRequestValidation
4747
EventAccessKcpChannelRequestValidationResult
48+
EventBroadcastToChannel
49+
EventChannelCreated
50+
EventChannelWillBeRemoved
4851
EventConnectionEstablishedResult
4952
EventDisconnectConnection
5053
EventDisconnectPlayer
@@ -56,6 +59,8 @@ EventPlayerJoinedRoomResult
5659
EventPlayerLoggedinResult
5760
EventPlayerReconnectedResult
5861
EventPlayerReconnectRequestHandle
62+
EventPlayerSubscribedChannel
63+
EventPlayerUnsubscribedChannel
5964
EventReceivedMessageFromPlayer
6065
EventRoomCreatedResult
6166
EventRoomWillBeRemoved

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20250511.0.6.2
1+
20250601.0.6.3

configuration.example.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
<Port name="tcp" type="tcp">8032</Port>
2222
<Port name="websocket" type="websocket">8033</Port>
2323
<Port name="kcp" type="kcp">20003</Port>
24-
<!-- It supports multiple ports, separated by commas -->
25-
<Port name="udp" type="udp">20004,20005,20006</Port>
24+
<Port name="udp" type="udp" cacheSize="10">20004</Port>
2625
<Port name="http" type="http">9999</Port>
2726
</Sockets>
2827
<Properties>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>io.github.congcoi123</groupId>
77
<artifactId>tenio-core</artifactId>
8-
<version>0.6.2</version>
8+
<version>0.6.3</version>
99
<packaging>jar</packaging>
1010

1111
<name>${project.groupId}:${project.artifactId}</name>

src/main/java/com/tenio/core/ApplicationLauncher.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
The MIT License
33
4-
Copyright (c) 2016-2023 kong <congcoi123@gmail.com>
4+
Copyright (c) 2016-2025 kong <congcoi123@gmail.com>
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal
@@ -29,14 +29,39 @@ of this software and associated documentation files (the "Software"), to deal
2929
import com.tenio.core.configuration.constant.CoreConstant;
3030
import com.tenio.core.configuration.constant.Trademark;
3131
import com.tenio.core.monitoring.system.SystemInfo;
32+
import com.tenio.core.server.Server;
3233
import com.tenio.core.server.ServerImpl;
3334
import java.util.Arrays;
3435
import java.util.Objects;
3536
import org.apache.logging.log4j.core.tools.picocli.CommandLine;
3637
import org.apache.logging.log4j.util.Strings;
3738

3839
/**
39-
* The application will start from here.
40+
* The main entry point for launching the game server application.
41+
* This class handles the initialization and startup of the server, including
42+
* configuration loading, system monitoring setup, and server instance creation.
43+
*
44+
* <p>Key features:
45+
* <ul>
46+
* <li>Command-line argument parsing</li>
47+
* <li>Configuration file loading</li>
48+
* <li>System monitoring initialization</li>
49+
* <li>Server instance creation and startup</li>
50+
* <li>Logging system configuration</li>
51+
* </ul>
52+
*
53+
* <p>Command-line options:
54+
* <ul>
55+
* <li>The first parameter: Path to the configuration file (default: configuration.xml)</li>
56+
* </ul>
57+
*
58+
* <p>Note: This class is designed to be the single entry point for the application
59+
* and should not be instantiated multiple times.
60+
*
61+
* @see Bootstrapper
62+
* @see Server
63+
* @see SystemInfo
64+
* @since 0.3.0
4065
*/
4166
public final class ApplicationLauncher extends SystemLogger {
4267

src/main/java/com/tenio/core/api/ServerApi.java

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
The MIT License
33
4-
Copyright (c) 2016-2023 kong <congcoi123@gmail.com>
4+
Copyright (c) 2016-2025 kong <congcoi123@gmail.com>
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,7 @@ of this software and associated documentation files (the "Software"), to deal
2626

2727
import com.tenio.common.data.DataCollection;
2828
import com.tenio.core.configuration.constant.CoreConstant;
29+
import com.tenio.core.entity.Channel;
2930
import com.tenio.core.entity.Player;
3031
import com.tenio.core.entity.Room;
3132
import com.tenio.core.entity.define.mode.ConnectionDisconnectMode;
@@ -37,11 +38,13 @@ of this software and associated documentation files (the "Software"), to deal
3738
import com.tenio.core.entity.manager.RoomManager;
3839
import com.tenio.core.entity.setting.InitialRoomSetting;
3940
import com.tenio.core.exception.AddedDuplicatedRoomException;
41+
import com.tenio.core.exception.CreatedDuplicatedChannelException;
4042
import com.tenio.core.handler.event.EventPlayerLoginResult;
4143
import com.tenio.core.network.entity.protocol.Response;
4244
import com.tenio.core.network.entity.session.Session;
4345
import java.util.Iterator;
4446
import java.util.List;
47+
import java.util.Map;
4548
import java.util.Optional;
4649

4750
/**
@@ -351,6 +354,81 @@ default void switchSpectatorToParticipant(Player player, Room room, int targetSl
351354
*/
352355
void removeRoom(Room room, RoomRemoveMode removeRoomMode);
353356

357+
/**
358+
* Creates a new channel.
359+
*
360+
* @param id a unique value and should not be duplicated
361+
* @param description the description of channel
362+
* @throws CreatedDuplicatedChannelException when a channel which has its id to be already
363+
* registered is added onto server.
364+
* @since 0.6.3
365+
*/
366+
void createChannel(String id, String description) throws CreatedDuplicatedChannelException;
367+
368+
/**
369+
* Creates a new channel.
370+
*
371+
* @param id a unique value and should not be duplicated
372+
* @throws CreatedDuplicatedChannelException when a channel which has its id to be already
373+
* registered is added onto server.
374+
* @since 0.6.3
375+
*/
376+
default void createChannel(String id) throws CreatedDuplicatedChannelException {
377+
createChannel(id, null);
378+
}
379+
380+
/**
381+
* Removes a channel from management.
382+
*
383+
* @param id the channel's id
384+
* @since 0.6.3
385+
*/
386+
void removeChannel(String id);
387+
388+
/**
389+
* A player subscribes to a channel.
390+
*
391+
* @param channel an instance of {@link Channel}
392+
* @param player an instance of {@link Player}
393+
* @since 0.6.3
394+
*/
395+
void subscribeToChannel(Channel channel, Player player);
396+
397+
/**
398+
* A player unsubscribes from a channel.
399+
*
400+
* @param channel an instance of {@link Channel}
401+
* @param player an instance of {@link Player}
402+
* @since 0.6.3
403+
*/
404+
void unsubscribeFromChannel(Channel channel, Player player);
405+
406+
/**
407+
* A player unsubscribes from all channels.
408+
*
409+
* @param player an instance of {@link Player}
410+
* @since 0.6.3
411+
*/
412+
void unsubscribeFromAllChannels(Player player);
413+
414+
/**
415+
* Broadcasts a message to a channel.
416+
*
417+
* @param channel an instance of {@link Channel}
418+
* @param message an instance of {@link DataCollection}
419+
* @since 0.6.3
420+
*/
421+
void broadcastToChannel(Channel channel, DataCollection message);
422+
423+
/**
424+
* Retrieves all channels that a player is subscribing to.
425+
*
426+
* @param player an instance of {@link Player}
427+
* @return a map of subscribing {@link Channel}
428+
* @since 0.6.3
429+
*/
430+
Map<String, Channel> getSubscribedChannelsForPlayer(Player player);
431+
354432
/**
355433
* Sends a message from a player to all recipients in a room.
356434
*
@@ -378,18 +456,20 @@ default void sendPrivateMessage(Player sender, Player recipient, DataCollection
378456
/**
379457
* Retrieves the current available UDP port.
380458
*
381-
* @return an {@code integer} value of UDP port
459+
* @return an {@code integer} value of UDP port if available, otherwise returns
460+
* {@link CoreConstant#NULL_PORT_VALUE}
382461
* @since 0.3.0
383462
*/
384-
int getCurrentAvailableUdpPort();
463+
int getUdpPort();
385464

386465
/**
387466
* Retrieves the current available KCP port.
388467
*
389-
* @return an {@code integer} value of KCP port if available, otherwise returns {@link CoreConstant#NULL_PORT_VALUE}
468+
* @return an {@code integer} value of KCP port if available, otherwise returns
469+
* {@link CoreConstant#NULL_PORT_VALUE}
390470
* @since 0.6.0
391471
*/
392-
int getCurrentAvailableKcpPort();
472+
int getKcpPort();
393473

394474
/**
395475
* Retrieves the current available KCP Convey Id.

src/main/java/com/tenio/core/api/implement/ServerApiImpl.java

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
The MIT License
33
4-
Copyright (c) 2016-2023 kong <congcoi123@gmail.com>
4+
Copyright (c) 2016-2025 kong <congcoi123@gmail.com>
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal
@@ -24,12 +24,11 @@ of this software and associated documentation files (the "Software"), to deal
2424

2525
package com.tenio.core.api.implement;
2626

27-
import com.tenio.common.configuration.Configuration;
27+
import com.tenio.common.data.DataCollection;
2828
import com.tenio.common.logger.SystemLogger;
2929
import com.tenio.core.api.ServerApi;
30-
import com.tenio.core.configuration.constant.CoreConstant;
31-
import com.tenio.core.configuration.define.CoreConfigurationType;
3230
import com.tenio.core.configuration.define.ServerEvent;
31+
import com.tenio.core.entity.Channel;
3332
import com.tenio.core.entity.Player;
3433
import com.tenio.core.entity.Room;
3534
import com.tenio.core.entity.define.mode.ConnectionDisconnectMode;
@@ -40,6 +39,7 @@ of this software and associated documentation files (the "Software"), to deal
4039
import com.tenio.core.entity.define.result.PlayerLeftRoomResult;
4140
import com.tenio.core.entity.define.result.PlayerLoggedInResult;
4241
import com.tenio.core.entity.define.result.RoomCreatedResult;
42+
import com.tenio.core.entity.manager.ChannelManager;
4343
import com.tenio.core.entity.manager.PlayerManager;
4444
import com.tenio.core.entity.manager.RoomManager;
4545
import com.tenio.core.entity.setting.InitialRoomSetting;
@@ -48,12 +48,12 @@ of this software and associated documentation files (the "Software"), to deal
4848
import com.tenio.core.exception.CreatedRoomException;
4949
import com.tenio.core.exception.PlayerJoinedRoomException;
5050
import com.tenio.core.exception.RemovedNonExistentPlayerException;
51-
import com.tenio.core.network.configuration.SocketConfiguration;
5251
import com.tenio.core.network.entity.session.Session;
5352
import com.tenio.core.server.Server;
5453
import java.io.IOException;
5554
import java.util.Iterator;
5655
import java.util.List;
56+
import java.util.Map;
5757
import java.util.Objects;
5858
import java.util.Optional;
5959

@@ -137,11 +137,18 @@ public void logout(Player player, ConnectionDisconnectMode connectionDisconnectM
137137

138138
try {
139139
if (player.containsSession() && player.getSession().isPresent()) {
140+
// check process on method InternalProcessorServiceImpl#processSessionWillBeClosed
140141
player.getSession().get().close(connectionDisconnectMode, playerDisconnectMode);
141142
} else {
143+
// unsubscribe it from all channels
144+
unsubscribeFromAllChannels(player);
145+
// player should leave room (if applicable) first
146+
if (player.isInRoom()) {
147+
leaveRoom(player, PlayerLeaveRoomMode.LOG_OUT);
148+
}
142149
getEventManager().emit(ServerEvent.DISCONNECT_PLAYER, player, playerDisconnectMode);
143150
String removedPlayer = player.getIdentity();
144-
getPlayerManager().removePlayerByIdentity(player.getIdentity());
151+
getPlayerManager().removePlayerByIdentity(removedPlayer);
145152
debug("DISCONNECTED PLAYER", "Player ", removedPlayer, " was removed");
146153
player.clean();
147154
}
@@ -318,17 +325,48 @@ public void removeRoom(Room room, RoomRemoveMode removeRoomMode) {
318325
}
319326

320327
@Override
321-
public int getCurrentAvailableUdpPort() {
322-
return server.getDatagramChannelManager().getCurrentAvailableUdpPort();
328+
public void createChannel(String id, String description) {
329+
getChannelManager().createChannel(id, description);
323330
}
324331

325332
@Override
326-
public int getCurrentAvailableKcpPort() {
327-
Configuration configuration = server.getConfiguration();
328-
if (Objects.isNull(configuration.get(CoreConfigurationType.NETWORK_KCP))) {
329-
return CoreConstant.NULL_PORT_VALUE;
330-
}
331-
return Integer.parseInt(((SocketConfiguration) (configuration.get(CoreConfigurationType.NETWORK_KCP))).port());
333+
public void removeChannel(String id) {
334+
getChannelManager().removeChannel(id);
335+
}
336+
337+
@Override
338+
public void subscribeToChannel(Channel channel, Player player) {
339+
getChannelManager().subscribe(channel, player);
340+
}
341+
342+
@Override
343+
public void unsubscribeFromChannel(Channel channel, Player player) {
344+
getChannelManager().unsubscribe(channel, player);
345+
}
346+
347+
@Override
348+
public void unsubscribeFromAllChannels(Player player) {
349+
getChannelManager().unsubscribe(player);
350+
}
351+
352+
@Override
353+
public void broadcastToChannel(Channel channel, DataCollection message) {
354+
getChannelManager().broadcast(channel, message);
355+
}
356+
357+
@Override
358+
public Map<String, Channel> getSubscribedChannelsForPlayer(Player player) {
359+
return getChannelManager().getSubscribedChannelsForPlayer(player);
360+
}
361+
362+
@Override
363+
public int getUdpPort() {
364+
return server.getDatagramChannelManager().getUdpPort();
365+
}
366+
367+
@Override
368+
public int getKcpPort() {
369+
return server.getDatagramChannelManager().getKcpPort();
332370
}
333371

334372
@Override
@@ -357,4 +395,8 @@ private PlayerManager getPlayerManager() {
357395
private RoomManager getRoomManager() {
358396
return server.getRoomManager();
359397
}
398+
399+
private ChannelManager getChannelManager() {
400+
return server.getChannelManager();
401+
}
360402
}

src/main/java/com/tenio/core/bootstrap/BootstrapHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
The MIT License
33
4-
Copyright (c) 2016-2023 kong <congcoi123@gmail.com>
4+
Copyright (c) 2016-2025 kong <congcoi123@gmail.com>
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal

0 commit comments

Comments
 (0)