Skip to content
Snippets Groups Projects
Commit 627a2f1e authored by Magix's avatar Magix Committed by GitHub
Browse files

Merge branch 'api' into development

parents fe055af5 444270fd
No related merge requests found
Showing
with 363 additions and 90 deletions
...@@ -30,6 +30,9 @@ hs_err_pid* ...@@ -30,6 +30,9 @@ hs_err_pid*
build/ build/
out/ out/
# Ignore Gradle properties
gradle.properties
# Eclipse # Eclipse
.project .project
.classpath .classpath
......
...@@ -12,11 +12,22 @@ plugins { ...@@ -12,11 +12,22 @@ plugins {
// Apply the application plugin to add support for building a CLI application // Apply the application plugin to add support for building a CLI application
id 'application' id 'application'
id 'maven-publish'
id 'signing'
} }
group = 'tech.xigam'
version = '1.0.0-dev'
sourceCompatibility = 17 sourceCompatibility = 17
targetCompatibility = 17 targetCompatibility = 17
java {
withJavadocJar()
withSourcesJar()
}
repositories { repositories {
mavenCentral() mavenCentral()
} }
...@@ -65,3 +76,68 @@ jar { ...@@ -65,3 +76,68 @@ jar {
destinationDir = file(".") destinationDir = file(".")
} }
publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'grasscutter'
from components.java
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
name = 'Grasscutter'
description = 'A server software reimplementation for an anime game.'
url = 'https://github.com/Grasscutters/Grasscutter'
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'melledy'
name = 'Melledy'
email = 'melledy@xigam.tech' // not a real email kek
}
developer {
id = 'magix'
name = 'Magix'
email = 'magix@xigam.tech'
}
}
scm {
connection = 'scm:git:git@github.com:Grasscutters/Grasscutter.git'
developerConnection = 'scm:git:ssh://github.com:Grasscutters/Grasscutter.git'
url = 'https://github.com/Grasscutters/Grasscutter'
}
}
}
}
repositories {
maven {
// change URLs to point to your repos, e.g. http://my.org/repo
def releasesRepoUrl = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
def snapshotsRepoUrl = 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
name = 'sonatype'
credentials(PasswordCredentials)
}
}
}
signing {
sign publishing.publications.mavenJava
}
javadoc {
if(JavaVersion.current().isJava9Compatible()) {
options.addBooleanOption('html5', true)
}
}
\ No newline at end of file
...@@ -36,7 +36,7 @@ public final class Grasscutter { ...@@ -36,7 +36,7 @@ public final class Grasscutter {
private static GameServer gameServer; private static GameServer gameServer;
private static PluginManager pluginManager; private static PluginManager pluginManager;
public static final Reflections reflector = new Reflections(); public static final Reflections reflector = new Reflections("emu.grasscutter");
static { static {
// Declare logback configuration. // Declare logback configuration.
...@@ -70,13 +70,13 @@ public final class Grasscutter { ...@@ -70,13 +70,13 @@ public final class Grasscutter {
// Database // Database
DatabaseManager.initialize(); DatabaseManager.initialize();
// Create plugin manager instance.
pluginManager = new PluginManager();
// Create server instances. // Create server instances.
dispatchServer = new DispatchServer(); dispatchServer = new DispatchServer();
gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port)); gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port));
// Create plugin manager instance.
pluginManager = new PluginManager();
// Start servers. // Start servers.
if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) { if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) {
dispatchServer.start(); dispatchServer.start();
......
...@@ -3,15 +3,10 @@ package emu.grasscutter.command.commands; ...@@ -3,15 +3,10 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.inventory.Inventory; import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List; import java.util.List;
@Command(label = "clear", usage = "clear <all|wp|art|mat>", //Merged /clearartifacts and /clearweapons to /clear <args> [uid] @Command(label = "clear", usage = "clear <all|wp|art|mat>", //Merged /clearartifacts and /clearweapons to /clear <args> [uid]
...@@ -33,34 +28,34 @@ public final class ClearCommand implements CommandHandler { ...@@ -33,34 +28,34 @@ public final class ClearCommand implements CommandHandler {
try { try {
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null && sender != null) { if (targetPlayer == null) {
target = sender.getUid(); target = sender.getUid();
} else { } else {
switch (cmdSwitch) { switch (cmdSwitch) {
case "wp": case "wp" -> {
playerInventory.getItems().values().stream() playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON) .filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount())); .forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " ."); sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
break; }
case "art": case "art" -> {
playerInventory.getItems().values().stream() playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY) .filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount())); .forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " ."); sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
break; }
case "mat": case "mat" -> {
playerInventory.getItems().values().stream() playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL) .filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount())); .forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " ."); sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
break; }
case "all": case "all" -> {
playerInventory.getItems().values().stream() playerInventory.getItems().values().stream()
.filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY) .filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0) .filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
...@@ -88,7 +83,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -88,7 +83,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item6 -> !item6.isLocked() && !item6.isEquipped()) .filter(item6 -> !item6.isLocked() && !item6.isEquipped())
.forEach(item6 -> playerInventory.removeItem(item6, item6.getCount())); .forEach(item6 -> playerInventory.removeItem(item6, item6.getCount()));
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " ."); sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " .");
break; }
} }
} }
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
......
...@@ -6,20 +6,19 @@ import emu.grasscutter.game.GenshinPlayer; ...@@ -6,20 +6,19 @@ import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
import java.util.List; import java.util.List;
@Command(label = "heal", usage = "heal|h", @Command(label = "heal", usage = "heal|h", aliases = {"h"},
description = "Heal all characters in your current team.", aliases = {"h"}, permission = "player.heal") description = "Heal all characters in your current team.", permission = "player.heal")
public class HealCommand implements CommandHandler { public final class HealCommand implements CommandHandler {
@Override @Override
public void execute(GenshinPlayer sender, List<String> args) { public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) { if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game."); CommandHandler.sendMessage(null, "Run this command in-game.");
return; return;
} }
sender.getTeamManager().getActiveTeam().forEach(entity -> { sender.getTeamManager().getActiveTeam().forEach(entity -> {
boolean isAlive = entity.isAlive(); boolean isAlive = entity.isAlive();
entity.setFightProperty( entity.setFightProperty(
...@@ -31,6 +30,6 @@ public class HealCommand implements CommandHandler { ...@@ -31,6 +30,6 @@ public class HealCommand implements CommandHandler {
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar())); entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
} }
}); });
CommandHandler.sendMessage(sender, "All characters are healed."); CommandHandler.sendMessage(sender, "All characters have been healed.");
} }
} }
...@@ -9,7 +9,7 @@ import java.util.List; ...@@ -9,7 +9,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@Command(label = "list", description = "List online players") @Command(label = "list", description = "List online players")
public class ListCommand implements CommandHandler { public final class ListCommand implements CommandHandler {
@Override @Override
public void execute(GenshinPlayer sender, List<String> args) { public void execute(GenshinPlayer sender, List<String> args) {
...@@ -19,14 +19,10 @@ public class ListCommand implements CommandHandler { ...@@ -19,14 +19,10 @@ public class ListCommand implements CommandHandler {
if (playersMap.size() != 0) { if (playersMap.size() != 0) {
StringBuilder playerSet = new StringBuilder(); StringBuilder playerSet = new StringBuilder();
playersMap.values().forEach(player ->
for (Map.Entry<Integer, GenshinPlayer> entry : playersMap.entrySet()) { playerSet.append(player.getNickname()).append(", "));
playerSet.append(entry.getValue().getNickname());
playerSet.append(", ");
}
String players = playerSet.toString(); String players = playerSet.toString();
CommandHandler.sendMessage(sender, players.substring(0, players.length() - 2)); CommandHandler.sendMessage(sender, players.substring(0, players.length() - 2));
} }
} }
......
...@@ -43,7 +43,7 @@ public final class SetFetterLevelCommand implements CommandHandler { ...@@ -43,7 +43,7 @@ public final class SetFetterLevelCommand implements CommandHandler {
sender.sendPacket(new PacketAvatarFetterDataNotify(avatar)); sender.sendPacket(new PacketAvatarFetterDataNotify(avatar));
CommandHandler.sendMessage(sender, "Fetter level set to " + fetterLevel); CommandHandler.sendMessage(sender, "Fetter level set to " + fetterLevel);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(null, "Invalid fetter level."); CommandHandler.sendMessage(sender, "Invalid fetter level.");
} }
} }
......
...@@ -13,7 +13,7 @@ import java.util.List; ...@@ -13,7 +13,7 @@ import java.util.List;
@Command(label = "talent", usage = "talent <talentID> <value>", @Command(label = "talent", usage = "talent <talentID> <value>",
description = "Set talent level for your current active character", permission = "player.settalent") description = "Set talent level for your current active character", permission = "player.settalent")
public class TalentCommand implements CommandHandler { public final class TalentCommand implements CommandHandler {
@Override @Override
public void execute(GenshinPlayer sender, List<String> args) { public void execute(GenshinPlayer sender, List<String> args) {
......
...@@ -9,7 +9,7 @@ import java.util.List; ...@@ -9,7 +9,7 @@ import java.util.List;
@Command(label = "teleport", usage = "teleport <x> <y> <z>", aliases = {"tp"}, @Command(label = "teleport", usage = "teleport <x> <y> <z>", aliases = {"tp"},
description = "Change the player's position.", permission = "player.teleport") description = "Change the player's position.", permission = "player.teleport")
public class TelePortCommand implements CommandHandler { public final class TeleportCommand implements CommandHandler {
@Override @Override
public void execute(GenshinPlayer sender, List<String> args) { public void execute(GenshinPlayer sender, List<String> args) {
......
...@@ -286,8 +286,6 @@ public class GachaManager { ...@@ -286,8 +286,6 @@ public class GachaManager {
this.watchService = FileSystems.getDefault().newWatchService(); this.watchService = FileSystems.getDefault().newWatchService();
Path path = new File(Grasscutter.getConfig().DATA_FOLDER).toPath(); Path path = new File(Grasscutter.getConfig().DATA_FOLDER).toPath();
path.register(watchService, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH); path.register(watchService, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH);
server.OnGameServerTick.register(this);
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload"); Grasscutter.getLogger().error("Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload");
e.printStackTrace(); e.printStackTrace();
......
package emu.grasscutter.plugin.api;
public enum Item {
/* TODO: Use handbook to generate an Item enum. */
}
package emu.grasscutter.plugin.api;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.props.EnterReason;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.utils.Position;
/**
* Hooks into the {@link GenshinPlayer} class, adding convenient ways to do certain things.
*/
public final class PlayerHook {
private final GenshinPlayer player;
/**
* Hooks into the player.
* @param player The player to hook into.
*/
public PlayerHook(GenshinPlayer player) {
this.player = player;
}
/**
* Kicks a player from the server.
*/
public void kick() {
this.player.getSession().close();
}
/**
* Sends a player to another scene.
* @param sceneId The scene to send the player to.
*/
public void changeScenes(int sceneId) {
this.player.getWorld().transferPlayerToScene(this.player, sceneId, this.player.getPos());
}
/**
* Broadcasts an avatar property notify to all world players.
* @param property The property that was updated.
*/
public void updateFightProperty(FightProperty property) {
this.broadcastPacketToWorld(new PacketAvatarFightPropUpdateNotify(this.getCurrentAvatar(), property));
}
/**
* Broadcasts the packet sent to all world players.
* @param packet The packet to send.
*/
public void broadcastPacketToWorld(GenshinPacket packet) {
this.player.getWorld().broadcastPacket(packet);
}
/**
* Set the currently equipped avatar's health.
* @param health The health to set the avatar to.
*/
public void setHealth(float health) {
this.getCurrentAvatarEntity().setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
this.updateFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
}
/**
* Revives the specified avatar.
* @param avatar The avatar to revive.
*/
public void reviveAvatar(GenshinAvatar avatar) {
this.broadcastPacketToWorld(new PacketAvatarLifeStateChangeNotify(avatar));
}
/**
* Teleports a player to a position.
* This will **not** transfer the player to another scene.
* @param position The position to teleport the player to.
*/
public void teleport(Position position) {
this.player.getPos().set(position);
this.player.sendPacket(new PacketPlayerEnterSceneNotify(this.player,
EnterType.EnterJump, EnterReason.TransPoint,
this.player.getSceneId(), position
));
}
/**
* Gets the currently selected avatar's max health.
* @return The max health as a float.
*/
public float getMaxHealth() {
return this.getCurrentAvatarEntity().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
}
/**
* Gets the currently selected avatar in entity form.
* @return The avatar as an {@link EntityAvatar}.
*/
public EntityAvatar getCurrentAvatarEntity() {
return this.player.getTeamManager().getCurrentAvatarEntity();
}
/**
* Gets the currently selected avatar.
* @return The avatar as an {@link GenshinAvatar}.
*/
public GenshinAvatar getCurrentAvatar() {
return this.getCurrentAvatarEntity().getAvatar();
}
}
\ No newline at end of file
# Grasscutter Plugin API
**Warning!** As of now, this is a work in progress and isn't completely documented.
\ No newline at end of file
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<GenshinPlayer> getOnlinePlayers() {
return new LinkedList<>(this.server.getPlayers().values());
}
}
\ No newline at end of file
...@@ -103,8 +103,8 @@ public final class DispatchServer { ...@@ -103,8 +103,8 @@ public final class DispatchServer {
byte[] decoded2 = Base64.getDecoder().decode(query_cur_region); byte[] decoded2 = Base64.getDecoder().decode(query_cur_region);
QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(decoded2); QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(decoded2);
List<RegionSimpleInfo> servers = new ArrayList<RegionSimpleInfo>(); List<RegionSimpleInfo> servers = new ArrayList<>();
List<String> usedNames = new ArrayList<String>(); // List to check for potential naming conflicts List<String> usedNames = new ArrayList<>(); // List to check for potential naming conflicts
if (Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in if (Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in
// hybrid mode // hybrid mode
RegionSimpleInfo server = RegionSimpleInfo.newBuilder() RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
...@@ -268,7 +268,10 @@ public final class DispatchServer { ...@@ -268,7 +268,10 @@ public final class DispatchServer {
Grasscutter.getLogger() Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s request: query_region_list", t.getRemoteAddress())); .info(String.format("[Dispatch] Client %s request: query_region_list", t.getRemoteAddress()));
responseHTML(t, regionListBase64); // Invoke event.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListBase64); event.call();
// Respond with event result.
responseHTML(t, event.getRegionList());
}); });
for (String regionName : regions.keySet()) { for (String regionName : regions.keySet()) {
......
...@@ -10,6 +10,10 @@ public abstract class ServerEvent extends Event { ...@@ -10,6 +10,10 @@ public abstract class ServerEvent extends Event {
this.type = type; this.type = type;
} }
public Type getServerType() {
return this.type;
}
public enum Type { public enum Type {
DISPATCH, DISPATCH,
GAME GAME
......
package emu.grasscutter.server.event.game;
import emu.grasscutter.server.event.ServerEvent;
public final class ServerTickEvent extends ServerEvent {
public ServerTickEvent() {
super(Type.GAME);
}
}
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;
}
}
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;
}
}
package emu.grasscutter.server.game; package emu.grasscutter.server.game;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.time.OffsetDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -20,7 +21,10 @@ import emu.grasscutter.game.shop.ShopManager; ...@@ -20,7 +21,10 @@ import emu.grasscutter.game.shop.ShopManager;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.netty.MihoyoKcpServer; 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 { public final class GameServer extends MihoyoKcpServer {
private final InetSocketAddress address; private final InetSocketAddress address;
...@@ -37,17 +41,9 @@ public final class GameServer extends MihoyoKcpServer { ...@@ -37,17 +41,9 @@ public final class GameServer extends MihoyoKcpServer {
private final DungeonManager dungeonManager; private final DungeonManager dungeonManager;
private final CommandMap commandMap; private final CommandMap commandMap;
public EventBus OnGameServerStartFinish;
public EventBus OnGameServerTick;
public EventBus OnGameServerStop;
public GameServer(InetSocketAddress address) { public GameServer(InetSocketAddress address) {
super(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.setServerInitializer(new GameServerInitializer(this));
this.address = address; this.address = address;
this.packetHandler = new GameServerPacketHandler(PacketHandler.class); this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
...@@ -179,11 +175,7 @@ public final class GameServer extends MihoyoKcpServer { ...@@ -179,11 +175,7 @@ public final class GameServer extends MihoyoKcpServer {
world.onTick(); world.onTick();
} }
for (GenshinPlayer player : this.getPlayers().values()) { ServerTickEvent event = new ServerTickEvent(); event.call();
player.onTick();
}
OnGameServerTick.post(new GameServerTickEvent());
} }
public void registerWorld(World world) { public void registerWorld(World world) {
...@@ -198,12 +190,11 @@ public final class GameServer extends MihoyoKcpServer { ...@@ -198,12 +190,11 @@ public final class GameServer extends MihoyoKcpServer {
@Override @Override
public void onStartFinish() { public void onStartFinish() {
Grasscutter.getLogger().info("Game Server started on port " + address.getPort()); Grasscutter.getLogger().info("Game Server started on port " + address.getPort());
ServerStartEvent event = new ServerStartEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call();
OnGameServerStartFinish.post(new GameServerStartFinishEvent());
} }
public void onServerShutdown() { public void onServerShutdown() {
OnGameServerStop.post(new GameServerStopEvent()); ServerStopEvent event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call();
// Kick and save all players // Kick and save all players
List<GenshinPlayer> list = new ArrayList<>(this.getPlayers().size()); List<GenshinPlayer> list = new ArrayList<>(this.getPlayers().size());
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment