Skip to content

Previous: ../02-ๆœไธปๆŒ‡ๅ—/่ฏŠๆ–ญไธŽๆŽ’้”™.mdใ€€ยทใ€€Next: ็‰ฉๅ“็ฑปๆ’ไปถ.md Related: ็‰ฉๅ“็ฑปๆ’ไปถ.md ยท ๆ–นๅ—ๆจกๅž‹ไฝœ็‰ฉ.md ยท ็ปๆตŽๆ’ไปถ.md ยท ../02-ๆœไธปๆŒ‡ๅ—/็‰ฉๅ“ๆบๅผ•็”จ.md

๐Ÿงฉ External Plugin Integration ยท Overview โ€‹

QinhCoreLib (QCL) can cooperate with a large set of third-party plugins on the server: it lets items from other plugins be referenced uniformly by QI/GUI/CustomBlock/API, and lets capabilities like blocks, models, crops, and economy be reused directly. This page explains the design philosophy of the integration, how to confirm it's connected, and provides a master matrix of all plugins. Per-plugin details are spread across three sub-pages.


๐Ÿ›Ÿ Design philosophy: soft dependency + reflection bridge, skip if not installed โ€‹

QCL follows the same set of rules for integration with all third-party plugins, which can be summed up in three sentences:

PrincipleMeaning
Soft dependency (softdepend)QCL does not hard-depend on any third-party plugin. It starts up normally even if none are installed, and never reports "missing dependency" and refuses to load.
Reflection bridgeQCL does not import third-party plugin classes at compile time; instead it calls them at runtime via reflection. This way, even if the other plugin isn't installed or has changed versions, QCL itself won't crash because it "can't find a class".
Degrade rather than crashWhen the corresponding plugin isn't installed, the bridge's isAvailable() returns false, and each capability method returns null / false. The caller gets an empty result and treats it as "that item source is unavailable", rather than throwing an exception and blowing up the server.

๐Ÿ’ก In one sentence: installed = automatically connected, not installed = silently skipped. You don't need to delete config or change anything just because "I haven't installed some plugin".

๐Ÿ”Œ When is a bridge probed? โ€‹

Each bridge probes once when its corresponding module loads (detecting whether the target class exists and whether the key methods can be reflected). On a successful probe, it is registered as hookedBridge in the startup summary and written into the BridgeStatusRegistry.

text
# In the startup summary you'll see "hooked bridge" entries like these
hookedBridge: MMOItems
hookedBridge: CraftEngine
hookedBridge: Vault

๐Ÿ” How to confirm it's connected โ€‹

After installing the third-party plugin and restarting the server, one command confirms it:

text
/qcl status detail

This detailed status lists the integration situation bridge by bridge, read from the BridgeStatusRegistry. You should pay attention to:

What you want to confirmWhere to look
Whether a given bridge is availableThe isAvailable status on that bridge's row
Whether MythicMobs is connecting to the modern or legacy versionThe bindMode in that bridge's diagnostics (dual binding, detailed on the items page below)
Which economy backend was actually chosenThe economy-related row + the economy.default-provider config

โš ๏ธ If you've installed a plugin but its bridge still shows as unavailable in /qcl status detail:

  1. Confirm the third-party plugin itself loaded successfully first (check its own startup log).
  2. Confirm the plugin version didn't drastically change class names โ€” the reflection bridge does its best for multi-version compatibility, but in extreme cases the probe can still fail.
  3. Reload with /qcl reload and check again (a reload refreshes the external item modules).

๐Ÿ—บ๏ธ Master matrix of all plugins โ€‹

The table below covers all third-party plugins QCL currently integrates with โ€” item types, block/model/crop types, and economy types.

๐ŸŽ’ Items (provide item-fetching capability, paired with unified item source references) โ€‹

PluginBridge classReference prefixMain capability
MMOItemsMMOItemsBridgemi-type-idFetch item by "type + id"
NeigeItemsNeigeItemsBridgeni-idFetch item by id
MythicMobsMythicMobsBridgemm-idFetch item by id (amount optional)
MagicGemMagicGemBridgemg-idFetch gem item, check whether a gem exists
CustomFishingCustomFishingBridgecf-idBuild item (amount optional)
ItemsAdderItemsAdderBridgeia-namespace_idBuild item stack
NexoNexoBridgenx-idBuild item stack
CraftEngineCraftEngineBridgece-namespace_idBuild item + block/furniture (see blocks page)
QinhItemsinternal QinhItemsItemSourceqi:idReflect QinhItemRegistry.create(id, amount)

These bridges let the corresponding items be referenced by QI / GUI / CustomBlock / API through the unified reference syntax. For per-plugin details see ๐Ÿ‘‰ ็‰ฉๅ“็ฑปๆ’ไปถ.md.

๐Ÿงฑ Blocks / models / crops โ€‹

PluginBridge classPurpose
CraftEngineCraftEngineBridge / CraftEngineManagerCustom items / block-placement recognition / furniture-placement recognition
(abstraction layer)CustomBlockBridge + CustomBlockProviderA unified "custom block" abstraction, with a built-in CraftEngine provider
ModelEngineModelEngineBridge / ManagerModeled entities, playing animations, bone item-holding
CustomCropsCustomCropsBridge / ManagerCrop recognition / harvest / planting / growth / bone meal

For details see ๐Ÿ‘‰ ๆ–นๅ—ๆจกๅž‹ไฝœ็‰ฉ.md.

๐Ÿ’ฐ Economy โ€‹

Backendprovider idCurrency modelImplementation
VaultvaultSingle currencyObtained via service registration
ExcellentEconomyexcellenteconomy (ee)Multiple currenciesReflection API
PlayerPointsplayerpoints (pp)Single point currency (integer)Reflection API

All managed uniformly by EconomyBridge, which registers the "installed and enabled" backends in order. For details see ๐Ÿ‘‰ ็ปๆตŽๆ’ไปถ.md.


๐Ÿงฐ The shared compatibility base: ReflectionBridge โ€‹

All bridges achieve "multi-version compatibility, no crash on missing class" thanks to a common underlying set of reflection utilities:

  • ReflectionBridge: isClassAvailable(className) โ€” determines whether a given class exists in the current runtime environment (the first step of a bridge probe).
  • ReflectionCache: caches method/field lookups to avoid repeated reflection overhead, providing utilities like getClazz / getMethod / getDeclaredMethod / findMethodByName / getField / findFieldInHierarchy / invoke / invokeStatic / get / set / safeCall.

Precisely because of this wrapper layer, a bridge can still find the correct method signature when "different major versions of the same plugin have different class names". For the developer-side details see ../04-ๅผ€ๅ‘่€…/ๅทฅๅ…ท้›†.md.


โœ… Standard procedure for integrating a third-party plugin โ€‹

  1. Install the third-party plugin normally (confirm it can load on its own).
  2. Restart the server (or start QCL first, then /qcl reload).
  3. Run /qcl status detail, and confirm the corresponding bridge's isAvailable is true and that there's a hookedBridge entry in the startup summary.
  4. Items: go to ็‰ฉๅ“ๆบๅผ•็”จ.md and try referencing with the corresponding prefix; blocks/models/crops: see the corresponding page; economy: configure economy.default-provider then verify via a GUI economy action or the API.

๐Ÿ“š Continue reading โ€‹