Skip to content

Commit

Permalink
refactor: ActorSpawnEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-vincent committed Jan 15, 2025
1 parent 529c2fa commit 4df58ee
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 69 deletions.
5 changes: 4 additions & 1 deletion src/bedrock/forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,10 @@ class TypedObjectHandle;
} // namespace Scripting
namespace ScriptModuleMinecraft {
class IScriptWorldBeforeEvents;
}
class ScriptBlockComponentRegistry;
class ScriptItemComponentRegistry;
class ScriptPropertyRegistry;
} // namespace ScriptModuleMinecraft

// Template Classes
template <typename A, typename B, typename C>
Expand Down
2 changes: 2 additions & 0 deletions src/bedrock/scripting/lifetime_registry/lifetime_scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
namespace Scripting {
class WeakLifetimeScope {
public:
WeakLifetimeScope();

protected:
LifetimeRegistryReference *registry_ref_; // +0
std::uint32_t version_; // +8
Expand Down
33 changes: 33 additions & 0 deletions src/bedrock/scripting/lifetime_registry/object_handle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "bedrock/scripting/runtime/context_id.h"

namespace Scripting {

enum class ObjectHandleValue : uint64_t {
};

struct ObjectHandle {
static const size_t ContextIdShift = 56;
ObjectHandle();
ObjectHandle(ObjectHandleValue, ContextId);
ObjectHandle(uint64_t);
ObjectHandleValue value;
ContextId context_id;
};

} // namespace Scripting
33 changes: 33 additions & 0 deletions src/bedrock/scripting/lifetime_registry/smart_object_handle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "bedrock/scripting/lifetime_registry/lifetime_scope.h"
#include "bedrock/scripting/lifetime_registry/object_handle.h"

namespace Scripting {
class StrongObjectHandle {
public:
StrongObjectHandle(WeakLifetimeScope, ObjectHandle, bool);

protected:
WeakLifetimeScope scope_;
ObjectHandle handle_;
};

template <typename T>
class StrongTypedObjectHandle : public StrongObjectHandle {};

} // namespace Scripting
23 changes: 23 additions & 0 deletions src/bedrock/scripting/runtime/context_id.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

namespace Scripting {
struct ContextId {
ContextId();
ContextId(std::uint8_t);
std::uint8_t value;
};
} // namespace Scripting
4 changes: 0 additions & 4 deletions src/bedrock/symbol_generator/symbols.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ version = "1.21.50"
"?setUserData@ItemStackBase@@QEAAXV?$unique_ptr@VCompoundTag@@U?$default_delete@VCompoundTag@@@std@@@std@@@Z" = 40591680
# Level
"?tick@Level@@UEAAXXZ" = 39489328
# LevelEventCoordinator
"?_postReloadActorAdded@LevelEventCoordinator@@AEAAXAEAVActor@@W4ActorInitializationMethod@@@Z" = 36309440
# MinecraftCommands
"?compileCommand@MinecraftCommands@@QEAAPEAVCommand@@AEBVHashedString@@AEAVCommandOrigin@@W4CurrentCmdVersion@@V?$function@$$A6AXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z@std@@@Z" = 22148496
"?executeCommand@MinecraftCommands@@QEBA?AUMCRESULT@@AEAVCommandContext@@_N@Z" = 22217824
Expand Down Expand Up @@ -148,8 +146,6 @@ version = "1.21.50"
"_ZN13ItemStackBase11setUserDataENSt3__110unique_ptrI11CompoundTagNS0_14default_deleteIS2_EEEE" = 133040528
# Level
"_ZN5Level4tickEv" = 130259312
# LevelEventCoordinator
"_ZN21LevelEventCoordinator21_postReloadActorAddedER5Actor25ActorInitializationMethod" = 129209008
# MinecraftCommands
"_ZN17MinecraftCommands14compileCommandERK12HashedStringR13CommandOrigin17CurrentCmdVersionNSt3__18functionIFvRKNS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEEEE" = 113630544
"_ZNK17MinecraftCommands14executeCommandER14CommandContextb" = 113627248
Expand Down
3 changes: 1 addition & 2 deletions src/bedrock/world/events/level_event_coordinator.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
#include "bedrock/world/events/event_coordinator.h"
#include "bedrock/world/events/level_event_listener.h"

class LevelEventCoordinator : public EventCoordinatorPimpl<LevelEventListener> {
class LevelEventCoordinator : public EventCoordinator<LevelEventListener> {
public:
private:
friend class endstone::core::EndstoneServer;
ENDSTONE_HOOK void _postReloadActorAdded(Actor &, ActorInitializationMethod);
std::unique_ptr<LevelGameplayHandler> level_gameplay_handler_; // +112
Bedrock::PubSub::Subscription game_rule_change_subscription_;
Bedrock::PubSub::Subscription on_remove_actor_entity_references_subscription_;
Expand Down
59 changes: 42 additions & 17 deletions src/bedrock/world/events/level_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,41 @@

#include <variant>

#include "bedrock/core/math/vec3.h"
#include "bedrock/core/utility/non_owner_pointer.h"
#include "bedrock/entity/gamerefs_entity/entity_context.h"
#include "bedrock/entity/gamerefs_entity/gamerefs_entity.h"
#include "bedrock/gameplayhandlers/coordinator_result.h"
#include "bedrock/gamerefs/weak_ref.h"
#include "bedrock/scripting/lifetime_registry/lifetime_scope.h"
#include "bedrock/scripting/lifetime_registry/smart_object_handle.h"
#include "bedrock/world/events/event_variant.h"
#include "bedrock/world/level/storage/game_rules.h"

class Level;

struct LevelAddedActorEvent {
Bedrock::NonOwnerPointer<Level> level; // +0
WeakRef<EntityContext> actor; // +16
gsl::not_null<Bedrock::NonOwnerPointer<Level>> level; // +0
WeakRef<EntityContext> actor; // +16
};
struct LevelBroadcastEvent {
const LevelEvent type;
const Vec3 pos;
const int data;
};
struct LevelSoundBroadcastEvent {
const LevelSoundEvent type;
const Vec3 pos;
const int data;
};
struct LevelDayCycleEvent {
int time_tick_in_day;
};
struct LevelGameRuleChangeEvent {
GameRules::GameRulesIndex rule;
GameRule::Type type;
GameRule::Value value;
};
struct LevelBroadcastEvent {};
struct LevelSoundBroadcastEvent {};
struct LevelDayCycleEvent {};
struct LevelStartLeaveGameEvent {};
struct LevelGameRuleChangeEvent {};
struct ScriptingInitializeEvent {};

template <typename Return>
struct LevelGameplayEvent;

template <>
struct LevelGameplayEvent<void>
: ConstEventVariant<LevelAddedActorEvent, LevelBroadcastEvent, LevelSoundBroadcastEvent, LevelDayCycleEvent,
LevelStartLeaveGameEvent, LevelGameRuleChangeEvent, ScriptingInitializeEvent> {};

struct LevelWeatherChangedEvent {
const bool is_raining;
const bool is_lightning;
Expand All @@ -52,6 +59,24 @@ struct LevelWeatherChangedEvent {
int rain_time;
int lightning_time;
};
struct ScriptingWorldInitializeEvent {
Scripting::StrongTypedObjectHandle<ScriptModuleMinecraft::ScriptPropertyRegistry> registry;
Scripting::StrongTypedObjectHandle<ScriptModuleMinecraft::ScriptBlockComponentRegistry> block_component_registry;
Scripting::StrongTypedObjectHandle<ScriptModuleMinecraft::ScriptItemComponentRegistry> item_component_registry;
Scripting::WeakLifetimeScope scope;
bool final_event;
};
struct LevelStartLeaveGameEvent {
gsl::not_null<Bedrock::NonOwnerPointer<Level>> level;
};

template <typename Return>
struct LevelGameplayEvent;

template <>
struct LevelGameplayEvent<void>
: ConstEventVariant<LevelAddedActorEvent, LevelBroadcastEvent, LevelSoundBroadcastEvent, LevelDayCycleEvent,
LevelStartLeaveGameEvent, LevelGameRuleChangeEvent, ScriptingWorldInitializeEvent> {};

template <typename Return>
struct MutableLevelGameplayEvent;
Expand Down
87 changes: 86 additions & 1 deletion src/bedrock/world/level/storage/game_rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,89 @@

#pragma once

class GameRules {};
class GameRule {
public:
enum class Type : uint8_t {
Invalid = 0,
Bool = 1,
Int = 2,
Float = 3,
};

union Value {
bool bool_val;
int int_val;
float float_val;
Value() = default;
Value(const bool val) : bool_val(val) {}
Value(const int val) : int_val(val) {}
Value(const float val) : float_val(val) {}
Value &operator=(const bool val)
{
bool_val = val;
return *this;
}
Value &operator=(const int val)
{
int_val = val;
return *this;
}
Value &operator=(const float val)
{
float_val = val;
return *this;
}
};
};

class GameRules : public Bedrock::EnableNonOwnerReferences {
public:
enum GameRulesIndex : int {
INVALID_GAME_RULE = -1,
COMMAND_BLOCK_OUTPUT = 0,
DO_DAYLIGHT_CYCLE = 1,
DO_ENTITY_DROPS = 2,
DO_FIRE_TICK = 3,
RECIPES_UNLOCK = 4,
DO_LIMITED_CRAFTING = 5,
DO_MOB_LOOT = 6,
DO_MOB_SPAWNING = 7,
DO_TILE_DROPS = 8,
DO_WEATHER_CYCLE = 9,
DROWNING_DAMAGE = 10,
FALL_DAMAGE = 11,
FIRE_DAMAGE = 12,
KEEP_INVENTORY = 13,
MOB_GRIEFING = 14,
PVP = 15,
SHOW_COORDINATES = 16,
SHOW_DAYS_PLAYED = 17,
DO_NATURAL_REGENERATION = 18,
DO_TNT_EXPLODE = 19,
SEND_COMMAND_FEEDBACK = 20,
MAX_COMMAND_CHAIN_LENGTH = 21,
DO_INSOMNIA = 22,
COMMAND_BLOCKS_ENABLED = 23,
RANDOM_TICK_SPEED = 24,
DO_IMMEDIATE_RESPAWN = 25,
SHOW_DEATH_MESSAGES = 26,
FUNCTION_COMMAND_LIMIT = 27,
PLAYER_SPAWN_RADIUS = 28,
SHOW_TAGS = 29,
FREEZE_DAMAGE = 30,
RESPAWN_BLOCKS_EXPLODE = 31,
SHOW_BORDER_EFFECT = 32,
SHOW_RECIPE_MESSAGES = 33,
PLAYER_SLEEPING_PERCENTAGE = 34,
PROJECTILES_CAN_BREAK_BLOCKS = 35,
TNT_EXPLOSION_DROP_DECAY = 36,
VANILLA_GAME_RULE_COUNT = 37,
GLOBAL_MUTE = 37,
ALLOW_DESTRUCTIVE_OBJECTS = 38,
ALLOW_MOBS = 39,
CODE_BUILDER = 40,
EDU_CLOUD_SAVE = 41,
EDU_GAME_RULE_COUNT = 42,
GAME_RULE_COUNT = 42,
};
};
33 changes: 30 additions & 3 deletions src/endstone/core/event/handlers/level_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "bedrock/world/actor/player/player.h"
#include "bedrock/world/events/level_events.h"
#include "endstone/core/server.h"
#include "endstone/event/actor/actor_spawn_event.h"
#include "endstone/event/weather/thunder_change_event.h"
#include "endstone/event/weather/weather_change_event.h"

Expand All @@ -32,20 +33,45 @@ EndstoneLevelGameplayHandler::EndstoneLevelGameplayHandler(std::unique_ptr<Level

HandlerResult EndstoneLevelGameplayHandler::handleEvent(LevelGameplayEvent<void> const &event)
{
return handle_->handleEvent(event);
auto visitor = [&](auto &&arg) -> HandlerResult {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, Details::ValueOrRef<const LevelAddedActorEvent>>) {
if (!handleEvent(arg.value())) {
return HandlerResult::BypassListeners;
}
}
return handle_->handleEvent(event);
};
return std::visit(visitor, event.variant);
}

GameplayHandlerResult<CoordinatorResult> EndstoneLevelGameplayHandler::handleEvent(
MutableLevelGameplayEvent<CoordinatorResult> &event)
{
auto visitor = [&](auto &&arg) -> GameplayHandlerResult<CoordinatorResult> {
handleEvent(arg.value());
if (!handleEvent(arg.value())) {
return {HandlerResult::BypassListeners, CoordinatorResult::Cancel};
}
return handle_->handleEvent(event);
};
return std::visit(visitor, event.variant);
}

void EndstoneLevelGameplayHandler::handleEvent(LevelWeatherChangedEvent &event)
bool EndstoneLevelGameplayHandler::handleEvent(const LevelAddedActorEvent &event)
{
const StackResultStorageEntity stack_result(event.actor);
if (auto *actor = ::Actor::tryGetFromEntity(stack_result.getStackRef(), false); actor && !actor->isPlayer()) {
const auto &server = entt::locator<EndstoneServer>::value();
ActorSpawnEvent e{actor->getEndstoneActor()};
server.getPluginManager().callEvent(e);
if (e.isCancelled()) {
actor->despawn();
}
}
return true;
}

bool EndstoneLevelGameplayHandler::handleEvent(LevelWeatherChangedEvent &event)
{
const auto &server = entt::locator<EndstoneServer>::value();
auto &level = *server.getLevel();
Expand All @@ -63,6 +89,7 @@ void EndstoneLevelGameplayHandler::handleEvent(LevelWeatherChangedEvent &event)
event.will_be_lightning = event.is_lightning;
}
}
return true;
}

} // namespace endstone::core
3 changes: 2 additions & 1 deletion src/endstone/core/event/handlers/level_gameplay_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class EndstoneLevelGameplayHandler final : public LevelGameplayHandler {
GameplayHandlerResult<CoordinatorResult> handleEvent(MutableLevelGameplayEvent<CoordinatorResult> &event) override;

private:
void handleEvent(LevelWeatherChangedEvent &event);
bool handleEvent(const LevelAddedActorEvent &event);
bool handleEvent(LevelWeatherChangedEvent &event);

std::unique_ptr<LevelGameplayHandler> handle_;
};
Expand Down
Loading

0 comments on commit 4df58ee

Please sign in to comment.