#include
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #include // #include #include #include #include #include #include #include #include #include #include #include // #include #include #include #include #include #include #include #include #include #include #include #include #include // #include #include #include #include #include #include #include // #include #include #include static_assert(offsetof(InventoryAction, source) == 0x0); static_assert(offsetof(InventoryAction, slot) == 0x0c); static_assert(offsetof(InventorySource, type) == 0x0); static_assert(offsetof(InventorySource, container) == 0x04); static_assert(offsetof(InventorySource, flags) == 0x08); static_assert(offsetof(ComplexInventoryTransaction, type) == 0x08); static_assert(offsetof(ComplexInventoryTransaction, data) == 0x10); static_assert(offsetof(InventoryTransaction, actions) == 0x0); static_assert(offsetof(InventoryTransaction, items) == 0x40); using namespace Event; using std::vector; extern Logger logger; /////////////////////////////// Event Data /////////////////////////////// int globalListenerId = 0; template struct ListenerData { std::string pluginName; int listenerId; bool isRef; std::function callback; std::function callbackRef; }; template std::list> listeners; /////////////////////////////// Listener Manager /////////////////////////////// template int EventManager::addEventListener(std::string name, std::function callback) { int newId = ++globalListenerId; listeners.push_back({name, newId, false, callback, nullptr}); return newId; } template int EventManager::addEventListenerRef(std::string name, std::function callback) { int newId = ++globalListenerId; listeners.push_back({name, newId, true, nullptr, callback}); return newId; } template bool EventManager::removeEventListener(int id) { for (auto i = listeners.begin(); i != listeners.end(); ++i) if (i->listenerId == id) { listeners.erase(i); return true; } return false; } template bool EventManager::hasListener() { return !listeners.empty(); } /////////////////////////////// Event Calling /////////////////////////////// inline void OutputError(std::string errorMsg, int errorCode, std::string errorWhat, std::string eventName, std::string pluginName) { logger.error(errorMsg); logger.error("Error: Code [{}] {}", errorCode, errorWhat); logger.error("In Event ({})", eventName); if (!pluginName.empty()) { auto plugin = LL::getPlugin(pluginName); if (plugin) { logger.error("In Plugin <{} {}>", plugin->name, plugin->version.toString()); } else { logger.error("In Plugin <{}>", pluginName); } } } template bool EventManager::call(EVENT& ev) { bool passToBDS = true; for (auto i = listeners.begin(); i != listeners.end(); ++i) { try { bool res = i->isRef ? i->callbackRef(ev) : i->callback(ev); if (!res) passToBDS = false; } catch (const seh_exception& e) { OutputError("Uncaught SEH Exception Detected!", e.code(), TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->pluginName); } catch (const std::exception& e) { OutputError("Uncaught C++ Exception Detected!", errno, TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->pluginName); } catch (...) { OutputError("Uncaught Exception Detected!", -1, "", typeid(EVENT).name(), i->pluginName); } } ///////////////////////////////////// For compatibility DO NOT UPDATE ///////////////////////////////////// auto iNoConst = ev.listenersNoConst.begin(); try { for (; iNoConst != ev.listenersNoConst.end(); ++iNoConst) if (!iNoConst->second(ev)) passToBDS = false; } catch (const seh_exception& e) { OutputError("Uncaught SEH Exception Detected!", e.code(), TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), iNoConst->first); } catch (const std::exception& e) { OutputError("Uncaught Exception Detected! ", -1, TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), iNoConst->first); } catch (...) { OutputError("Uncaught Exception Detected!", -1, "", typeid(EVENT).name(), iNoConst->first); } ///////////////////////////////////// For compatibility DO NOT UPDATE ///////////////////////////////////// auto i = ev.listeners.begin(); try { for (; i != ev.listeners.end(); ++i) if (!i->second(ev)) passToBDS = false; } catch (const seh_exception& e) { OutputError("Uncaught SEH Exception Detected!", e.code(), TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->first); } catch (const std::exception& e) { OutputError("Uncaught Exception Detected! ", -1, TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->first); } catch (...) { OutputError("Uncaught Exception Detected!", -1, "", typeid(EVENT).name(), i->first); } ///////////////////////////////////// For compatibility DO NOT UPDATE ///////////////////////////////////// return passToBDS; } template bool EventManager::callToPlugin(std::string pluginName, EVENT& ev) { bool passToBDS = true; for (auto i = listeners.begin(); i != listeners.end(); ++i) { if (i->pluginName != pluginName) continue; try { bool res = i->isRef ? i->callbackRef(ev) : i->callback(ev); if (!res) passToBDS = false; } catch (const seh_exception& e) { OutputError("Uncaught SEH Exception Detected!", e.code(), TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->pluginName); } catch (const std::exception& e) { OutputError("Uncaught C++ Exception Detected!", errno, TextEncoding::toUTF8(e.what()), typeid(EVENT).name(), i->pluginName); } catch (...) { OutputError("Uncaught Exception Detected!", -1, "", typeid(EVENT).name(), i->pluginName); } } return passToBDS; } /////////////////////////////// Event Declare /////////////////////////////// #define DECLARE_EVENT_DATA(EVENT) \ template class EventManager; \ /*********************** For Compatibility ***********************/ \ std::list>> EventTemplate::listeners; \ std::list>> EventTemplate::listenersNoConst; DECLARE_EVENT_DATA(PlayerPreJoinEvent); DECLARE_EVENT_DATA(PlayerJoinEvent); DECLARE_EVENT_DATA(PlayerLeftEvent); DECLARE_EVENT_DATA(PlayerRespawnEvent); DECLARE_EVENT_DATA(PlayerChatEvent); DECLARE_EVENT_DATA(PlayerUseItemEvent); DECLARE_EVENT_DATA(PlayerUseItemOnEvent); DECLARE_EVENT_DATA(PlayerChangeDimEvent); DECLARE_EVENT_DATA(PlayerJumpEvent); DECLARE_EVENT_DATA(PlayerSneakEvent); DECLARE_EVENT_DATA(PlayerAttackEvent); DECLARE_EVENT_DATA(PlayerAttackBlockEvent); DECLARE_EVENT_DATA(PlayerDieEvent); DECLARE_EVENT_DATA(PlayerPickupItemEvent); DECLARE_EVENT_DATA(PlayerDropItemEvent); DECLARE_EVENT_DATA(PlayerEatEvent); DECLARE_EVENT_DATA(PlayerConsumeTotemEvent); DECLARE_EVENT_DATA(PlayerCmdEvent); DECLARE_EVENT_DATA(PlayerDestroyBlockEvent); DECLARE_EVENT_DATA(PlayerPlaceBlockEvent); DECLARE_EVENT_DATA(BlockPlacedByPlayerEvent); DECLARE_EVENT_DATA(PlayerEffectChangedEvent); DECLARE_EVENT_DATA(PlayerStartDestroyBlockEvent); DECLARE_EVENT_DATA(PlayerOpenContainerEvent); DECLARE_EVENT_DATA(PlayerCloseContainerEvent); DECLARE_EVENT_DATA(PlayerInventoryChangeEvent); DECLARE_EVENT_DATA(PlayerMoveEvent); DECLARE_EVENT_DATA(PlayerSprintEvent); DECLARE_EVENT_DATA(PlayerSetArmorEvent); DECLARE_EVENT_DATA(PlayerUseRespawnAnchorEvent); DECLARE_EVENT_DATA(PlayerOpenContainerScreenEvent); DECLARE_EVENT_DATA(PlayerUseFrameBlockEvent); DECLARE_EVENT_DATA(PlayerExperienceAddEvent); DECLARE_EVENT_DATA(PlayerInteractEntityEvent); DECLARE_EVENT_DATA(MobHurtEvent); DECLARE_EVENT_DATA(MobDieEvent); DECLARE_EVENT_DATA(EntityExplodeEvent); DECLARE_EVENT_DATA(ProjectileHitEntityEvent); DECLARE_EVENT_DATA(WitherBossDestroyEvent); DECLARE_EVENT_DATA(EntityRideEvent); DECLARE_EVENT_DATA(EntityStepOnPressurePlateEvent); DECLARE_EVENT_DATA(NpcCmdEvent); DECLARE_EVENT_DATA(ProjectileSpawnEvent); DECLARE_EVENT_DATA(ProjectileCreatedEvent); DECLARE_EVENT_DATA(EntityTransformEvent); DECLARE_EVENT_DATA(BlockInteractedEvent); DECLARE_EVENT_DATA(ArmorStandChangeEvent); DECLARE_EVENT_DATA(BlockExplodeEvent); DECLARE_EVENT_DATA(ContainerChangeEvent); DECLARE_EVENT_DATA(PistonPushEvent); DECLARE_EVENT_DATA(PistonTryPushEvent); DECLARE_EVENT_DATA(RedStoneUpdateEvent); DECLARE_EVENT_DATA(BlockExplodedEvent); DECLARE_EVENT_DATA(LiquidSpreadEvent); DECLARE_EVENT_DATA(ProjectileHitBlockEvent); DECLARE_EVENT_DATA(HopperSearchItemEvent); DECLARE_EVENT_DATA(HopperPushOutEvent); DECLARE_EVENT_DATA(BlockChangedEvent); DECLARE_EVENT_DATA(FarmLandDecayEvent); DECLARE_EVENT_DATA(FireSpreadEvent); DECLARE_EVENT_DATA(CmdBlockExecuteEvent); DECLARE_EVENT_DATA(ConsoleCmdEvent); DECLARE_EVENT_DATA(PlayerScoreChangedEvent); DECLARE_EVENT_DATA(ConsoleOutputEvent); DECLARE_EVENT_DATA(PostInitEvent); DECLARE_EVENT_DATA(ServerStartedEvent); DECLARE_EVENT_DATA(ServerStoppedEvent); DECLARE_EVENT_DATA(RegCmdEvent); DECLARE_EVENT_DATA(PlayerBedEnterEvent); DECLARE_EVENT_DATA(ScriptPluginManagerEvent); DECLARE_EVENT_DATA(MobSpawnEvent); DECLARE_EVENT_DATA(FormResponsePacketEvent); DECLARE_EVENT_DATA(ResourcePackInitEvent); #define IF_LISTENED(EVENT) \ if (EVENT::hasListener()) { \ try #define IF_LISTENED_END(EVENT) \ catch (...) { \ logger.error("Event Callback Failed!"); \ logger.error("Uncaught Exception Detected!"); \ logger.error("In Event: " #EVENT ""); \ PrintCurrentStackTraceback(); \ } \ } /////////////////////////////// Events /////////////////////////////// /////////////////// PreJoin /////////////////// TClasslessInstanceHook(void, "?sendLoginMessageLocal@ServerNetworkHandler@@QEAAXAEBVNetworkIdentifier@@" "AEBVConnectionRequest@@AEAVServerPlayer@@@Z", NetworkIdentifier* Ni, ConnectionRequest* a3, ServerPlayer* sp) { IF_LISTENED(PlayerPreJoinEvent) { PlayerPreJoinEvent ev{}; ev.mPlayer = sp; ev.mIP = Ni->getIP(); ev.mXUID = sp->getXuid(); if (!ev.call()) return; } IF_LISTENED_END(PlayerPreJoinEvent) return original(this, Ni, a3, sp); } /////////////////// PlayerJoin /////////////////// //没有这个符号 TInstanceHook(bool, "?onReady_ClientGeneration@ServerNetworkHandler@@QEAAXAEAVPlayer@@AEBVNetworkIdentifier@@@Z", ServerNetworkHandler,Player* player,NetworkIdentifier *net) { IF_LISTENED(PlayerJoinEvent) { PlayerJoinEvent ev{}; ev.mPlayer = player; if (!ev.call()) return false; } IF_LISTENED_END(PlayerJoinEvent) return original(this,player,net); } /////////////////// PlayerLeft /////////////////// THook(void, "?_onPlayerLeft@ServerNetworkHandler@@AEAAXPEAVServerPlayer@@_N@Z", ServerNetworkHandler *_this,ServerPlayer* sp,char a3) { IF_LISTENED(PlayerLeftEvent) { PlayerLeftEvent ev{}; ev.mPlayer = sp; ev.mXUID = sp->getXuid(); ev.call(); } IF_LISTENED_END(PlayerLeftEvent) return original(_this,sp,a3); } /////////////////// PlayerRespawn /////////////////// TClasslessInstanceHook(void, "?handle@?$PacketHandlerDispatcherInstance@VPlayerActionPacket@@$0A@@@UEBAXAEBVNetworkIdentifier@@AEAVNetEventCallback@@AEAV?$shared_ptr@VPacket@@@std@@@Z", NetworkIdentifier* id, ServerNetworkHandler* handler, void* pPacket) { PlayerActionPacket* packet = *(PlayerActionPacket**)pPacket; if (packet->actionType == PlayerActionType::Respawn) { IF_LISTENED(PlayerRespawnEvent) { PlayerRespawnEvent ev{}; ev.mPlayer = packet->getPlayerFromPacket(handler, id); if (!ev.mPlayer) return; ev.call(); } IF_LISTENED_END(PlayerRespawnEvent) } return original(this, id, handler, pPacket); } /////////////////// PlayerChat /////////////////// TInstanceHook(void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdentifier@@AEBVTextPacket@@@Z", ServerNetworkHandler, NetworkIdentifier* id, void* text) { IF_LISTENED(PlayerChatEvent) { Event::PlayerChatEvent ev{}; ev.mPlayer = this->getServerPlayer(*id); if (!ev.mPlayer) return; ev.mMessage = std::string(*(std::string*)((uintptr_t)text + 80)); if (!ev.call()) return; *(std::string*)((uintptr_t)text + 80) = ev.mMessage; } IF_LISTENED_END(PlayerChatEvent); return original(this, id, text); } /////////////////// PlayerChangeDim /////////////////// class ChangeDimensionRequest { public: int mState; AutomaticID mFromDimensionId; AutomaticID mToDimensionId; Vec3 mPosition; bool mUsePortal; bool mRespawn; std::unique_ptr mAgentTag; }; //没有这个符号 // TClasslessInstanceHook(bool, "?requestPlayerChangeDimension@Level@@UEAAXAEAVPlayer@@V?$unique_ptr@VChangeDimensionRequest@@U?$default_delete@VChangeDimensionRequest@@@std@@@std@@@Z", // Player* sp, std::unique_ptr request) { // if (request->mToDimensionId == sp->getDimensionId()) // return original(this, sp, std::move(request)); // IF_LISTENED(PlayerChangeDimEvent) { // PlayerChangeDimEvent ev{}; // ev.mPlayer = sp; // ev.mToDimensionId = request->mToDimensionId; // if (!ev.call()) // return false; // } // IF_LISTENED_END(PlayerChangeDimEvent) // return original(this, sp, std::move(request)); // } int num = 0; /////////////////// PlayerJump /////////////////// TInstanceHook(void, "?jumpFromGround@Player@@UEAAXXZ", Player) { IF_LISTENED(PlayerJumpEvent) { PlayerJumpEvent ev{}; ev.mPlayer = this; ev.call(); } IF_LISTENED_END(PlayerJumpEvent) return original(this); } /////////////////// PlayerSneak /////////////////// //没有这个符号 // TClasslessInstanceHook(void, "?sendActorSneakChanged@ActorEventCoordinator@@QEAAXAEAVActor@@_N@Z", // Actor* ac, bool isSneaking) { // IF_LISTENED(PlayerSneakEvent) { // PlayerSneakEvent ev{}; // ev.mPlayer = (Player*)ac; // ev.mIsSneaking = isSneaking; // ev.call(); // isSneaking = ev.mIsSneaking; // } // IF_LISTENED_END(PlayerSneakEvent) // return original(this, ac, isSneaking); // } /////////////////// PlayerAttackEntity /////////////////// //没有这个符号 // TInstanceHook(bool, "?attack@Player@@UEAA_NAEAVActor@@AEBW4ActorDamageCause@@@Z", // Player, Actor* ac, int* damageCause) { // IF_LISTENED(PlayerAttackEvent) { // PlayerAttackEvent ev{}; // ev.mPlayer = this; // ev.mTarget = ac; // ev.mAttackDamage = *damageCause; // if (!ev.call()) // return false; // ac = ev.mTarget; // *damageCause = ev.mAttackDamage; // } // IF_LISTENED_END(PlayerAttackEvent) // return original(this, ac, damageCause); // } /////////////////// PlayerAttackBlock /////////////////// //没有这个符号 // TInstanceHook(bool, "?attack@Block@@QEBA_NPEAVPlayer@@AEBVBlockPos@@@Z", // Block, Player* pl, BlockPos* bp) { // IF_LISTENED(PlayerAttackBlockEvent) { // PlayerAttackBlockEvent ev{}; // ev.mPlayer = pl; // ev.mItemStack = pl->getHandSlot(); // ev.mBlockInstance = BlockInstance::createBlockInstance(this, *bp, pl->getDimensionId()); // if (!ev.call()) // return false; // } // IF_LISTENED_END(PlayerAttackBlockEvent) // return original(this, pl, bp); // } /////////////////// PlayerTakeItem /////////////////// TInstanceHook(bool, "?take@Player@@QEAA_NAEAVActor@@HH@Z", Player, Actor* actor, int a2, int a3) { IF_LISTENED(PlayerPickupItemEvent) { ItemStack* it = nullptr; if (actor->isItemActor()) it = ((ItemActor*)actor)->getItemStack(); PlayerPickupItemEvent ev{}; ev.mPlayer = this; ev.mItemEntity = actor; ev.mItemStack = it; if (!ev.call()) return false; } IF_LISTENED_END(PlayerPickupItemEvent) return original(this, actor, a2, a3); } bool isQDrop; bool isDieDrop; /////////////////// PlayerDropItem /////////////////// TInstanceHook(bool, "?drop@Player@@UEAA_NAEBVItemStack@@_N@Z", Player, ItemStack* it, bool a3) { if (isQDrop) return original(this, it, a3); if (isDieDrop) return original(this, it, a3); IF_LISTENED(PlayerDropItemEvent) { PlayerDropItemEvent ev{}; ev.mPlayer = this; ev.mItemStack = it; if (!ev.call()) return false; } IF_LISTENED_END(PlayerDropItemEvent) return original(this, it, a3); } /////////////////// PlayerConsumeTotem /////////////////// TInstanceHook(void, "?consumeTotem@Player@@UEAA_NXZ", Player) { IF_LISTENED(PlayerConsumeTotemEvent) { PlayerConsumeTotemEvent ev{}; ev.mPlayer = this; if (!ev.call()) return; } IF_LISTENED_END(PlayerConsumeTotemEvent) return original(this); } /////////////////// PlayerEffectChanged /////////////////// // add TInstanceHook(void, "?onEffectAdded@ServerPlayer@@MEAAXAEAVMobEffectInstance@@@Z", Player, MobEffectInstance* effect) { IF_LISTENED(PlayerEffectChangedEvent) { PlayerEffectChangedEvent ev{}; ev.mPlayer = this; ev.mEventType = PlayerEffectChangedEvent::EventType::Add; ev.mEffect = effect; ev.call(); } IF_LISTENED_END(PlayerEffectChangedEvent) return original(this, effect); } // remove TInstanceHook(void, "?onEffectRemoved@ServerPlayer@@MEAAXAEAVMobEffectInstance@@@Z", Player, MobEffectInstance* effect) { IF_LISTENED(PlayerEffectChangedEvent) { PlayerEffectChangedEvent ev{}; ev.mPlayer = this; ev.mEventType = PlayerEffectChangedEvent::EventType::Remove; ev.mEffect = effect; ev.call(); } IF_LISTENED_END(PlayerEffectChangedEvent) return original(this, effect); } // update // 没有这个符号 // TInstanceHook(void, "?onEffectUpdated@ServerPlayer@@MEAAXAEAVMobEffectInstance@@@Z", Player, MobEffectInstance* effect) { // IF_LISTENED(PlayerEffectChangedEvent) { // PlayerEffectChangedEvent ev{}; // ev.mPlayer = this; // ev.mEventType = PlayerEffectChangedEvent::EventType::Update; // ev.mEffect = effect; // ev.call(); // } // IF_LISTENED_END(PlayerEffectChangedEvent) // return original(this, effect); // } /////////////////// PlayerStartDestroyBlock /////////////////// // 没有这个符号 // TClasslessInstanceHook(void, "?sendBlockDestructionStarted@BlockEventCoordinator@@QEAAXAEAVPlayer@@AEBVBlockPos@@@Z", // Player* pl, BlockPos* bp) { // IF_LISTENED(PlayerStartDestroyBlockEvent) { // PlayerStartDestroyBlockEvent ev{}; // ev.mPlayer = pl; // ev.mBlockInstance = Level::getBlockInstance(bp, Level::getBlockSource(pl)); // ev.call(); // } // IF_LISTENED_END(PlayerStartDestroyBlockEvent) // return original(this, pl, bp); // } /////////////////// PlayerPlaceBlock /////////////////// #include // 没有这个符号 // TInstanceHook(char, "?checkBlockPermissions@BlockSource@@QEAA_NAEAVActor@@AEBVBlockPos@@EAEBVItemStackBase@@_N@Z", // BlockSource, Actor* ac, BlockPos* bp, unsigned __int8 facing, ItemStackBase* item, bool a6) { // if (ac->isPlayer()) { // IF_LISTENED(PlayerPlaceBlockEvent) { // auto pl = (Player*)ac; // PlayerPlaceBlockEvent ev{}; // ev.mPlayer = pl; // ev.mBlockInstance = this->getBlockInstance(*bp); // if (!ev.call()) { // this pointer is not used. // ((ItemUseInventoryTransaction*)nullptr)->resendBlocksAroundArea(*pl, *bp, facing); // return false; // } // } // IF_LISTENED_END(PlayerPlaceBlockEvent) // } // return original(this, ac, bp, facing, item, a6); // } /////////////////// BlockPlacedByPlayerEvent /////////////////// TClasslessInstanceHook(void, "?sendBlockPlacedByPlayer@BlockEventCoordinator@@QEAAXAEAVPlayer@@AEBVBlock@@AEBVBlockPos@@_N@Z", Player* pl, Block* bl, BlockPos* bp, bool a5) { IF_LISTENED(BlockPlacedByPlayerEvent) { BlockPlacedByPlayerEvent ev{}; ev.mPlayer = pl; ev.mBlockInstance = BlockInstance::createBlockInstance(bl, *bp, pl->getDimensionId()); ev.call(); } IF_LISTENED_END(BlockPlacedByPlayerEvent) original(this, pl, bl, bp, a5); } /* #include #include TInstanceHook(bool, "?_useOn@BlockItem@@MEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", Item, ItemStack* a2, Actor* ac, BlockPos* a4, unsigned __int8 a5, class Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { Block* RenderBlock; auto RegionConst = ac->getBlockSource(); if (!a2->getCount()) { return 0; } auto& bls = this->getLegacyBlock(); if (bls && bls.get() != 0i64) RenderBlock = const_cast(&bls.get()->getRenderBlock()); else RenderBlock = const_cast(BedrockBlocks::mAir); if (RegionConst->mayPlace(*RenderBlock, *a4, a5, (class Actor*)ac, 0)) { if (Player::isValid((Player*)ac)) { PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)ac; ev.mBlockInstance = BlockInstance::createBlockInstance(Block::create(RenderBlock->getTypeName(), a2->getAux()), *a4, (int)RegionConst->getDimensionId()); if (!ev.call()) return false; } } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, ac, a4, a5,a6); } TClasslessInstanceHook(bool, "?_useOn@BambooBlockItem@@UEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { auto& bs = a3->getRegion(); auto onBlockPos = a4.relative(a5, -1); auto onBlock = &bs.getBlock(onBlockPos).getDefaultState(); auto underBlock = &bs.getBlock(a4.relative(0, 1)).getDefaultState(); if (onBlock == VanillaBlocks::mBambooBlock || onBlock == VanillaBlocks::mBambooSapling || underBlock == VanillaBlocks::mBambooBlock || underBlock == VanillaBlocks::mBambooSapling) return original(this, a2, a3, a4, a5, a6); // listen in BlockSource::mayPlace PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(VanillaBlocks::mBambooSapling), a4, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } //THook(bool, "?_useOn@BannerItem@@UEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EMMM@Z", __int64 a1, ItemStackBase* a2, Actor* a3, const struct BlockPos* a4, unsigned __int8 a5, int a6, int a7, int a8) //{ // IF_LISTENED(PlayerPlaceBlockEvent) // { // if (Player::isValid((Player*)a3)) // { // PlayerPlaceBlockEvent ev{}; // ev.mPlayer = (Player*)a3; // ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(a2->getBlock()), *a4, (int)a3->getDimensionId()); // if (!ev.call()) // return false; // } // } // IF_LISTENED_END(PlayerPlaceBlockEvent) // return original(a1, a2, a3, a4, a5, a6); //} TClasslessInstanceHook(bool, "?_tryUseOn@BedItem@@AEBA_NAEAVItemStackBase@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", ItemStackBase *a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(VanillaBlocks::mBed), a4, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } TClasslessInstanceHook(bool, "?_useOn@DyePowderItem@@EEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; auto& PlacementBlock = VanillaBlocks::mCocoa->getPlacementBlock(*a3, a4, a5, a4.toVec3(), 0); ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(&PlacementBlock), a4, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } TClasslessInstanceHook(bool, "?_useOn@DoorItem@@EEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; const Block* v11 = nullptr; switch (dAccess(this)) { case 0: v11 = VanillaBlocks::mWoodenDoor; break; case 1: v11 = VanillaBlocks::mWoodenDoorSpruce; break; case 2: v11 = VanillaBlocks::mWoodenDoorBirch; break; case 3: v11 = VanillaBlocks::mWoodenDoorJungle; break; case 4: v11 = VanillaBlocks::mWoodenDoorAcacia; break; case 5: v11 = VanillaBlocks::mWoodenDoorDarkOak; break; case 6: v11 = VanillaBlocks::mIronDoor; break; case 7: v11 = VanillaBlocks::mCrimsonDoor; break; case 8: v11 = VanillaBlocks::mWarpedDoor; break; case 9: v11 = VanillaBlocks::mMangroveDoor; break; } if (!v11) return false; ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(v11), {a4.x, a4.y + 1, a4.z}, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } TClasslessInstanceHook(bool, "?_useOn@RedStoneDustItem@@EEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EAEBVVec3@@@Z", ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; ev.mBlockInstance = BlockInstance::createBlockInstance(const_cast(VanillaBlocks::mRedStoneDust), a4, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } //THook(bool, "?_useOn@SignItem@@UEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EMMM@Z", // class SignItem* a1, ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) //{ // IF_LISTENED(PlayerPlaceBlockEvent) // { // if (Player::isValid((Player*)a3)) // { // auto& blockMap = dAccess>>(a1, 552); // SignItem::SignItem // auto& signType = dAccess(a1, 568); // SignItem::SignItem // auto block = a5 == 1 ? blockMap[signType].first : blockMap[signType].second; // PlayerPlaceBlockEvent ev{}; // ev.mPlayer = (Player*)a3; // ev.mBlockInstance = BlockInstance::createBlockInstance(block, a4, (int)a3->getDimensionId()); // if (!ev.call()) // return false; // } // } // IF_LISTENED_END(PlayerPlaceBlockEvent) // return original(a1, a2, a3, a4, a5, a6); //} TInstanceHook(bool, "?_calculatePlacePos@SignItem@@EEBA_NAEAVItemStackBase@@AEAVActor@@AEAEAEAVBlockPos@@@Z", SignItem, ItemStackBase* a2, Actor* a3, unsigned char& a4, class BlockPos* a5) { auto rtn = original(this, a2, a3, a4, a5); if (!rtn) return rtn; IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { // map> blockMap auto& blockMap = dAccess>>(this, 552); // SignItem::SignItem auto& signType = dAccess(this, 568); // SignItem::SignItem auto block = a4 == 1 ? blockMap[signType].first : blockMap[signType].second; PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; ev.mBlockInstance = BlockInstance::createBlockInstance(block, *a5, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return rtn; } //THook(bool, "?_useOn@BlockPlanterItem@@MEBA_NAEAVItemStack@@AEAVActor@@VBlockPos@@EMMM@Z", // class BlockPlanterItem* a1, ItemStack* a2, Actor* a3, BlockPos a4, unsigned char a5, Vec3* a6) //{ // IF_LISTENED(PlayerPlaceBlockEvent) // { // if (Player::isValid((Player*)a3)) // { // PlayerPlaceBlockEvent ev{}; // ev.mPlayer = (Player*)a3; // ev.mBlockInstance = BlockInstance::createBlockInstance(dAccess(a1, 69*8), a4, (int)a3->getDimensionId()); // if (!ev.call()) // return false; // } // } // IF_LISTENED_END(PlayerPlaceBlockEvent) // return original(a1, a2, a3, a4, a5, a6); //} #include TInstanceHook(bool, "?useOn@SeedItemComponentLegacy@@QEAA_NAEAVItemStack@@AEAVActor@@AEBVBlockPos@@EAEBVVec3@@@Z", SeedItemComponentLegacy, ItemStack* a2, Actor* a3, BlockPos const* a4, unsigned char a5, Vec3 const* a6) { IF_LISTENED(PlayerPlaceBlockEvent) { if (Player::isValid((Player*)a3)) { //if (!this->_canPlant(a3->getRegion().getBlock(*a4))) // return original(this, a2, a3, a4, a5, a6); auto growthDirection = dAccess(this, 42); auto blockPos = a4->relative(growthDirection, 1); auto block = dAccess(this); PlayerPlaceBlockEvent ev{}; ev.mPlayer = (Player*)a3; ev.mBlockInstance = BlockInstance::createBlockInstance(block, blockPos, (int)a3->getDimensionId()); if (!ev.call()) return false; } } IF_LISTENED_END(PlayerPlaceBlockEvent) return original(this, a2, a3, a4, a5, a6); } */ /////////////////// PlayerOpenContainer /////////////////// // 没有这个符号 // TClasslessInstanceHook(__int64, "?onEvent@VanillaServerGameplayEventListener@@UEAA?AW4EventResult@@AEBUPlayerOpenContainerEvent@@@Z", void* a2) { // Actor* pl = SymCall("??$tryUnwrap@VActor@@$$V@WeakEntityRef@@QEBAPEAVActor@@XZ", Actor*, void*)(a2); // if (pl->isPlayer()) { // IF_LISTENED(PlayerOpenContainerEvent) { // BlockPos bp = dAccess(a2, 28); // PlayerOpenContainerEvent ev{}; // ev.mPlayer = (Player*)pl; // ev.mBlockInstance = Level::getBlockInstance(bp, pl->getDimensionId()); // ev.mContainer = ev.mBlockInstance.getContainer(); // if (!ev.call()) // return 0; // } // IF_LISTENED_END(PlayerOpenContainerEvent) // } // return original(this, a2); // } /////////////////// PlayerCloseContainer /////////////////// // chest TInstanceHook(bool, "?stopOpen@ChestBlockActor@@UEAAXAEAVPlayer@@@Z", ChestBlockActor, Player* pl) { IF_LISTENED(PlayerCloseContainerEvent) { BlockActor* ba = (BlockActor*)((char*)this - 248); // IDA ChestBlockActor::stopOpen BlockPos bp = ba->getPosition(); PlayerCloseContainerEvent ev{}; ev.mPlayer = pl; ev.mBlockInstance = Level::getBlockInstance(bp, pl->getDimensionId()); ev.mContainer = Level::getBlockInstance(bp, pl->getDimensionId()).getContainer(); ev.call(); } IF_LISTENED_END(PlayerCloseContainerEvent) return original(this, pl); } // barrel TClasslessInstanceHook(bool, "?stopOpen@BarrelBlockActor@@UEAAXAEAVPlayer@@@Z", Player* pl) { IF_LISTENED(PlayerCloseContainerEvent) { BlockActor* ba = (BlockActor*)((char*)this - 240); // IDA ChestBlockActor::stopOpen BlockPos bp = ba->getPosition(); PlayerCloseContainerEvent ev{}; ev.mPlayer = pl; ev.mBlockInstance = Level::getBlockInstance(bp, pl->getDimensionId()); ev.mContainer = Level::getBlockInstance(bp, pl->getDimensionId()).getContainer(); ev.call(); } IF_LISTENED_END(PlayerCloseContainerEvent) return original(this, pl); } /////////////////// PlayerInventoryChange /////////////////// TInstanceHook(void, "?inventoryChanged@Player@@UEAAXAEAVContainer@@HAEBVItemStack@@1_N@Z", Player, void* container, int slotNumber, ItemStack* oldItem, ItemStack* newItem, bool is) { IF_LISTENED(PlayerInventoryChangeEvent) { if (this->isPlayer()) { PlayerInventoryChangeEvent ev{}; ev.mPlayer = this; ev.mSlot = slotNumber; ev.mPreviousItemStack = oldItem; ev.mNewItemStack = newItem; ev.call(); } } IF_LISTENED_END(PlayerInventoryChangeEvent) return original(this, container, slotNumber, oldItem, newItem, is); } /////////////////// PlayerMove /////////////////// // 没有这个符号 // TClasslessInstanceHook(void, "?sendPlayerMove@PlayerEventCoordinator@@QEAAXAEAVPlayer@@@Z", // Player* pl) { // IF_LISTENED(PlayerMoveEvent) { // if (pl->isMoving()) { // PlayerMoveEvent ev{}; // ev.mPlayer = pl; // ev.mPos = pl->getPosition(); // ev.call(); // } // } // IF_LISTENED_END(PlayerMoveEvent) // return original(this, pl); // } /////////////////// PlayerSprint /////////////////// TInstanceHook(void, "?setSprinting@Mob@@UEAAX_N@Z", Mob, bool sprinting) { IF_LISTENED(PlayerSprintEvent) { if (this->isPlayer() && this->isSprinting() != sprinting) { PlayerSprintEvent ev{}; ev.mPlayer = (Player*)this; ev.mIsSprinting = sprinting; if (!ev.call()) return; // sprinting = ev.mIsSprinting; } } IF_LISTENED_END(PlayerSprintEvent) return original(this, sprinting); } #include #include /////////////////// PlayerSetArmor /////////////////// // TInstanceHook(void, "?setArmor@Player@@UEAAXW4ArmorSlot@@AEBVItemStack@@@Z", // Player, unsigned slot, ItemStack* it) { // original(this, slot, it); // IF_LISTENED(PlayerSetArmorEvent) { // if (this->isPlayer()) { // PlayerSetArmorEvent ev{}; // ev.mPlayer = this; // ev.mSlot = slot; // ev.mArmorItem = it; // if (!ev.call()) { // auto& uid = getUniqueID(); // auto& plinv = getSupplies(); // plinv.add(*it, 1); // getArmorContainer().setItem(slot, ItemStack::EMPTY_ITEM); // Schedule::delay([uid] { // auto sp = Global->getPlayer(uid); // if (sp) // sp->refreshInventory(); // }, // 1); // } // } // } // IF_LISTENED_END(PlayerSetArmorEvent) // } /////////////////// PlayerUseRespawnAnchor /////////////////// TInstanceHook(bool, "?trySetSpawn@RespawnAnchorBlock@@CA_NAEAVPlayer@@AEBVBlockPos@@AEAVBlockSource@@AEAVLevel@@@Z", Player, BlockPos* bp, BlockSource* bs, Level* a4) { IF_LISTENED(PlayerUseRespawnAnchorEvent) { PlayerUseRespawnAnchorEvent ev{}; ev.mPlayer = this; ev.mBlockInstance = Level::getBlockInstance(bp, bs); if (!ev.call()) return false; } IF_LISTENED_END(PlayerUseRespawnAnchorEvent) return original(this, bp, bs, a4); } /////////////////// PlayerOpenContainerScreen /////////////////// TInstanceHook(bool, "?canOpenContainerScreen@Player@@UEAA_NXZ", Player) { IF_LISTENED(PlayerOpenContainerScreenEvent) { PlayerOpenContainerScreenEvent ev{}; ev.mPlayer = this; if (!ev.call()) return false; } IF_LISTENED_END(PlayerOpenContainerScreenEvent) return original(this); } /////////////////// PlayerCmdEvent & ConsoleCmd /////////////////// // TClasslessInstanceHook(MCRESULT*, "?executeCommand@MinecraftCommands@@QEBA?AUMCRESULT@@V?$shared_ptr@VCommandContext@@@std@@_N@Z", // MCRESULT* rtn, std::shared_ptr context, bool print) { // Player* sp; // string cmd; // try { // sp = context->getOrigin().getPlayer(); // cmd = context->getCmd(); // if (!cmd.empty() && cmd.at(0) == '/') { // cmd = cmd.substr(1, cmd.size() - 1); // } // if (!Util::isValidUTF8(cmd)) { // logger.error("Detected invalid utf-8 character, command will not be executed"); // return rtn; // } // } catch (...) { // return rtn; // } // if (LL::isDebugMode() && LL::globalConfig.tickThreadId != std::this_thread::get_id()) { // logger.warn("The thread executing the command \"{}\" is not the \"MC_SERVER\" thread", cmd); // } // if (sp) { // // PlayerCmd // IF_LISTENED(PlayerCmdEvent) { // PlayerCmdEvent ev{}; // ev.mCommand = cmd; // ev.mPlayer = sp; // ev.mResult = rtn; // if (!ev.call()) // return rtn; // if (ev.mCommand.empty() || ev.mCommand.at(0) != '/') // context->getCmd() = "/" + ev.mCommand; // else // context->getCmd() = ev.mCommand; // } // IF_LISTENED_END(PlayerCmdEvent) // } else { // // ConsoleCmd // IF_LISTENED(ConsoleCmdEvent) { // ConsoleCmdEvent ev{}; // ev.mCommand = cmd; // if (!ev.call()) // return rtn; // if (ev.mCommand.empty() || ev.mCommand.at(0) != '/') // context->getCmd() = "/" + ev.mCommand; // else // context->getCmd() = ev.mCommand; // } // IF_LISTENED_END(ConsoleCmdEvent) // } // return original(this, rtn, context, print); // } /////////////////// PlayerExperienceAddEvent /////////////////// TInstanceHook(void, "?addExperience@Player@@UEAAXH@Z", Player, int exp) { IF_LISTENED(PlayerExperienceAddEvent) { PlayerExperienceAddEvent ev{}; ev.mPlayer = this; ev.mExp = exp; if (!ev.call()) return; } IF_LISTENED_END(PlayerExperienceAddEvent) return original(this, exp); } ////////////// PlayerInteractEntity ////////////// TInstanceHook(void, "?handle@ItemUseOnActorInventoryTransaction@@UEBA?AW4InventoryTransactionError@@AEAVPlayer@@_N@Z", ServerNetworkHandler, ServerPlayer* sp, bool unk) { IF_LISTENED(PlayerInteractEntityEvent) { PlayerInteractEntityEvent ev{}; ev.mPlayer = sp; ev.mTargetId = dAccess(this); ev.mInteractiveMode = static_cast(dAccess(this)); if (!ev.call()) return; } IF_LISTENED_END(PlayerInteractEntityEvent) return original(this, sp, unk); } /////////////////// CmdBlockExecute /////////////////// // TInstanceHook(bool, "?_performCommand@BaseCommandBlock@@AEAA_NAEAVBlockSource@@AEBVCommandOrigin@@AEA_N@Z", // BaseCommandBlock, BlockSource* a2, CommandOrigin* a3, bool* a4) { // IF_LISTENED(CmdBlockExecuteEvent) { // CmdBlockExecuteEvent ev{}; // ev.mCommand = this->getCommand(); // if ((OriginType)a3->getOriginType() == OriginType::MinecartBlock) { // ev.mIsMinecart = true; // ev.mMinecart = a3->getEntity(); // } else { // ev.mIsMinecart = false; // ev.mBlockInstance = Level::getBlockInstance(a3->getBlockPosition(), a2); // } // if (!ev.call()) // return false; // } // IF_LISTENED_END(CmdBlockExecuteEvent) // return original(this, a2, a3, a4); // } /////////////////// BlockInteracted /////////////////// TClasslessInstanceHook(unsigned short, "?onBlockInteractedWith@VanillaServerGameplayEventListener@@UEAA?AW4EventResult@@AEAVPlayer@@AEBVBlockPos@@@Z", Player* pl, BlockPos* bp) { IF_LISTENED(BlockInteractedEvent) { BlockInteractedEvent ev{}; ev.mPlayer = pl; ev.mBlockInstance = Level::getBlockInstance(bp, pl->getDimensionId()); if (!ev.call()) return 0; } IF_LISTENED_END(BlockInteractedEvent) return original(this, pl, bp); } /////////////////// BlockChanged /////////////////// // 没有这个符号 // TInstanceHook(void, "?_blockChanged@BlockSource@@IEAAXAEBVBlockPos@@IAEBVBlock@@1HPEBUActorBlockSyncMessage@@PEAVActor@@@Z", // BlockSource, BlockPos* bp, int a3, Block* afterBlock, Block* beforeBlock, int a6, void* a7, Actor* ac) { // IF_LISTENED(BlockChangedEvent) { // int dimId = this->getDimensionId(); // BlockChangedEvent ev{}; // ev.mPreviousBlockInstance = BlockInstance::createBlockInstance(beforeBlock, *bp, dimId); // ev.mNewBlockInstance = BlockInstance::createBlockInstance(afterBlock, *bp, dimId); // if (!ev.call()) // return; // } // IF_LISTENED_END(BlockChangedEvent) // return original(this, bp, a3, afterBlock, beforeBlock, a6, a7, ac); // } /////////////////// BlockExploded /////////////////// // 没有这个符号 // TInstanceHook(void, "?onExploded@Block@@QEBAXAEAVBlockSource@@AEBVBlockPos@@PEAVActor@@@Z", // Block, BlockSource* bs, BlockPos* bp, Actor* actor) { // IF_LISTENED(BlockExplodedEvent) { // if (actor) { // BlockExplodedEvent ev{}; // ev.mBlockInstance = BlockInstance::createBlockInstance(this, *bp, bs->getDimensionId()); // ev.mExplodeSource = actor; // ev.call(); // } // } // IF_LISTENED_END(BlockExplodedEvent) // return original(this, bs, bp, actor); // } /////////////////// FireSpread /////////////////// bool onFireSpread_OnPlace = false; TClasslessInstanceHook(void, "?onPlace@FireBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@@Z", BlockSource* bs, BlockPos* bp) { onFireSpread_OnPlace = true; original(this, bs, bp); onFireSpread_OnPlace = false; } TClasslessInstanceHook(bool, "?mayPlace@FireBlock@@UEBA_NAEAVBlockSource@@AEBVBlockPos@@@Z", BlockSource* bs, BlockPos* bp) { auto rtn = original(this, bs, bp); if (!onFireSpread_OnPlace || !rtn) return rtn; IF_LISTENED(FireSpreadEvent) { FireSpreadEvent ev{}; ev.mTarget = *bp; ev.mDimensionId = bs->getDimensionId(); if (!ev.call()) return false; } IF_LISTENED_END(FireSpreadEvent) return rtn; } /////////////////// ContainerChange /////////////////// // #include // TInstanceHook(void, "?_onItemChanged@LevelContainerModel@@MEAAXHAEBVItemStack@@0@Z", // LevelContainerModel, int slotNumber, ItemStack* oldItem, ItemStack* newItem) { // IF_LISTENED(ContainerChangeEvent) { // Player* pl = (Player*)dAccess(this, 208); // IDA LevelContainerModel::LevelContainerModel // if (pl->hasOpenContainer()) { // BlockPos* bp = (BlockPos*)((char*)this + 216); // ContainerChangeEvent ev{}; // ev.mBlockInstance = Level::getBlockInstance(bp, pl->getDimensionId()); // ev.mContainer = ev.mBlockInstance.getContainer(); // ev.mPlayer = pl; // ev.mSlot = slotNumber + this->_getContainerOffset(); // ev.mPreviousItemStack = oldItem; // ev.mNewItemStack = newItem; // ev.mActor = this->getEntity(); // ev.call(); // } // } // IF_LISTENED_END(ContainerChangeEvent) // return original(this, slotNumber, oldItem, newItem); // } /////////////////// ProjectileHitBlock /////////////////// // 没有这个符号 // TInstanceHook(void, "?onProjectileHit@Block@@QEBAXAEAVBlockSource@@AEBVBlockPos@@AEBVActor@@@Z", // Block, BlockSource* bs, BlockPos* bp, Actor* actor) { // // Exclude default position BlockPos::Zero // if ((bp->x | bp->y | bp->z) == 0) // actor->getPos().distanceTo(bp->center())>5) // return original(this, bs, bp, actor); // IF_LISTENED(ProjectileHitBlockEvent) { // if (this->getTypeName() != "minecraft:air") { // ProjectileHitBlockEvent ev{}; // ev.mBlockInstance = Level::getBlockInstance(bp, bs); // ev.mSource = actor; // ev.call(); // } // } // IF_LISTENED_END(ProjectileHitBlockEvent) // return original(this, bs, bp, actor); // } /////////////////// RedStoneUpdate /////////////////// // 红石�?? TClasslessInstanceHook(void, "?onRedstoneUpdate@RedStoneWireBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@H_N@Z", BlockSource* bs, BlockPos* bp, int level, bool isActive) { IF_LISTENED(RedStoneUpdateEvent) { RedStoneUpdateEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mRedStonePower = level; ev.mIsActivated = level != 0; if (!ev.call()) return; level = ev.mRedStonePower; } IF_LISTENED_END(RedStoneUpdateEvent) return original(this, bs, bp, level, isActive); } // 红石火把 TClasslessInstanceHook(void, "?onRedstoneUpdate@RedstoneTorchBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@H_N@Z", BlockSource* bs, BlockPos* bp, int level, bool isActive) { IF_LISTENED(RedStoneUpdateEvent) { RedStoneUpdateEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mRedStonePower = level; ev.mIsActivated = level != 0; if (!ev.call()) return; level = ev.mRedStonePower; } IF_LISTENED_END(RedStoneUpdateEvent) return original(this, bs, bp, level, isActive); } // 红石中继�?? TClasslessInstanceHook(void, "?onRedstoneUpdate@DiodeBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@H_N@Z", BlockSource* bs, BlockPos* bp, int level, bool isActive) { IF_LISTENED(RedStoneUpdateEvent) { RedStoneUpdateEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mRedStonePower = level; ev.mIsActivated = level != 0; if (!ev.call()) return; level = ev.mRedStonePower; } IF_LISTENED_END(RedStoneUpdateEvent) return original(this, bs, bp, level, isActive); } // 红石比较�?? TClasslessInstanceHook(void, "?onRedstoneUpdate@ComparatorBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@H_N@Z", BlockSource* bs, BlockPos* bp, int level, bool isActive) { IF_LISTENED(RedStoneUpdateEvent) { RedStoneUpdateEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mRedStonePower = level; ev.mIsActivated = level != 0; if (!ev.call()) return; level = ev.mRedStonePower; } IF_LISTENED_END(RedStoneUpdateEvent) return original(this, bs, bp, level, isActive); } /////////////////// HopperSearchItem /////////////////// // 没有这个符号 // TClasslessInstanceHook(bool, "?_tryPullInItemsFromAboveContainer@Hopper@@IEAA_NAEAVBlockSource@@AEAVContainer@@AEBVVec3@@@Z", // BlockSource* bs, void* container, Vec3* pos) { // bool isMinecart = dAccess(this, 5); // IDA Hopper::Hopper // IF_LISTENED(HopperSearchItemEvent) { // HopperSearchItemEvent ev{}; // if (isMinecart) { // ev.isMinecart = true; // ev.mMinecartPos = *pos; // } else { // ev.isMinecart = false; // ev.mHopperBlock = Level::getBlockInstance(pos->toBlockPos(), bs); // } // ev.mDimensionId = bs->getDimensionId(); // if (!ev.call()) // return false; // } // IF_LISTENED_END(HopperSearchItemEvent) // return original(this, bs, container, pos); // } /////////////////// HopperPushOut /////////////////// TClasslessInstanceHook(bool, "?_pushOutItems@Hopper@@IEAA_NAEAVBlockSource@@AEAVContainer@@AEBVVec3@@H@Z", BlockSource* bs, void* container, Vec3* pos, int a5) { IF_LISTENED(HopperPushOutEvent) { HopperPushOutEvent ev{}; ev.mPos = *pos; ev.mDimensionId = bs->getDimensionId(); if (!ev.call()) return false; } IF_LISTENED_END(HopperPushOutEvent) return original(this, bs, container, pos, a5); } /////////////////// PistonTryPushEvent & PistonPushEvent /////////////////// TInstanceHook(bool, "?_attachedBlockWalker@PistonBlockActor@@AEAA_NAEAVBlockSource@@AEBVBlockPos@@EE@Z", PistonBlockActor, BlockSource* bs, BlockPos* bp, char a3, char a4) { IF_LISTENED(PistonTryPushEvent) { PistonTryPushEvent ev{}; ev.mTargetBlockInstance = Level::getBlockInstance(bp, bs); if (ev.mTargetBlockInstance.getBlock()->getTypeName() == "minecraft:air") return original(this, bs, bp, a3, a4); ev.mPistonBlockInstance = Level::getBlockInstance(this->getPosition(), bs); if (!ev.call()) return false; } IF_LISTENED_END(PistonTryPushEvent) bool res = original(this, bs, bp, a3, a4); if (!res) return false; IF_LISTENED(PistonPushEvent) { PistonPushEvent ev{}; ev.mTargetBlockInstance = Level::getBlockInstance(bp, bs); if (ev.mTargetBlockInstance.getBlock()->getTypeName() == "minecraft:air") return true; ev.mPistonBlockInstance = Level::getBlockInstance(this->getPosition(), bs); ev.call(); } IF_LISTENED_END(PistonPushEvent) return true; } /////////////////// FarmLandDecay /////////////////// TClasslessInstanceHook(void, "?transformOnFall@FarmBlock@@UEBAXAEAVBlockSource@@AEBVBlockPos@@PEAVActor@@M@Z", BlockSource* bs, BlockPos* bp, Actor* ac, float a5) { IF_LISTENED(FarmLandDecayEvent) { FarmLandDecayEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mActor = ac; if (!ev.call()) return; } IF_LISTENED_END(FarmLandDecayEvent) return original(this, bs, bp, ac, a5); } /////////////////// PlayerUseFrameBlockEvent /////////////////// // 没有这个符号 // TClasslessInstanceHook(bool, "?use@ItemFrameBlock@@UEBA_NAEAVPlayer@@AEBVBlockPos@@E@Z", // Player* a2, BlockPos* a3) { // IF_LISTENED(PlayerUseFrameBlockEvent) { // PlayerUseFrameBlockEvent ev{}; // ev.mType = PlayerUseFrameBlockEvent::Type::Use; // ev.mBlockInstance = Level::getBlockInstance(a3, a2->getDimensionId()); // ev.mPlayer = a2; // if (!ev.call()) // return false; // } // IF_LISTENED_END(PlayerUseFrameBlockEvent) // return original(this, a2, a3); // } TClasslessInstanceHook(bool, "?attack@ItemFrameBlock@@UEBA_NPEAVPlayer@@AEBVBlockPos@@@Z", Player* a2, BlockPos* a3) { IF_LISTENED(PlayerUseFrameBlockEvent) { PlayerUseFrameBlockEvent ev{}; ev.mType = PlayerUseFrameBlockEvent::Type::Attack; ev.mBlockInstance = Level::getBlockInstance(a3, a2->getDimensionId()); ev.mPlayer = a2; if (!ev.call()) return false; } IF_LISTENED_END(PlayerUseFrameBlockEvent) return original(this, a2, a3); } /////////////////// LiquidSpreadEvent /////////////////// #include TInstanceHook(bool, "?_canSpreadTo@LiquidBlockDynamic@@AEBA_NAEAVBlockSource@@AEBVBlockPos@@1E@Z", LiquidBlockDynamic, class BlockSource& bs, class BlockPos const& to, class BlockPos const& from, unsigned char unk) { auto rtn = original(this, bs, to, from, unk); if (!rtn) return rtn; IF_LISTENED(LiquidSpreadEvent) { LiquidSpreadEvent ev{}; ev.mBlockInstance = BlockInstance::createBlockInstance( const_cast(&this->getRenderBlock()), from, bs.getDimensionId()); ev.mTarget = to; ev.mDimensionId = bs.getDimensionId(); if (!ev.call()) return false; } IF_LISTENED_END(LiquidSpreadEvent) return rtn; } // THook(void, "?_trySpreadTo@LiquidBlockDynamic@@AEBAXAEAVBlockSource@@AEBVBlockPos@@H1E@Z", // LiquidBlockDynamic* _this, BlockSource* bs, BlockPos* to, unsigned int a4, BlockPos* from, char id) //{ // IF_LISTENED(LiquidSpreadEvent) // { // LiquidSpreadEvent ev{}; // ev.mBlockInstance = BlockInstance::createBlockInstance( // const_cast(&_this->getRenderBlock()), *from, bs->getDimensionId()); // ev.mTarget = *to; // ev.mDimensionId = bs->getDimensionId(); // logger.warn("LiquidSpreadEvent - {} - {} -> {}", // ev.mBlockInstance.getBlock()->getTypeName(), from->toString(), to->toString()); // if (!ev.call()) // return; // } // IF_LISTENED_END(LiquidSpreadEvent) // return; // original(_this, bs, to, a4, from, id); // } /////////////////// PlayerDeath /////////////////// TInstanceHook(void*, "?die@ServerPlayer@@UEAAXAEBVActorDamageSource@@@Z", ServerPlayer, ActorDamageSource* src) { IF_LISTENED(PlayerDieEvent) { if (this->isPlayer()) { PlayerDieEvent ev{}; ev.mPlayer = this; ev.mDamageSource = src; ev.call(); } } IF_LISTENED_END(PlayerDieEvent) isDieDrop = true; auto out = original(this, src); isDieDrop = false; return out; } #include /////////////////// PlayerDestroy /////////////////// // TInstanceHook(bool, "?destroyBlock@SurvivalMode@@UEAA_NAEBVBlockPos@@E@Z", // SurvivalMode, BlockPos a3, unsigned __int8 a4) //{ // IF_LISTENED(PlayerDestroyBlockEvent) // { // if (getPlayer()->isPlayer()) // { // PlayerDestroyBlockEvent ev{}; // ev.mPlayer = getPlayer(); // auto bl = Level::getBlockInstance(a3, getPlayer()->getDimensionId()); // ev.mBlockInstance = bl; // if (!ev.call()) // { // return false; // } // } // } // IF_LISTENED_END(PlayerDestroyBlockEvent) // return original(this, a3, a4); // } TInstanceHook(bool, "?destroyBlock@GameMode@@UEAA_NAEBVBlockPos@@E@Z", GameMode, BlockPos a3, unsigned __int8 a4) { IF_LISTENED(PlayerDestroyBlockEvent) { if (getPlayer()->isPlayer()) { PlayerDestroyBlockEvent ev{}; ev.mPlayer = getPlayer(); auto bl = Level::getBlockInstance(a3, getPlayer()->getDimensionId()); ev.mBlockInstance = bl; if (!ev.call()) { return false; } } } IF_LISTENED_END(PlayerDestroyBlockEvent) return original(this, a3, a4); } /////////////////// PlayerUseItemOn /////////////////// TInstanceHook(bool, "?useItemOn@GameMode@@UEAA_NAEAVItemStack@@AEBVBlockPos@@EAEBVVec3@@PEBVBlock@@@Z", GameMode, ItemStack& it, BlockPos bp, unsigned char side, Vec3* clickPos, void* a6_block) { IF_LISTENED(PlayerUseItemOnEvent) { PlayerUseItemOnEvent ev{}; ev.mPlayer = this->getPlayer(); ev.mBlockInstance = Level::getBlockInstance(bp, ev.mPlayer->getDimensionId()); ev.mItemStack = ⁢ ev.mFace = side; ev.mClickPos = *clickPos; if (!ev.call()) return false; } IF_LISTENED_END(PlayerUseItemOnEvent) return original(this, it, bp, side, clickPos, a6_block); } /////////////////// MobHurt /////////////////// // TInstanceHook(bool, "?_hurt@Mob@@MEAA_NAEBVActorDamageSource@@M_N1@Z", // Mob, ActorDamageSource& src, float damage, bool unk1_1, bool unk2_0) { // IF_LISTENED(MobHurtEvent) { // if (this) { // MobHurtEvent ev{}; // ev.mMob = this; // ev.mDamageSource = &src; // ev.mDamage = damage; // if (!ev.call()) // return false; // damage = ev.mDamage; // } // } // IF_LISTENED_END(MobHurtEvent) // return original(this, src, damage, unk1_1, unk2_0); // } // TInstanceHook(float, "?getDamageAfterResistanceEffect@Mob@@UEBAMAEBVActorDamageSource@@M@Z", Mob, ActorDamageSource* src, float damage) { // if (src->getCause() == ActorDamageCause::ActorDamageCause_Magic) { // IF_LISTENED(MobHurtEvent) { // if (this) { // MobHurtEvent ev{}; // ev.mMob = this; // ev.mDamageSource = src; // ev.mDamage = damage; // if (!ev.call()) // return 0; // damage = ev.mDamage; // } // } // IF_LISTENED_END(MobHurtEvent) // } // return original(this, src, damage); // } //////////////// PlayerUseItem & PlayerEat //////////////// // #include // TInstanceHook(bool, "?baseUseItem@GameMode@@QEAA_NAEAVItemStack@@@Z", GameMode, ItemStack& it) { // auto pl = this->getPlayer(); // IF_LISTENED(PlayerUseItemEvent) { // PlayerUseItemEvent ev{}; // ev.mPlayer = pl; // ev.mItemStack = ⁢ // if (!ev.call()) // return false; // } // IF_LISTENED_END(PlayerUseItemEvent) // IF_LISTENED(PlayerEatEvent) { // if (it.getItem()->isFood() && (pl->isHungry() || pl->forceAllowEating())) { // PlayerEatEvent ev{}; // ev.mPlayer = pl; // ev.mFoodItem = ⁢ // if (!ev.call()) { // pl->refreshAttribute(Player::HUNGER); // return false; // } // } // } // IF_LISTENED_END(PlayerEatEvent) // return original(this, it); // } // THook(ItemStack*, "?use@BucketItem@@UEBAAEAVItemStack@@AEAV2@AEAVPlayer@@@Z", Item* _this, ItemStack* a1, Player* a2) { // if (_this->getFullItemName() == "minecraft:milk_bucket") { // IF_LISTENED(PlayerEatEvent) { // PlayerEatEvent ev{}; // ev.mPlayer = a2; // ev.mFoodItem = a1; // if (!ev.call()) { // return a1; // } // } // IF_LISTENED_END(PlayerEatEvent) // } // return original(_this, a1, a2); // } // THook(ItemStack*, "?use@PotionItem@@UEBAAEAVItemStack@@AEAV2@AEAVPlayer@@@Z", void* _this, ItemStack* a1, Player* a2) { // IF_LISTENED(PlayerEatEvent) { // PlayerEatEvent ev{}; // ev.mPlayer = a2; // ev.mFoodItem = a1; // if (!ev.call()) { // return a1; // } // } // IF_LISTENED_END(PlayerEatEvent) // return original(_this, a1, a2); // } /////////////////// MobDie /////////////////// TInstanceHook(bool, "?die@Mob@@UEAAXAEBVActorDamageSource@@@Z", Mob, ActorDamageSource* ads) { IF_LISTENED(MobDieEvent) { if (this) { MobDieEvent ev{}; ev.mMob = this; ev.mDamageSource = ads; if (!ev.call()) return false; } } IF_LISTENED_END(MobDieEvent) return original(this, ads); } /////////////////// Entity & Block Explosion /////////////////// TClasslessInstanceHook(void, "?explode@Explosion@@QEAAXXZ") { try { auto acId = *(ActorUniqueID*)((QWORD*)this + 11); auto actor = Global->getEntity(acId); auto pos = *(Vec3*)(QWORD*)this; auto radius = *((float*)this + 3); auto bs = (BlockSource*)*((QWORD*)this + 12); auto maxResistance = *((float*)this + 26); auto genFire = (bool)*((BYTE*)this + 80); auto canBreaking = (bool)*((BYTE*)this + 81); IF_LISTENED(EntityExplodeEvent) { if (actor) { EntityExplodeEvent ev{}; ev.mActor = actor; ev.mBreaking = canBreaking; ev.mFire = genFire; ev.mMaxResistance = maxResistance; ev.mPos = pos; ev.mRadius = radius; ev.mDimension = bs; if (!ev.call()) return; *((float*)this + 3) = ev.mRadius; *((float*)this + 26) = ev.mMaxResistance; *((BYTE*)this + 80) = ev.mFire; *((BYTE*)this + 81) = ev.mBreaking; } } IF_LISTENED_END(EntityExplodeEvent) IF_LISTENED(BlockExplodeEvent) { if (!actor) { BlockPos bp = pos.toBlockPos(); BlockExplodeEvent ev{}; ev.mBlockInstance = Level::getBlockInstance(bp, bs); ev.mBreaking = canBreaking; ev.mFire = genFire; ev.mMaxResistance = maxResistance; ev.mRadius = radius; if (!ev.call()) return; *((float*)this + 3) = ev.mRadius; *((float*)this + 26) = ev.mMaxResistance; *((BYTE*)this + 80) = ev.mFire; *((BYTE*)this + 81) = ev.mBreaking; } } IF_LISTENED_END(BlockExplodeEvent) } catch (...) { logger.error("Event Callback Failed!"); logger.error("Uncaught Exception Detected!"); logger.error("In Event: Entity or Block Explosion"); } original(this); } ////////////// ProjectileHitEntity ////////////// // TClasslessInstanceHook(void, "?onHit@ProjectileComponent@@QEAAXAEAVActor@@AEBVHitResult@@@Z", // Actor* item, HitResult* res) { // IF_LISTENED(ProjectileHitEntityEvent) { // Actor* to = res->getEntity(); // if (to) { // ProjectileHitEntityEvent ev{}; // ev.mTarget = to; // ev.mSource = item; // ev.call(); // } // } // IF_LISTENED_END(ProjectileHitEntityEvent) // return original(this, item, res); // } ////////////// WitherBossDestroy ////////////// // 没有这个符号 // TInstanceHook(void, "?_destroyBlocks@WitherBoss@@AEAAXAEAVLevel@@AEBVAABB@@AEAVBlockSource@@HW4WitherAttackType@1@@Z", // Actor, Level* a2, AABB* aabb, BlockSource* a4, int a5, unsigned int a6) { // IF_LISTENED(WitherBossDestroyEvent) { // WitherBossDestroyEvent ev{}; // ev.mWitherBoss = (WitherBoss*)this; // ev.mDestroyRange = *aabb; // if (!ev.call()) // return; // *aabb = ev.mDestroyRange; // } // IF_LISTENED_END(WitherBossDestroyEvent) // original(this, a2, aabb, a4, a5, a6); // } ////////////// EntityRide ////////////// // 没有这个符号 // TInstanceHook(bool, "?canAddPassenger@Actor@@UEBA_NAEAV1@@Z", // Actor, Actor* a2) { // auto rtn = original(this, a2); // if (!rtn) // return false; // IF_LISTENED(EntityRideEvent) { // EntityRideEvent ev{}; // ev.mRider = a2; // ev.mVehicle = this; // if (!ev.call()) // return false; // } // IF_LISTENED_END(EntityRideEvent) // return rtn; // } ////////////// EntityStepOnPressurePlate ////////////// // 没有这个符号 // TClasslessInstanceHook(bool, "?shouldTriggerEntityInside@BasePressurePlateBlock@@UEBA_NAEAVBlockSource@@AEBVBlockPos@@AEAVActor@@@Z", // BlockSource* a2, BlockPos* a3, Actor* a4) { // IF_LISTENED(EntityStepOnPressurePlateEvent) { // EntityStepOnPressurePlateEvent ev{}; // ev.mActor = a4; // ev.mBlockInstance = Level::getBlockInstance(a3, a4->getDimensionId()); // if (!ev.call()) // return false; // } // IF_LISTENED_END(EntityStepOnPressurePlateEvent) // return original(this, a2, a3, a4); // } ////////////// ProjectileSpawn ////////////// // TClasslessInstanceHook(Actor*, // "?spawnProjectile@Spawner@@QEAAPEAVActor@@AEAVBlockSource@@AEBUActorDefinitionIdentifier@@PEAV2@AEBVVec3@@3@Z", // BlockSource* a2, ActorDefinitionIdentifier* a3, Actor* a4, Vec3* a5, Vec3* a6) { // string name = a3->getCanonicalName(); // if (name != "minecraft:thrown_trident") { // IF_LISTENED(ProjectileSpawnEvent) { // ProjectileSpawnEvent ev{}; // ev.mShooter = a4; // ev.mIdentifier = a3; // ev.mType = name; // if (!ev.call()) // return nullptr; // } // IF_LISTENED_END(ProjectileSpawnEvent) // } // auto projectile = original(this, a2, a3, a4, a5, a6); // IF_LISTENED(ProjectileCreatedEvent) { // ProjectileCreatedEvent ev{}; // ev.mShooter = a4; // ev.mProjectile = projectile; // ev.call(); // } // IF_LISTENED_END(ProjectileCreatedEvent) // return projectile; // } // #include #include // static_assert(sizeof(ActorDefinitionIdentifier) == 176); // TInstanceHook(void, "?_shootFirework@CrossbowItem@@AEBAXAEBVItemInstance@@AEAVPlayer@@@Z", // CrossbowItem, void* a1, Player* a2) { // IF_LISTENED(ProjectileSpawnEvent) { // ActorDefinitionIdentifier identifier("minecraft:fireworks_rocket"); // ProjectileSpawnEvent ev{}; // ev.mShooter = a2; // ev.mIdentifier = &identifier; // ev.mType = this->getFullItemName(); // if (!ev.call()) // return; // } // IF_LISTENED_END(ProjectileSpawnEvent) // original(this, a1, a2); // } // TClasslessInstanceHook(void, "?releaseUsing@TridentItem@@UEBAXAEAVItemStack@@PEAVPlayer@@H@Z", // ItemStack* a2, Player* a3, int a4) { // IF_LISTENED(ProjectileSpawnEvent) { // ActorDefinitionIdentifier identifier("minecraft:thrown_trident"); // ProjectileSpawnEvent ev{}; // ev.mShooter = a3; // ev.mIdentifier = &identifier; // ev.mType = a2->getTypeName(); // if (!ev.call()) // return; // } // IF_LISTENED_END(ProjectileSpawnEvent) // return original(this, a2, a3, a4); // } // #include // #include ////////////// NpcCmd ////////////// // TInstanceHook(void, // "?executeCommandAction@NpcComponent@@QEAAXAEAVActor@@AEAVPlayer@@HAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", // NpcComponent, Actor* ac, Player* pl, int a4, string& a5) { // IF_LISTENED(NpcCmdEvent) { // // IDA NpcComponent::executeCommandAction // // NpcSceneDialogueData data(*this, *ac, a5); // auto ec = (EntityContext*)((char*)ac + 8); // NpcSceneDialogueData data(WeakEntityRef(ec->getWeakRef()), a5); // auto container = data.getActionsContainer(); // auto actionAt = container->getActionAt(a4); // if (actionAt && dAccess(actionAt, 8) == (char)1) { // NpcCmdEvent ev{}; // ev.mPlayer = pl; // ev.mNpc = ac; // ev.mCommand = actionAt->getText(); // if (!ev.call()) // return; // } // } // IF_LISTENED_END(NpcCmdEvent) // return original(this, ac, pl, a4, a5); // } ////////////// ArmorStandChange ////////////// TInstanceHook(bool, "?_trySwapItem@ArmorStand@@AEAA_NAEAVPlayer@@W4EquipmentSlot@@@Z", ArmorStand, Player* a2, int a3) { IF_LISTENED(ArmorStandChangeEvent) { ArmorStandChangeEvent ev{}; ev.mArmorStand = this; ev.mPlayer = a2; ev.mSlot = a3; if (!ev.call()) return false; } IF_LISTENED_END(ArmorStandChangeEvent) return original(this, a2, a3); } ////////////////// EntityTransform ////////////////// TClasslessInstanceHook(void, "?maintainOldData@TransformationComponent@@QEAAXAEAVActor@@0AEBUTransformationDescription@@AEBUActorUniqueID@@AEBVLevel@@@Z", Actor* beforeEntity, Actor* afterEntity, void* a4, ActorUniqueID* aid, Level* level) { IF_LISTENED(EntityTransformEvent) { EntityTransformEvent ev{}; ActorUniqueID actorUniqueID = beforeEntity->getActorUniqueId(); ev.mBeforeEntityUniqueId = &actorUniqueID; ev.mAfterEntity = afterEntity; ev.call(); } IF_LISTENED_END(EntityTransformEvent) original(this, beforeEntity, afterEntity, a4, aid, level); } ////////////// PlayerScoreChangedEvent ////////////// TClasslessInstanceHook(void, "?onScoreChanged@ServerScoreboard@@UEAAXAEBUScoreboardId@@AEBVObjective@@@Z", ScoreboardId* a1, Objective* a2) { IF_LISTENED(PlayerScoreChangedEvent) { __int64 id = a1->id; Player* player = nullptr; auto pls = Level::getAllPlayers(); for (auto& pl : pls) { if (Global->getScoreboardId(*pl).id == id) { player = pl; break; } } if (player) { PlayerScoreChangedEvent ev{}; ev.mPlayer = player; ev.mScore = a2->getPlayerScore(*a1).getCount(); ev.mScoreboardId = a1; ev.mObjective = a2; ev.call(); } } IF_LISTENED_END(PlayerScoreChangedEvent) return original(this, a1, a2); } #include ////////////// ServerStarted ////////////// // 没有这个符号 // TClasslessInstanceHook(void, "?sendServerThreadStarted@ServerInstanceEventCoordinator@@QEAAXAEAVServerInstance@@@Z", // class ServerInstance& ins) { // if(!LL::isDebugMode()) // _set_se_translator(seh_exception::TranslateSEHtoCE); // LL::globalConfig.tickThreadId = std::this_thread::get_id(); // Global = Global->getLevel(); // Global = (ServerLevel*)Global->getLevel(); // // Global = Global->getServerNetworkHandler(); // LL::globalConfig.serverStatus = LL::LLServerStatus::Running; // IF_LISTENED(ServerStartedEvent) { // ServerStartedEvent ev{}; // ev.call(); // } // IF_LISTENED_END(ServerStartedEvent) // original(this, ins); // } ////////////// ServerStopped ////////////// TClasslessInstanceHook(void, "??1DedicatedServer@@UEAA@XZ") { LL::globalConfig.serverStatus = LL::LLServerStatus::Stopping; IF_LISTENED(ServerStoppedEvent) { ServerStoppedEvent ev{}; ev.call(); } IF_LISTENED_END(ServerStoppedEvent) original(this); } TClasslessInstanceHook(void, "?execute@StopCommand@@UEBAXAEBVCommandOrigin@@AEAVCommandOutput@@@Z", class CommandOrigin const& origin, class CommandOutput& output) { LL::globalConfig.serverStatus = LL::LLServerStatus::Stopping; original(this, origin, output); } ////////////// RegCmd ////////////// // TInstanceHook(void, "?setup@ChangeSettingCommand@@SAXAEAVCommandRegistry@@@Z", // CommandRegistry, void* a1) { // Global = this; // original(this, a1); // IF_LISTENED(RegCmdEvent) { // RegCmdEvent ev{}; // ev.mCommandRegistry = this; // ev.call(); // // setup dynamic command // DynamicCommand::onServerCommandsRegister(*this); // } // IF_LISTENED_END(RegCmdEvent) // } ////////////// ConsoleOutput ////////////// THook(std::ostream&, "??$_Insert_string@DU?$char_traits@D@std@@_K@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@QEBD_K@Z", std::ostream& _this, const char* str, unsigned size) { IF_LISTENED(ConsoleOutputEvent) { if (&_this == &std::cout) { ConsoleOutputEvent ev{}; ev.mOutput = string(str, size); if (!ev.call()) return _this; } } IF_LISTENED_END(ConsoleOutputEvent) return original(_this, str, size); } ////////////// PlayerDropItem ////////////// TInstanceHook(void*, "?handle@ComplexInventoryTransaction@@UEBA?AW4InventoryTransactionError@@AEAVPlayer@@_N@Z", ComplexInventoryTransaction, Player* a2, int a3) { if (this->type == ComplexInventoryTransaction::Type::NORMAL) { IF_LISTENED(PlayerDropItemEvent) { auto& InvTran = this->data; auto& action = InvTran.getActions(InventorySource(InventorySourceType::Container, ContainerID::Inventory)); if (action.size() == 1) { PlayerDropItemEvent ev{}; auto& item = a2->getInventory().getItem(action[0].slot); ev.mItemStack = const_cast(&item); ev.mPlayer = a2; if (!ev.call()) { a2->sendInventory(1); return nullptr; } isQDrop = true; auto out = original(this, a2, a3); isQDrop = false; return out; } } IF_LISTENED_END(PlayerDropItemEvent) } return original(this, a2, a3); } // 没有这个符号 // TInstanceHook(void, "?dropSlot@Inventory@@QEAAXH_N00@Z", // Container, int a2, char a3, char a4, bool a5) { // auto pl = dAccess(this); // if (pl->isPlayer()) { // IF_LISTENED(PlayerDropItemEvent) { // PlayerDropItemEvent ev{}; // if (a2 >= 0) { // auto& item = this->getItem(a2); // if (!item.isNull()) { // ev.mItemStack = const_cast(&item); // ev.mPlayer = pl; // } // if (!ev.call()) { // return; // } // } // } // IF_LISTENED_END(PlayerDropItemEvent) // } // return original(this, a2, a3, a4, a5); // } ////////////// PlayerBedEnter ////////////// TInstanceHook(int, "?startSleepInBed@Player@@UEAA?AW4BedSleepingResult@@AEBVBlockPos@@@Z", Player, BlockPos const& blk) { auto bl = Level::getBlockInstance(blk, getDimensionId()); IF_LISTENED(PlayerBedEnterEvent) { PlayerBedEnterEvent ev{}; ev.mPlayer = this; ev.mBlockInstance = &bl; if (!ev.call()) return 0; } IF_LISTENED_END(PlayerBedEnterEvent) return original(this, blk); } #include ////////////// MobSpawn ////////////// // TInstanceHook(Mob*, "?spawnMob@Spawner@@QEAAPEAVMob@@AEAVBlockSource@@AEBUActorDefinitionIdentifier@@PEAVActor@@AEBVVec3@@_N44@Z", // Spawner, BlockSource* a2, ActorDefinitionIdentifier* a3, Actor* a4, Vec3& a5, bool a6, bool a7, bool a8) { // IF_LISTENED(MobSpawnEvent) { // MobSpawnEvent ev{}; // ev.mTypeName = a3->getCanonicalName(); // ev.mPos = a5; // ev.mDimensionId = a2->getDimensionId(); // if (!ev.call()) // return nullptr; // } // IF_LISTENED_END(MobSpawnEvent) // return original(this, a2, a3, a4, a5, a6, a7, a8); // } #include "Impl/FormPacketHelper.h" #include ////////////// FormResponsePacket ////////////// TClasslessInstanceHook(void, "?handle@?$PacketHandlerDispatcherInstance@VModalFormResponsePacket@@$0A@@@UEBAXAEBVNetworkIdentifier@@AEAVNetEventCallback@@AEAV?$shared_ptr@VPacket@@@std@@@Z", NetworkIdentifier* id, ServerNetworkHandler* handler, void* pPacket) { Packet* packet = *(Packet**)pPacket; ServerPlayer* sp = handler->getServerPlayer(*id, 0); if (sp) { string data; auto formId = dAccess(packet, 48); if (!dAccess(packet, 81)) { if (dAccess(packet, 72)) { auto json = dAccess(packet, 56); data = json.toStyledString(); } } if (data.empty()) { data = "null"; } if (data.back() == '\n') data.pop_back(); IF_LISTENED(FormResponsePacketEvent) { FormResponsePacketEvent ev{}; ev.mServerPlayer = sp; ev.mFormId = formId; ev.mJsonData = data; if (!ev.call()) return; } IF_LISTENED_END(FormResponsePacketEvent) HandleFormPacket(sp, formId, data); } original(this, id, handler, pPacket); } THook(void, "?_initialize@ResourcePackRepository@@AEAAXXZ", ResourcePackRepository* self) { Global = self; IF_LISTENED(ResourcePackInitEvent) { ResourcePackInitEvent ev{}; ev.mRepo = self; ev.call(); } IF_LISTENED_END(ResourcePackInitEvent) original(self); }