diff --git a/src/main/java/emu/grasscutter/Grasscutter.java b/src/main/java/emu/grasscutter/Grasscutter.java index 3db73eb1b..dcd6a3b6f 100644 --- a/src/main/java/emu/grasscutter/Grasscutter.java +++ b/src/main/java/emu/grasscutter/Grasscutter.java @@ -70,13 +70,13 @@ public final class Grasscutter { // Database DatabaseManager.initialize(); + // Create plugin manager instance. + pluginManager = new PluginManager(); + // Create server instances. dispatchServer = new DispatchServer(); gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port)); - // Create plugin manager instance. - pluginManager = new PluginManager(); - // Start servers. if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) { dispatchServer.start(); diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaManager.java b/src/main/java/emu/grasscutter/game/gacha/GachaManager.java index 079f0dda3..ffb68a1d7 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaManager.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaManager.java @@ -286,8 +286,6 @@ public class GachaManager { this.watchService = FileSystems.getDefault().newWatchService(); Path path = new File(Grasscutter.getConfig().DATA_FOLDER).toPath(); path.register(watchService, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH); - - server.OnGameServerTick.register(this); } catch (Exception e) { Grasscutter.getLogger().error("Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload"); e.printStackTrace(); diff --git a/src/main/java/emu/grasscutter/plugin/api/ServerHook.java b/src/main/java/emu/grasscutter/plugin/api/ServerHook.java new file mode 100644 index 000000000..34ceb25f4 --- /dev/null +++ b/src/main/java/emu/grasscutter/plugin/api/ServerHook.java @@ -0,0 +1,41 @@ +package emu.grasscutter.plugin.api; + +import emu.grasscutter.game.GenshinPlayer; +import emu.grasscutter.server.game.GameServer; + +import java.util.LinkedList; +import java.util.List; + +/** + * Hooks into the {@link GameServer} class, adding convenient ways to do certain things. + */ +public final class ServerHook { + private static ServerHook instance; + private final GameServer server; + + /** + * Gets the server hook instance. + * @return A {@link ServerHook} singleton. + */ + public static ServerHook getInstance() { + return instance; + } + + /** + * Hooks into a server. + * @param server The server to hook into. + */ + public ServerHook(GameServer server) { + this.server = server; + + instance = this; + } + + /** + * Gets all online players. + * @return Players connected to the server. + */ + public List getOnlinePlayers() { + return new LinkedList<>(this.server.getPlayers().values()); + } +} \ No newline at end of file diff --git a/src/main/java/emu/grasscutter/server/event/ServerEvent.java b/src/main/java/emu/grasscutter/server/event/ServerEvent.java index e87abae0d..5e73afdec 100644 --- a/src/main/java/emu/grasscutter/server/event/ServerEvent.java +++ b/src/main/java/emu/grasscutter/server/event/ServerEvent.java @@ -10,6 +10,10 @@ public abstract class ServerEvent extends Event { this.type = type; } + public Type getServerType() { + return this.type; + } + public enum Type { DISPATCH, GAME diff --git a/src/main/java/emu/grasscutter/server/event/game/ServerTickEvent.java b/src/main/java/emu/grasscutter/server/event/game/ServerTickEvent.java new file mode 100644 index 000000000..8ca7c8379 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/event/game/ServerTickEvent.java @@ -0,0 +1,9 @@ +package emu.grasscutter.server.event.game; + +import emu.grasscutter.server.event.ServerEvent; + +public final class ServerTickEvent extends ServerEvent { + public ServerTickEvent() { + super(Type.GAME); + } +} diff --git a/src/main/java/emu/grasscutter/server/event/internal/ServerStartEvent.java b/src/main/java/emu/grasscutter/server/event/internal/ServerStartEvent.java new file mode 100644 index 000000000..fd950a002 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/event/internal/ServerStartEvent.java @@ -0,0 +1,19 @@ +package emu.grasscutter.server.event.internal; + +import emu.grasscutter.server.event.ServerEvent; + +import java.time.OffsetDateTime; + +public final class ServerStartEvent extends ServerEvent { + private final OffsetDateTime startTime; + + public ServerStartEvent(Type type, OffsetDateTime startTime) { + super(type); + + this.startTime = startTime; + } + + public OffsetDateTime getStartTime() { + return this.startTime; + } +} diff --git a/src/main/java/emu/grasscutter/server/event/internal/ServerStopEvent.java b/src/main/java/emu/grasscutter/server/event/internal/ServerStopEvent.java new file mode 100644 index 000000000..5d105e3b3 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/event/internal/ServerStopEvent.java @@ -0,0 +1,19 @@ +package emu.grasscutter.server.event.internal; + +import emu.grasscutter.server.event.ServerEvent; + +import java.time.OffsetDateTime; + +public final class ServerStopEvent extends ServerEvent { + private final OffsetDateTime stopTime; + + public ServerStopEvent(Type type, OffsetDateTime stopTime) { + super(type); + + this.stopTime = stopTime; + } + + public OffsetDateTime getStopTime() { + return this.stopTime; + } +} diff --git a/src/main/java/emu/grasscutter/server/game/GameServer.java b/src/main/java/emu/grasscutter/server/game/GameServer.java index 065344ee2..a1986d1a2 100644 --- a/src/main/java/emu/grasscutter/server/game/GameServer.java +++ b/src/main/java/emu/grasscutter/server/game/GameServer.java @@ -1,6 +1,7 @@ package emu.grasscutter.server.game; import java.net.InetSocketAddress; +import java.time.OffsetDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -19,7 +20,10 @@ import emu.grasscutter.game.shop.ShopManager; import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.netty.MihoyoKcpServer; -import org.greenrobot.eventbus.EventBus; +import emu.grasscutter.server.event.ServerEvent; +import emu.grasscutter.server.event.game.ServerTickEvent; +import emu.grasscutter.server.event.internal.ServerStartEvent; +import emu.grasscutter.server.event.internal.ServerStopEvent; public final class GameServer extends MihoyoKcpServer { private final InetSocketAddress address; @@ -34,18 +38,10 @@ public final class GameServer extends MihoyoKcpServer { private final MultiplayerManager multiplayerManager; private final DungeonManager dungeonManager; private final CommandMap commandMap; - - public EventBus OnGameServerStartFinish; - public EventBus OnGameServerTick; - public EventBus OnGameServerStop; public GameServer(InetSocketAddress address) { super(address); - OnGameServerStartFinish = EventBus.builder().throwSubscriberException(true).logNoSubscriberMessages(false).build(); - OnGameServerTick = EventBus.builder().throwSubscriberException(true).logNoSubscriberMessages(false).build(); - OnGameServerStop = EventBus.builder().throwSubscriberException(true).logNoSubscriberMessages(false).build(); - this.setServerInitializer(new GameServerInitializer(this)); this.address = address; this.packetHandler = new GameServerPacketHandler(PacketHandler.class); @@ -160,23 +156,22 @@ public final class GameServer extends MihoyoKcpServer { return DatabaseHelper.getAccountByName(username); } - public void onTick() throws Exception { + public void onTick() { for (GenshinPlayer player : this.getPlayers().values()) { player.onTick(); } - OnGameServerTick.post(new GameServerTickEvent()); + ServerTickEvent event = new ServerTickEvent(); event.call(); } @Override public void onStartFinish() { Grasscutter.getLogger().info("Game Server started on port " + address.getPort()); - - OnGameServerStartFinish.post(new GameServerStartFinishEvent()); + ServerStartEvent event = new ServerStartEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call(); } public void onServerShutdown() { - OnGameServerStop.post(new GameServerStopEvent()); + ServerStopEvent event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call(); // Kick and save all players List list = new ArrayList<>(this.getPlayers().size());