Skip to content

Commit

Permalink
fix: resolve a crash caused by compatibility issues with the script A…
Browse files Browse the repository at this point in the history
…PI during server reload
  • Loading branch information
wu-vincent committed Jan 25, 2025
1 parent 809b3ca commit 12767cf
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 17 deletions.
5 changes: 5 additions & 0 deletions src/endstone/core/event/handlers/actor_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ GameplayHandlerResult<CoordinatorResult> EndstoneActorGameplayHandler::handleEve
return handle_->handleEvent(event);
}

std::unique_ptr<ActorGameplayHandler> EndstoneActorGameplayHandler::unwrap()
{
return std::move(handle_);
}

bool EndstoneActorGameplayHandler::handleEvent(const ActorKilledEvent &event)
{
if (const auto *mob = WeakEntityRef(event.actor_context).tryUnwrap<::Mob>(); mob && !mob->isPlayer()) {
Expand Down
1 change: 1 addition & 0 deletions src/endstone/core/event/handlers/actor_gameplay_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EndstoneActorGameplayHandler final : public ActorGameplayHandler {
HandlerResult handleEvent(const ActorGameplayEvent<void> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(const ActorGameplayEvent<CoordinatorResult> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(MutableActorGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<ActorGameplayHandler> unwrap();

private:
bool handleEvent(const ActorKilledEvent &event);
Expand Down
5 changes: 5 additions & 0 deletions src/endstone/core/event/handlers/block_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ GameplayHandlerResult<CoordinatorResult> EndstoneBlockGameplayHandler::handleEve
return std::visit(visitor, event.variant);
}

std::unique_ptr<BlockGameplayHandler> EndstoneBlockGameplayHandler::unwrap()
{
return std::move(handle_);
}

bool EndstoneBlockGameplayHandler::handleEvent(const PistonActionEvent &event)
{
// TODO(event): piston events
Expand Down
1 change: 1 addition & 0 deletions src/endstone/core/event/handlers/block_gameplay_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class EndstoneBlockGameplayHandler final : public BlockGameplayHandler {
GameplayHandlerResult<std::optional<std::string>> handleEvent(
const BlockGameplayEvent<std::optional<std::string>> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(MutableBlockGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<BlockGameplayHandler> unwrap();

private:
bool handleEvent(const PistonActionEvent &event);
Expand Down
5 changes: 5 additions & 0 deletions src/endstone/core/event/handlers/level_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ GameplayHandlerResult<CoordinatorResult> EndstoneLevelGameplayHandler::handleEve
return std::visit(visitor, event.variant);
}

std::unique_ptr<LevelGameplayHandler> EndstoneLevelGameplayHandler::unwrap()
{
return std::move(handle_);
}

bool EndstoneLevelGameplayHandler::handleEvent(const LevelAddedActorEvent &event)
{
if (auto *actor = WeakEntityRef(event.actor).tryUnwrap<::Actor>(); actor && !actor->isPlayer()) {
Expand Down
1 change: 1 addition & 0 deletions src/endstone/core/event/handlers/level_gameplay_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class EndstoneLevelGameplayHandler final : public LevelGameplayHandler {
explicit EndstoneLevelGameplayHandler(std::unique_ptr<LevelGameplayHandler> handle);
HandlerResult handleEvent(LevelGameplayEvent<void> const &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(MutableLevelGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<LevelGameplayHandler> unwrap();

private:
bool handleEvent(const LevelAddedActorEvent &event);
Expand Down
5 changes: 5 additions & 0 deletions src/endstone/core/event/handlers/player_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ GameplayHandlerResult<CoordinatorResult> EndstonePlayerGameplayHandler::handleEv
return std::visit(visitor, event.variant);
}

std::unique_ptr<PlayerGameplayHandler> EndstonePlayerGameplayHandler::unwrap()
{
return std::move(handle_);
}

bool EndstonePlayerGameplayHandler::handleEvent(const PlayerDamageEvent &event)
{
if (auto *player = WeakEntityRef(event.player).tryUnwrap<::Player>(); player) {
Expand Down
1 change: 1 addition & 0 deletions src/endstone/core/event/handlers/player_gameplay_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EndstonePlayerGameplayHandler final : public PlayerGameplayHandler {
HandlerResult handleEvent(const PlayerGameplayEvent<void> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(const PlayerGameplayEvent<CoordinatorResult> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(MutablePlayerGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<PlayerGameplayHandler> unwrap();

private:
bool handleEvent(const PlayerDamageEvent &event);
Expand Down
5 changes: 5 additions & 0 deletions src/endstone/core/event/handlers/scripting_event_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ GameplayHandlerResult<CoordinatorResult> EndstoneScriptingEventHandler::handleEv
return std::visit(visitor, event.variant);
}

std::unique_ptr<ScriptingEventHandler> EndstoneScriptingEventHandler::unwrap()
{
return std::move(handle_);
}

bool EndstoneScriptingEventHandler::handleEvent(const ScriptCommandMessageEvent &event)
{
const auto &server = entt::locator<EndstoneServer>::value();
Expand Down
1 change: 1 addition & 0 deletions src/endstone/core/event/handlers/scripting_event_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class EndstoneScriptingEventHandler final : public ScriptingEventHandler {
MutableScriptingGameplayEvent<CoordinatorResult> &event) override;
GameplayHandlerResult<CoordinatorResult> handleEvent(
const ScriptingGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<ScriptingEventHandler> unwrap();

private:
bool handleEvent(const ScriptCommandMessageEvent &event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ GameplayHandlerResult<CoordinatorResult> EndstoneServerNetworkEventHandler::hand
return std::visit(visitor, event.variant);
}

std::unique_ptr<ServerNetworkEventHandler> EndstoneServerNetworkEventHandler::unwrap()
{
return std::move(handle_);
}

bool EndstoneServerNetworkEventHandler::handleEvent(ChatEvent &event)
{
const auto &server = entt::locator<EndstoneServer>::value();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EndstoneServerNetworkEventHandler final : public ServerNetworkEventHandler
explicit EndstoneServerNetworkEventHandler(std::unique_ptr<ServerNetworkEventHandler> handle);
GameplayHandlerResult<CoordinatorResult> handleEvent(
MutableServerNetworkGameplayEvent<CoordinatorResult> &event) override;
std::unique_ptr<ServerNetworkEventHandler> unwrap();

private:
bool handleEvent(ChatEvent &event);
Expand Down
37 changes: 22 additions & 15 deletions src/endstone/core/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ EndstoneServer::~EndstoneServer()
{
py::gil_scoped_acquire acquire{};
disablePlugins();
unregisterEventListeners();
}

void EndstoneServer::init(ServerInstance &server_instance)
Expand All @@ -98,7 +99,7 @@ void EndstoneServer::setLevel(::Level &level)
scoreboard_ = std::make_unique<EndstoneScoreboard>(level.getScoreboard());
command_map_ = std::make_unique<EndstoneCommandMap>(*this);
loadResourcePacks();
registerGameplayHandlers();
registerEventListeners();
level._getPlayerDeathManager()->sender_.reset(); // prevent BDS from sending the death message
enablePlugins(PluginLoadOrder::PostWorld);
ServerLoadEvent event{ServerLoadEvent::LoadType::Startup};
Expand Down Expand Up @@ -154,22 +155,26 @@ void EndstoneServer::loadResourcePacks()
std::make_move_iterator(pack_stack->stack.end()));
}

void EndstoneServer::registerGameplayHandlers()
void EndstoneServer::registerEventListeners()
{
auto &level = level_->getHandle();
level.getActorEventCoordinator().actor_gameplay_handler_ = std::make_unique<EndstoneActorGameplayHandler>(
std::move(level.getActorEventCoordinator().actor_gameplay_handler_));
level.getBlockEventCoordinator().block_gameplay_handler_ = std::make_unique<EndstoneBlockGameplayHandler>(
std::move(level.getBlockEventCoordinator().block_gameplay_handler_));
level.getLevelEventCoordinator().level_gameplay_handler_ = std::make_unique<EndstoneLevelGameplayHandler>(
std::move(level.getLevelEventCoordinator().level_gameplay_handler_));
level.getServerPlayerEventCoordinator().player_gameplay_handler_ = std::make_unique<EndstonePlayerGameplayHandler>(
std::move(level.getServerPlayerEventCoordinator().player_gameplay_handler_));
level.getScriptingEventCoordinator().scripting_event_handler_ = std::make_unique<EndstoneScriptingEventHandler>(
std::move(level.getScriptingEventCoordinator().scripting_event_handler_));
level.getServerNetworkEventCoordinator().server_network_event_handler_ =
std::make_unique<EndstoneServerNetworkEventHandler>(
std::move(level.getServerNetworkEventCoordinator().server_network_event_handler_));
wrap<EndstoneActorGameplayHandler>(level.getActorEventCoordinator().actor_gameplay_handler_);
wrap<EndstoneBlockGameplayHandler>(level.getBlockEventCoordinator().block_gameplay_handler_);
wrap<EndstoneLevelGameplayHandler>(level.getLevelEventCoordinator().level_gameplay_handler_);
wrap<EndstonePlayerGameplayHandler>(level.getServerPlayerEventCoordinator().player_gameplay_handler_);
wrap<EndstoneScriptingEventHandler>(level.getScriptingEventCoordinator().scripting_event_handler_);
wrap<EndstoneServerNetworkEventHandler>(level.getServerNetworkEventCoordinator().server_network_event_handler_);
}

void EndstoneServer::unregisterEventListeners()
{
auto &level = level_->getHandle();
unwrap<EndstoneActorGameplayHandler>(level.getActorEventCoordinator().actor_gameplay_handler_);
unwrap<EndstoneBlockGameplayHandler>(level.getBlockEventCoordinator().block_gameplay_handler_);
unwrap<EndstoneLevelGameplayHandler>(level.getLevelEventCoordinator().level_gameplay_handler_);
unwrap<EndstonePlayerGameplayHandler>(level.getServerPlayerEventCoordinator().player_gameplay_handler_);
unwrap<EndstoneScriptingEventHandler>(level.getScriptingEventCoordinator().scripting_event_handler_);
unwrap<EndstoneServerNetworkEventHandler>(level.getServerNetworkEventCoordinator().server_network_event_handler_);
}

std::string EndstoneServer::getName() const
Expand Down Expand Up @@ -366,9 +371,11 @@ void EndstoneServer::reload()
{
plugin_manager_->clearPlugins();
command_map_->clearCommands();
unregisterEventListeners();
reloadData();

// TODO(server): Wait for at most 2.5 seconds for all async tasks to finish, otherwise issue a warning
registerEventListeners();
loadPlugins();
enablePlugins(PluginLoadOrder::Startup);
enablePlugins(PluginLoadOrder::PostWorld);
Expand Down
15 changes: 13 additions & 2 deletions src/endstone/core/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class EndstoneServer : public Server {
void init(ServerInstance &server_instance);
void setLevel(::Level &level);
void setResourcePackRepository(Bedrock::NotNullNonOwnerPtr<IResourcePackRepository> repo);
PackSource &getPackSource() const;
[[nodiscard]] PackSource &getPackSource() const;

[[nodiscard]] ServerInstance &getServer() const;

Expand All @@ -122,7 +122,18 @@ class EndstoneServer : public Server {
friend class EndstonePlayer;
void enablePlugin(Plugin &plugin);
void loadResourcePacks();
void registerGameplayHandlers();
template <typename Wrapper, typename T>
void wrap(std::unique_ptr<T> &target)
{
target = std::make_unique<Wrapper>(std::move(target));
}
void registerEventListeners();
template <typename Wrapper, typename T>
void unwrap(std::unique_ptr<T> &target)
{
target = static_cast<Wrapper *>(target.get())->unwrap();
}
void unregisterEventListeners();

ServerInstance *server_instance_{nullptr};
Logger &logger_;
Expand Down

0 comments on commit 12767cf

Please sign in to comment.