Skip to content

Commit 473a355

Browse files
committed
fix: add server thread check for events
1 parent 4c05c1f commit 473a355

7 files changed

Lines changed: 735 additions & 550 deletions

File tree

src/legacy/api/EventAPI.cpp

Lines changed: 233 additions & 170 deletions
Large diffs are not rendered by default.

src/lse/api/Thread.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "lse/api/Thread.h"
2+
3+
#include "ll/api/service/Bedrock.h"
4+
#include "mc/server/ServerInstance.h"
5+
6+
namespace lse::api::thread {
7+
bool isServerThread() {
8+
auto instance = ll::service::getServerInstance();
9+
return instance && std::this_thread::get_id() == instance->mServerInstanceThread->get_id();
10+
}
11+
} // namespace lse::api::thread

src/lse/api/Thread.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
namespace lse::api::thread {
4+
bool isServerThread();
5+
inline bool checkClientIsServerThread() {
6+
#ifdef LL_PLAT_C
7+
return isServerThread();
8+
#else
9+
return true;
10+
#endif
11+
}
12+
} // namespace lse::api::thread

src/lse/events/BlockEvents.cpp

Lines changed: 129 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "ll/api/memory/Hook.h"
88
#include "ll/api/memory/Memory.h"
99
#include "ll/api/service/Bedrock.h"
10+
#include "lse/api/Thread.h"
1011
#include "lse/api/helper/BlockHelper.h"
1112
#include "mc/legacy/ActorUniqueID.h"
1213
#include "mc/scripting/modules/minecraft/events/ScriptBlockGlobalEventListener.h"
@@ -52,6 +53,8 @@
5253
#include "mc/world/level/material/Material.h"
5354

5455
namespace lse::events::block {
56+
using api::thread::checkClientIsServerThread;
57+
5558
LL_TYPE_INSTANCE_HOOK(
5659
ContainerChangeHook,
5760
HookPriority::Normal,
@@ -63,20 +66,22 @@ LL_TYPE_INSTANCE_HOOK(
6366
ItemStack const& newItem
6467
) {
6568
IF_LISTENED(EVENT_TYPES::onContainerChange) {
66-
if (*reinterpret_cast<void***>(this) != LevelContainerModel::$vftable())
67-
return origin(slotNumber, oldItem, newItem);
69+
if (checkClientIsServerThread()) {
70+
if (*reinterpret_cast<void***>(this) != LevelContainerModel::$vftable())
71+
return origin(slotNumber, oldItem, newItem);
6872

69-
// Player::hasOpenContainer()
70-
if (mPlayer.mContainerManager) {
71-
if (!CallEvent(
72-
EVENT_TYPES::onContainerChange,
73-
PlayerClass::newPlayer(&mPlayer),
74-
BlockClass::newBlock(mBlockPos, mPlayer.getDimensionId().id),
75-
Number::newNumber(slotNumber + this->_getContainerOffset()),
76-
ItemClass::newItem(&const_cast<ItemStack&>(oldItem)),
77-
ItemClass::newItem(&const_cast<ItemStack&>(newItem))
78-
)) {
79-
return;
73+
// Player::hasOpenContainer()
74+
if (mPlayer.mContainerManager) {
75+
if (!CallEvent(
76+
EVENT_TYPES::onContainerChange,
77+
PlayerClass::newPlayer(&mPlayer),
78+
BlockClass::newBlock(mBlockPos, mPlayer.getDimensionId().id),
79+
Number::newNumber(slotNumber + this->_getContainerOffset()),
80+
ItemClass::newItem(&const_cast<ItemStack&>(oldItem)),
81+
ItemClass::newItem(&const_cast<ItemStack&>(newItem))
82+
)) {
83+
return;
84+
}
8085
}
8186
}
8287
}
@@ -94,13 +99,15 @@ LL_TYPE_INSTANCE_HOOK(
9499
::SharedTypes::Legacy::EquipmentSlot slot
95100
) {
96101
IF_LISTENED(EVENT_TYPES::onChangeArmorStand) {
97-
if (!CallEvent(
98-
EVENT_TYPES::onChangeArmorStand,
99-
EntityClass::newEntity(this),
100-
PlayerClass::newPlayer(&player),
101-
Number::newNumber((int)slot)
102-
)) {
103-
return false;
102+
if (checkClientIsServerThread()) {
103+
if (!CallEvent(
104+
EVENT_TYPES::onChangeArmorStand,
105+
EntityClass::newEntity(this),
106+
PlayerClass::newPlayer(&player),
107+
Number::newNumber((int)slot)
108+
)) {
109+
return false;
110+
}
104111
}
105112
}
106113
IF_LISTENED_END(EVENT_TYPES::onChangeArmorStand);
@@ -118,12 +125,14 @@ LL_TYPE_INSTANCE_HOOK(
118125
Actor& entity
119126
) {
120127
IF_LISTENED(EVENT_TYPES::onStepOnPressurePlate) {
121-
if (!CallEvent(
122-
EVENT_TYPES::onStepOnPressurePlate,
123-
EntityClass::newEntity(&entity),
124-
BlockClass::newBlock(pos, region.getDimensionId())
125-
)) {
126-
return false;
128+
if (checkClientIsServerThread()) {
129+
if (!CallEvent(
130+
EVENT_TYPES::onStepOnPressurePlate,
131+
EntityClass::newEntity(&entity),
132+
BlockClass::newBlock(pos, region.getDimensionId())
133+
)) {
134+
return false;
135+
}
127136
}
128137
}
129138
IF_LISTENED_END(EVENT_TYPES::onStepOnPressurePlate);
@@ -142,12 +151,14 @@ LL_TYPE_INSTANCE_HOOK(
142151
float fallDistance
143152
) {
144153
IF_LISTENED(EVENT_TYPES::onFarmLandDecay) {
145-
if (!CallEvent(
146-
EVENT_TYPES::onFarmLandDecay,
147-
IntPos::newPos(pos, region.getDimensionId()),
148-
EntityClass::newEntity(actor)
149-
)) {
150-
return;
154+
if (checkClientIsServerThread()) {
155+
if (!CallEvent(
156+
EVENT_TYPES::onFarmLandDecay,
157+
IntPos::newPos(pos, region.getDimensionId()),
158+
EntityClass::newEntity(actor)
159+
)) {
160+
return;
161+
}
151162
}
152163
}
153164
IF_LISTENED_END(EVENT_TYPES::onFarmLandDecay);
@@ -166,21 +177,23 @@ LL_TYPE_INSTANCE_HOOK(
166177
uchar pistonMoveFacing
167178
) {
168179
IF_LISTENED(EVENT_TYPES::onPistonTryPush) {
169-
if (region.getBlock(curPos).isAir()) {
170-
return origin(region, curPos, curBranchFacing, pistonMoveFacing);
171-
}
172-
if (!CallEvent(
173-
EVENT_TYPES::onPistonTryPush,
174-
IntPos::newPos(this->mPosition, region.getDimensionId()),
175-
BlockClass::newBlock(curPos, region.getDimensionId())
176-
)) {
177-
return false;
180+
if (checkClientIsServerThread()) {
181+
if (region.getBlock(curPos).isAir()) {
182+
return origin(region, curPos, curBranchFacing, pistonMoveFacing);
183+
}
184+
if (!CallEvent(
185+
EVENT_TYPES::onPistonTryPush,
186+
IntPos::newPos(this->mPosition, region.getDimensionId()),
187+
BlockClass::newBlock(curPos, region.getDimensionId())
188+
)) {
189+
return false;
190+
}
178191
}
179192
}
180193
IF_LISTENED_END(EVENT_TYPES::onPistonTryPush);
181194
bool shouldPush = origin(region, curPos, curBranchFacing, pistonMoveFacing);
182195
IF_LISTENED(EVENT_TYPES::onPistonPush) {
183-
if (shouldPush) {
196+
if (checkClientIsServerThread() && shouldPush) {
184197
CallEvent( // Not cancellable
185198
EVENT_TYPES::onPistonPush,
186199
IntPos::newPos(this->mPosition, region.getDimensionId()),
@@ -194,10 +207,29 @@ LL_TYPE_INSTANCE_HOOK(
194207

195208
LL_TYPE_INSTANCE_HOOK(ExplodeHook, HookPriority::Normal, Explosion, &Explosion::explode, bool, ::IRandom& random) {
196209
IF_LISTENED(EVENT_TYPES::onEntityExplode) {
197-
if (mSourceID->rawID != ActorUniqueID::INVALID_ID().rawID) {
210+
if (checkClientIsServerThread()) {
211+
if (mSourceID->rawID != ActorUniqueID::INVALID_ID().rawID) {
212+
if (!CallEvent(
213+
EVENT_TYPES::onEntityExplode,
214+
EntityClass::newEntity(ll::service::getLevel()->fetchEntity(mSourceID, false)),
215+
FloatPos::newPos(mPos, mRegion.getDimensionId()),
216+
Number::newNumber(mRadius),
217+
Number::newNumber(mMaxResistance),
218+
Boolean::newBoolean(mBreaking),
219+
Boolean::newBoolean(mFire)
220+
)) {
221+
return false;
222+
}
223+
}
224+
}
225+
}
226+
IF_LISTENED_END(EVENT_TYPES::onEntityExplode);
227+
228+
IF_LISTENED(EVENT_TYPES::onBlockExplode) {
229+
if (checkClientIsServerThread()) {
198230
if (!CallEvent(
199-
EVENT_TYPES::onEntityExplode,
200-
EntityClass::newEntity(ll::service::getLevel()->fetchEntity(mSourceID, false)),
231+
EVENT_TYPES::onBlockExplode,
232+
BlockClass::newBlock(*mPos, mRegion.getDimensionId()),
201233
FloatPos::newPos(mPos, mRegion.getDimensionId()),
202234
Number::newNumber(mRadius),
203235
Number::newNumber(mMaxResistance),
@@ -208,21 +240,6 @@ LL_TYPE_INSTANCE_HOOK(ExplodeHook, HookPriority::Normal, Explosion, &Explosion::
208240
}
209241
}
210242
}
211-
IF_LISTENED_END(EVENT_TYPES::onEntityExplode);
212-
213-
IF_LISTENED(EVENT_TYPES::onBlockExplode) {
214-
if (!CallEvent(
215-
EVENT_TYPES::onBlockExplode,
216-
BlockClass::newBlock(*mPos, mRegion.getDimensionId()),
217-
FloatPos::newPos(mPos, mRegion.getDimensionId()),
218-
Number::newNumber(mRadius),
219-
Number::newNumber(mMaxResistance),
220-
Boolean::newBoolean(mBreaking),
221-
Boolean::newBoolean(mFire)
222-
)) {
223-
return false;
224-
}
225-
}
226243
IF_LISTENED_END(EVENT_TYPES::onBlockExplode);
227244
return origin(random);
228245
}
@@ -239,12 +256,14 @@ LL_TYPE_STATIC_HOOK(
239256
Level& level
240257
) {
241258
IF_LISTENED(EVENT_TYPES::onRespawnAnchorExplode) {
242-
if (!CallEvent(
243-
EVENT_TYPES::onRespawnAnchorExplode,
244-
IntPos::newPos(pos, region.getDimensionId()),
245-
PlayerClass::newPlayer(&player)
246-
)) {
247-
return;
259+
if (checkClientIsServerThread()) {
260+
if (!CallEvent(
261+
EVENT_TYPES::onRespawnAnchorExplode,
262+
IntPos::newPos(pos, region.getDimensionId()),
263+
PlayerClass::newPlayer(&player)
264+
)) {
265+
return;
266+
}
248267
}
249268
}
250269
IF_LISTENED_END(EVENT_TYPES::onRespawnAnchorExplode);
@@ -263,14 +282,16 @@ LL_TYPE_INSTANCE_HOOK(
263282
Actor* source
264283
) {
265284
IF_LISTENED(EVENT_TYPES::onBlockExploded) {
266-
if (destroyedBlock.isAir()) {
267-
return origin(dimension, blockPos, destroyedBlock, source);
285+
if (checkClientIsServerThread()) {
286+
if (destroyedBlock.isAir()) {
287+
return origin(dimension, blockPos, destroyedBlock, source);
288+
}
289+
CallEvent(
290+
EVENT_TYPES::onBlockExploded,
291+
BlockClass::newBlock(destroyedBlock, blockPos, dimension.getDimensionId()),
292+
EntityClass::newEntity(source)
293+
);
268294
}
269-
CallEvent(
270-
EVENT_TYPES::onBlockExploded,
271-
BlockClass::newBlock(destroyedBlock, blockPos, dimension.getDimensionId()),
272-
EntityClass::newEntity(source)
273-
);
274295
}
275296
IF_LISTENED_END(EVENT_TYPES::onBlockExploded);
276297
return origin(dimension, blockPos, destroyedBlock, source);
@@ -302,8 +323,10 @@ inline bool RedstoneUpdateEvent(BlockSource& region, BlockPos const& pos, int& s
302323
bool isFirstTime \
303324
) { \
304325
IF_LISTENED(EVENT_TYPES::onRedStoneUpdate) { \
305-
if (!RedstoneUpdateEvent(region, pos, strength, isFirstTime)) { \
306-
return; \
326+
if (checkClientIsServerThread()) { \
327+
if (!RedstoneUpdateEvent(region, pos, strength, isFirstTime)) { \
328+
return; \
329+
} \
307330
} \
308331
} \
309332
IF_LISTENED_END(EVENT_TYPES::onRedStoneUpdate); \
@@ -373,9 +396,7 @@ LL_TYPE_INSTANCE_HOOK(
373396
uchar flowFromDirection
374397
) {
375398
IF_LISTENED(EVENT_TYPES::onLiquidFlow) {
376-
auto ins = ll::service::getServerInstance();
377-
if (ins && std::this_thread::get_id() == ins->mServerInstanceThread->get_id()
378-
&& liquidBlockCanSpreadTo(*this, region, pos, flowFromPos, flowFromDirection)) {
399+
if (checkClientIsServerThread() && liquidBlockCanSpreadTo(*this, region, pos, flowFromPos, flowFromDirection)) {
379400
if (!CallEvent(
380401
EVENT_TYPES::onLiquidFlow,
381402
region.isInstaticking(pos) ? Local<Value>() : BlockClass::newBlock(pos, region.getDimensionId()),
@@ -400,23 +421,25 @@ LL_TYPE_INSTANCE_HOOK(
400421
bool& markForSaving
401422
) {
402423
IF_LISTENED(EVENT_TYPES::onCmdBlockExecute) {
403-
if (commandOrigin.getOriginType() == CommandOriginType::MinecartCommandBlock) {
404-
if (!CallEvent(
405-
EVENT_TYPES::onCmdBlockExecute,
406-
String::newString(this->mCommand),
407-
FloatPos::newPos(commandOrigin.getEntity()->getPosition(), region.getDimensionId()),
408-
Boolean::newBoolean(true)
409-
)) {
410-
return false;
411-
}
412-
} else {
413-
if (!CallEvent(
414-
EVENT_TYPES::onCmdBlockExecute,
415-
String::newString(this->mCommand),
416-
FloatPos::newPos(commandOrigin.getBlockPosition(), region.getDimensionId()),
417-
Boolean::newBoolean(false)
418-
)) {
419-
return false;
424+
if (checkClientIsServerThread()) {
425+
if (commandOrigin.getOriginType() == CommandOriginType::MinecartCommandBlock) {
426+
if (!CallEvent(
427+
EVENT_TYPES::onCmdBlockExecute,
428+
String::newString(this->mCommand),
429+
FloatPos::newPos(commandOrigin.getEntity()->getPosition(), region.getDimensionId()),
430+
Boolean::newBoolean(true)
431+
)) {
432+
return false;
433+
}
434+
} else {
435+
if (!CallEvent(
436+
EVENT_TYPES::onCmdBlockExecute,
437+
String::newString(this->mCommand),
438+
FloatPos::newPos(commandOrigin.getBlockPosition(), region.getDimensionId()),
439+
Boolean::newBoolean(false)
440+
)) {
441+
return false;
442+
}
420443
}
421444
}
422445
}
@@ -438,8 +461,10 @@ LL_TYPE_INSTANCE_HOOK(
438461
Container& toContainer,
439462
Vec3 const& pos
440463
) {
441-
hopperStatus = HopperStatus::PullIn;
442-
hopperPos = pos;
464+
if (checkClientIsServerThread()) {
465+
hopperStatus = HopperStatus::PullIn;
466+
hopperPos = pos;
467+
}
443468
return origin(region, toContainer, pos);
444469
}
445470

@@ -454,8 +479,10 @@ LL_TYPE_INSTANCE_HOOK(
454479
Vec3 const& position,
455480
int attachedFace
456481
) {
457-
hopperStatus = HopperStatus::PullOut;
458-
hopperPos = position;
482+
if (checkClientIsServerThread()) {
483+
hopperStatus = HopperStatus::PullOut;
484+
hopperPos = position;
485+
}
459486
return origin(region, fromContainer, position, attachedFace);
460487
}
461488

@@ -473,7 +500,7 @@ LL_TYPE_INSTANCE_HOOK(
473500
int itemCount
474501
) {
475502
IF_LISTENED(EVENT_TYPES::onHopperSearchItem) {
476-
if (hopperStatus == HopperStatus::PullIn) {
503+
if (checkClientIsServerThread() && hopperStatus == HopperStatus::PullIn) {
477504
if (!CallEvent(
478505
EVENT_TYPES::onHopperSearchItem,
479506
FloatPos::newPos(hopperPos, region.getDimensionId()),
@@ -486,7 +513,7 @@ LL_TYPE_INSTANCE_HOOK(
486513
}
487514
IF_LISTENED_END(EVENT_TYPES::onHopperSearchItem);
488515
IF_LISTENED(EVENT_TYPES::onHopperPushOut) {
489-
if (hopperStatus == HopperStatus::PullOut) {
516+
if (checkClientIsServerThread() && hopperStatus == HopperStatus::PullOut) {
490517
if (!CallEvent(
491518
EVENT_TYPES::onHopperPushOut,
492519
FloatPos::newPos(hopperPos, region.getDimensionId()),
@@ -543,4 +570,4 @@ void HopperEvent(bool pullIn) {
543570
hopper::HopperPushOutHook::hook();
544571
}
545572
}
546-
} // namespace lse::events::block
573+
} // namespace lse::events::block

0 commit comments

Comments
 (0)