11 #define LUA_USE_MACOSX
17 #include "../CommandOutput.h"
21 #include "../WebAdmin.h"
25 #include "lua/src/lauxlib.h"
28 #undef TOLUA_TEMPLATE_BIND
29 #include "tolua++/include/tolua++.h"
40 m_LuaState(
fmt::format(FMT_STRING(
"plugin {}"), a_PluginDirectory)),
41 m_DeadlockDetect(a_DeadlockDetect)
104 tolua_pushusertype(
m_LuaState,
this,
"cPluginLua");
113 bool HasInfoLua =
false;
114 for (AStringVector::const_iterator itr = Files.begin(), end = Files.end(); itr != end; ++itr)
116 size_t ExtensionStart = itr->find_last_of(
'.');
117 if ((ExtensionStart != std::string::npos) && (itr->substr(ExtensionStart) ==
".lua"))
119 if (*itr ==
"Info.lua")
125 LuaFiles.push_back(*itr);
129 std::sort(LuaFiles.begin(), LuaFiles.end());
132 if (LuaFiles.empty())
134 SetLoadError(
"No lua files found, plugin is probably missing.");
141 for (AStringVector::const_iterator itr = LuaFiles.begin(), end = LuaFiles.end(); itr != end; ++itr)
143 AString Path = PluginPath + *itr;
146 SetLoadError(fmt::format(FMT_STRING(
"Failed to load file {}."), *itr));
153 AString Path = PluginPath +
"Info.lua";
167 LOGWARNING(
"Error in plugin %s: Cannot call the Initialize() function. Plugin is temporarily disabled.",
GetName().c_str());
174 LOGINFO(
"Plugin %s: Initialize() call failed, plugin is temporarily disabled.",
GetName().c_str());
201 if (!op().HasFunction(
"OnDisable"))
205 op().Call(
"OnDisable");
236 const cItem * a_Tool,
245 a_BlockPos.
x, a_BlockPos.
y, a_BlockPos.
z,
246 a_BlockType, a_BlockMeta, &a_Pickups
281 for (
auto & hook: hooks)
404 for (
auto & hook: hooks)
406 hook->Call(a_Player, a_Split, a_EntireCommand,
cLuaState::Return, res, a_Result);
428 for (
auto & hook: hooks)
432 case esBed: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<Vector3i *
> (a_SourceData),
cLuaState::Return, res);
break;
435 case esMonster: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cMonster *
> (a_SourceData),
cLuaState::Return, res);
break;
436 case esOther: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
cLuaState::Return, res);
break;
437 case esPlugin: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
cLuaState::Return, res);
break;
444 ASSERT(!
"Invalid explosion source");
469 for (
auto & hook: hooks)
473 case esBed: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<Vector3i *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
474 case esEnderCrystal: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cEntity *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
475 case esGhastFireball: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cGhastFireballEntity *
>(a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
476 case esMonster: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cMonster *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
477 case esOther: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
478 case esPlugin: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
479 case esPrimedTNT: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cTNTEntity *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
480 case esTNTMinecart: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cMinecartWithTNT *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
481 case esWitherBirth: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cMonster *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
482 case esWitherSkull: hook->Call(&a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source,
static_cast<cWitherSkullEntity *
> (a_SourceData),
cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize);
break;
485 ASSERT(!
"Invalid explosion source");
546 for (
auto & hook: hooks)
548 hook->Call(&a_Victim, &a_TDI, a_DeathMessage,
cLuaState::Return, res, a_DeathMessage);
710 a_BlockChange.
GetX(), a_BlockChange.
GetY(), a_BlockChange.
GetZ(),
723 a_BlockChange.
GetX(), a_BlockChange.
GetY(), a_BlockChange.
GetZ(),
789 return CallSimpleHooks(
cPluginManager::HOOK_PLAYER_USED_BLOCK, &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta);
807 return CallSimpleHooks(
cPluginManager::HOOK_PLAYER_USING_BLOCK, &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta);
841 for (
auto & hook: hooks)
899 for (
auto & hook: hooks)
901 hook->Call(&a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon,
cLuaState::Return, res, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon);
961 int a_BlockX,
int a_BlockY,
int a_BlockZ,
975 int a_BlockX,
int a_BlockY,
int a_BlockZ,
987 for (
auto & hook: hooks)
989 hook->Call(&a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player,
cLuaState::Return, res, a_Line1, a_Line2, a_Line3, a_Line4);
1014 if (!op().IsValid())
1020 for (
auto & hook: hooks)
1056 if (FnName ==
nullptr)
1059 LOGWARNING(
"Plugin %s wants to add an unknown hook ID (%d). The plugin need not work properly.",
1072 LOGWARNING(
"Plugin %s wants to add a hook (%d), but it doesn't provide the callback function \"%s\" for it. The plugin need not work properly.",
1073 GetName().c_str(), a_HookType, FnName
1152 ASSERT(!
"Unknown hook requested!");
1162 m_HookMap[a_HookType].push_back(std::move(a_Callback));
1171 const AString & a_FunctionName,
1180 int NumReturns = op().CallFunctionWithForeignParams(a_FunctionName, a_ForeignState, a_ParamStart, a_ParamEnd);
1207 if (webAdmin !=
nullptr)
#define LUA_PLUGIN_INSTANCE_VAR_NAME
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
eExplosionSource
The source of an explosion.
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
std::basic_string_view< std::byte > ContiguousByteBufferView
void LOGWARNING(std::string_view a_Format, const Args &... args)
void LOGINFO(std::string_view a_Format, const Args &... args)
std::vector< AString > AStringVector
std::map< AString, AString > AStringMap
A string dictionary, used for key-value pairs.
Implements custom fmtlib formatting for cChunkCoords.
Encapsulates a Lua state and provides some syntactic sugar for common operations.
void AddPackagePath(const AString &a_PathVariable, const AString &a_Path)
Adds the specified path to package.
void LogStackTrace(int a_StartingDepth=0)
Logs all items in the current stack trace to the server console.
std::unique_ptr< cCallback > cCallbackPtr
bool Call(const FnT &a_Function, Args &&... args)
Call the specified Lua function.
bool HasFunction(const char *a_FunctionName)
Returns true if a_FunctionName is a valid Lua function that can be called.
bool LoadFile(const AString &a_FileName, bool a_LogWarnings=true)
Loads the specified file Returns false and optionally logs a warning to the console if not successful...
void RegisterAPILibs(void)
Registers all the API libraries that MCS provides into m_LuaState.
int CopyStackFrom(cLuaState &a_SrcLuaState, int a_SrcStart, int a_SrcEnd, int a_NumAllowedNestingLevels=16)
Copies objects on the stack from the specified state.
void UntrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect)
Removes this object's CS from the DeadlockDetect's tracked CSs.
void TrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect)
Adds this object's CS to the DeadlockDetect's tracked CSs.
void Create(void)
Creates the m_LuaState, if not created already.
AString m_Name
The name of the plugin, used to identify the plugin in the system and for inter-plugin calls.
AString GetLocalFolder(void) const
Returns the folder relative to the MCS Executable, from which the plugin is loaded.
const AString & GetName(void) const
cPluginManager::ePluginStatus m_Status
virtual void Unload(void)
Unloads the plugin.
void SetLoadError(const AString &a_LoadError)
Sets m_LoadError to the specified string and m_Status to psError.
virtual bool OnPlayerFished(cPlayer &a_Player, const cItems &a_Reward, const int ExperienceAmount) override
virtual bool OnChat(cPlayer &a_Player, AString &a_Message) override
virtual bool OnExploded(cWorld &a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void *a_SourceData) override
virtual bool OnSpawningMonster(cWorld &a_World, cMonster &a_Monster) override
virtual bool OnChunkAvailable(cWorld &a_World, int a_ChunkX, int a_ChunkZ) override
bool CanAddOldStyleHook(int a_HookType)
Returns true if the plugin contains the function for the specified hook type, using the old-style reg...
virtual void Tick(float a_Dt) override
virtual bool OnPostCrafting(cPlayer &a_Player, cCraftingGrid &a_Grid, cCraftingRecipe &a_Recipe) override
virtual bool OnWorldStarted(cWorld &a_World) override
virtual bool OnChunkGenerated(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc) override
virtual bool OnLogin(cClientHandle &a_Client, UInt32 a_ProtocolVersion, const AString &a_Username) override
virtual bool OnPlayerMoving(cPlayer &a_Player, const Vector3d &a_OldPosition, const Vector3d &a_NewPosition, bool a_PreviousIsOnGround) override
virtual bool OnSpawnedEntity(cWorld &a_World, cEntity &a_Entity) override
virtual bool OnPlayerDestroyed(cPlayer &a_Player) override
void Close(void)
Releases all Lua references, notifies and removes all m_Resettables[] and closes the m_LuaState.
virtual bool OnCollectingPickup(cPlayer &a_Player, cPickup &a_Pickup) override
static const char * GetHookFnName(int a_HookType)
Returns the name of Lua function that should handle the specified hook type in the older (#121) API.
virtual bool OnKilled(cEntity &a_Victim, TakeDamageInfo &a_TDI, AString &a_DeathMessage) override
virtual ~cPluginLua() override
virtual void OnDisable(void) override
Called as the last call into the plugin before it is unloaded.
bool AddHookCallback(int a_HookType, cLuaState::cCallbackPtr &&a_Callback)
Adds a Lua callback to be called for the specified hook.
virtual bool OnDisconnect(cClientHandle &a_Client, const AString &a_Reason) override
virtual bool OnPlayerSpawned(cPlayer &a_Player) override
virtual bool OnPreCrafting(cPlayer &a_Player, cCraftingGrid &a_Grid, cCraftingRecipe &a_Recipe) override
virtual bool OnPluginsLoaded(void) override
virtual bool OnSpawnedMonster(cWorld &a_World, cMonster &a_Monster) override
virtual bool OnPlayerRightClickingEntity(cPlayer &a_Player, cEntity &a_Entity) override
virtual bool OnKilling(cEntity &a_Victim, cEntity *a_Killer, TakeDamageInfo &a_TDI) override
virtual bool OnWeatherChanging(cWorld &a_World, eWeather &a_NewWeather) override
virtual bool OnServerPing(cClientHandle &a_ClientHandle, AString &a_ServerDescription, int &a_OnlinePlayersCount, int &a_MaxPlayersCount, AString &a_Favicon) override
virtual bool OnBrewingCompleting(cWorld &a_World, cBrewingstandEntity &a_BrewingstandEntity) override
int CallFunctionFromForeignState(const AString &a_FunctionName, cLuaState &a_ForeignState, int a_ParamStart, int a_ParamEnd)
Calls a function in this plugin's LuaState with parameters copied over from a_ForeignState.
virtual bool OnExploding(cWorld &a_World, double &a_ExplosionSize, bool &a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void *a_SourceData) override
virtual bool OnPlayerJoined(cPlayer &a_Player) override
virtual bool OnHopperPushingItem(cWorld &a_World, cHopperEntity &a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems &a_DstEntity, int a_DstSlotNum) override
virtual bool OnPlayerOpeningWindow(cPlayer &a_Player, cWindow &a_Window) override
virtual bool OnPlayerAnimation(cPlayer &a_Player, int a_Animation) override
virtual bool OnPlayerUsedItem(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
virtual bool OnUpdatedSign(cWorld &a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4, cPlayer *a_Player) override
virtual bool OnEntityChangedWorld(cEntity &a_Entity, cWorld &a_World) override
virtual bool OnPlayerBrokenBlock(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
virtual bool OnLoginForge(cClientHandle &a_Client, const AStringMap &a_Mods) override
virtual bool OnPluginMessage(cClientHandle &a_Client, const AString &a_Channel, ContiguousByteBufferView a_Message) override
virtual bool OnPlayerUsingItem(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
cPluginLua(const AString &a_PluginDirectory, cDeadlockDetect &a_DeadlockDetect)
virtual bool OnHopperPullingItem(cWorld &a_World, cHopperEntity &a_Hopper, int a_DstSlotNum, cBlockEntityWithItems &a_SrcEntity, int a_SrcSlotNum) override
cLuaState m_LuaState
The plugin's Lua state.
virtual bool OnEntityAddEffect(cEntity &a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override
virtual bool OnSpawningEntity(cWorld &a_World, cEntity &a_Entity) override
virtual bool OnPlayerFoodLevelChange(cPlayer &a_Player, int a_NewFoodLevel) override
virtual bool OnProjectileHitEntity(cProjectileEntity &a_Projectile, cEntity &a_HitEntity) override
virtual bool OnPlayerEating(cPlayer &a_Player) override
bool CallSimpleHooks(int a_HookType, Args &&... a_Args)
Calls a hook that has the simple format - single bool return value specifying whether the chain shoul...
virtual bool OnBlockToPickups(cWorld &a_World, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cBlockEntity *a_BlockEntity, const cEntity *a_Digger, const cItem *a_Tool, cItems &a_Pickups) override
virtual bool OnPlayerUsedBlock(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
virtual bool OnChunkUnloading(cWorld &a_World, int a_ChunkX, int a_ChunkZ) override
virtual bool OnPlayerShooting(cPlayer &a_Player) override
virtual bool OnChunkUnloaded(cWorld &a_World, int a_ChunkX, int a_ChunkZ) override
virtual bool OnPlayerUsingBlock(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
virtual bool OnHandshake(cClientHandle &a_Client, const AString &a_Username) override
virtual bool OnEntityChangingWorld(cEntity &a_Entity, cWorld &a_World) override
virtual bool OnPlayerPlacingBlock(cPlayer &a_Player, const sSetBlock &a_BlockChange) override
virtual bool OnPlayerBreakingBlock(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
virtual bool OnEntityTeleport(cEntity &a_Entity, const Vector3d &a_OldPosition, const Vector3d &a_NewPosition) override
virtual bool OnProjectileHitBlock(cProjectileEntity &a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d &a_BlockHitPos) override
virtual bool OnExecuteCommand(cPlayer *a_Player, const AStringVector &a_Split, const AString &a_EntireCommand, cPluginManager::CommandResult &a_Result) override
void ClearWebTabs(void)
Removes all WebTabs currently registered for this plugin from the WebAdmin.
virtual bool OnCraftingNoRecipe(cPlayer &a_Player, cCraftingGrid &a_Grid, cCraftingRecipe &a_Recipe) override
virtual bool OnWeatherChanged(cWorld &a_World) override
virtual bool OnPlayerFishing(cPlayer &a_Player, cItems &a_Reward, int &ExperienceAmount) override
virtual bool OnChunkGenerating(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc) override
virtual bool OnUpdatingSign(cWorld &a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString &a_Line1, AString &a_Line2, AString &a_Line3, AString &a_Line4, cPlayer *a_Player) override
virtual bool OnPlayerCrouched(cPlayer &a_Player) override
virtual bool Load(void) override
Loads and initializes the plugin.
virtual bool OnPlayerLeftClick(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status) override
cDeadlockDetect & m_DeadlockDetect
The DeadlockDetect object to which the plugin's CS is tracked.
virtual bool OnTakeDamage(cEntity &a_Receiver, TakeDamageInfo &a_TakeDamageInfo) override
virtual bool OnBlockSpread(cWorld &a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override
Calls the specified hook with the params given.
cHookMap m_HookMap
Hooks that the plugin has registered.
virtual bool OnPlayerPlacedBlock(cPlayer &a_Player, const sSetBlock &a_BlockChange) override
virtual bool OnWorldTick(cWorld &a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) override
virtual bool OnPlayerRightClick(cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
virtual void Unload(void) override
Unloads the plugin.
virtual bool OnBrewingCompleted(cWorld &a_World, cBrewingstandEntity &a_BrewingstandEntity) override
virtual bool OnDropSpense(cWorld &a_World, cDropSpenserEntity &a_DropSpenser, int a_SlotNum) override
virtual bool OnPlayerTossingItem(cPlayer &a_Player) override
A RAII-style mutex lock for accessing the internal LuaState.
@ HOOK_PLAYER_RIGHT_CLICK
@ HOOK_PLAYER_OPENING_WINDOW
@ HOOK_PROJECTILE_HIT_ENTITY
@ HOOK_HOPPER_PUSHING_ITEM
@ HOOK_ENTITY_CHANGING_WORLD
@ HOOK_PLAYER_TOSSING_ITEM
@ HOOK_ENTITY_CHANGED_WORLD
@ HOOK_PLAYER_USING_BLOCK
@ HOOK_PROJECTILE_HIT_BLOCK
@ HOOK_PLAYER_RIGHT_CLICKING_ENTITY
@ HOOK_HOPPER_PULLING_ITEM
@ HOOK_PLAYER_PLACING_BLOCK
@ HOOK_PLAYER_BREAKING_BLOCK
@ HOOK_PLAYER_PLACED_BLOCK
@ HOOK_BREWING_COMPLETING
@ HOOK_PLAYER_BROKEN_BLOCK
@ HOOK_CRAFTING_NO_RECIPE
@ HOOK_PLAYER_FOOD_LEVEL_CHANGE
@ psLoaded
The plugin has been loaded successfully.
int GetX(void) const
Returns the absolute X coord of the stored block.
int GetY(void) const
Returns the absolute Y coord of the stored block.
int GetZ(void) const
Returns the absolute Z coord of the stored block.
This class bridges a vector of cItem for safe access via Lua.
static AStringVector GetFolderContents(const AString &a_Folder)
Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there).
cWebAdmin * GetWebAdmin(void)
void RemoveAllPluginWebTabs(const AString &a_PluginName)
Removes all WebTabs registered by the specified plugin.