summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Bindings/Plugin.h2
-rw-r--r--src/Bindings/PluginLua.cpp50
-rw-r--r--src/Bindings/PluginLua.h2
-rw-r--r--src/Bindings/PluginManager.cpp36
-rw-r--r--src/Bindings/PluginManager.h4
-rw-r--r--src/Entities/Entity.cpp11
-rw-r--r--src/Entities/Player.cpp10
7 files changed, 115 insertions, 0 deletions
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index d0c2bcefa..b4bbfd802 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -56,6 +56,8 @@ public:
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0;
virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0;
+ virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) = 0;
+ virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) = 0;
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) = 0;
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) = 0;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index 76d3557a4..a8be26f71 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -534,6 +534,54 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E
+bool cPluginLua::OnEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
+{
+ cCSLock Lock(m_CriticalSection);
+ if (!m_LuaState.IsValid())
+ {
+ return false;
+ }
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGE_WORLD];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Entity, &a_World, cLuaState::Return, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+bool cPluginLua::OnEntityChangedWorld(cEntity & a_Entity, cWorld & a_World)
+{
+ cCSLock Lock(m_CriticalSection);
+ if (!m_LuaState.IsValid())
+ {
+ return false;
+ }
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGED_WORLD];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Entity, &a_World, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result)
{
cCSLock Lock(m_CriticalSection);
@@ -1884,6 +1932,8 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect";
case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation";
case cPluginManager::HOOK_ENTITY_ADD_EFFECT: return "OnEntityAddEffect";
+ case cPluginManager::HOOK_ENTITY_CHANGE_WORLD: return "OnEntityChangeWorld";
+ case cPluginManager::HOOK_ENTITY_CHANGED_WORLD: return "OnEntityChangedWorld";
case cPluginManager::HOOK_ENTITY_TELEPORT: return "OnEntityTeleport";
case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand";
case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake";
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index 524c249b0..533dc0331 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -115,6 +115,8 @@ public:
virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override;
+ virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) override;
+ virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) 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 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;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index db2493955..cc74c8372 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -525,6 +525,42 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d &
+bool cPluginManager::CallHookEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
+{
+ FIND_HOOK(HOOK_ENTITY_CHANGE_WORLD);
+ VERIFY_HOOK;
+
+ for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
+ {
+ if ((*itr)->OnEntityChangeWorld(a_Entity, a_World))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+bool cPluginManager::CallHookEntityChangedWorld(cEntity & a_Entity, cWorld & a_World)
+{
+ FIND_HOOK(HOOK_ENTITY_CHANGED_WORLD);
+ VERIFY_HOOK;
+
+ for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
+ {
+ if ((*itr)->OnEntityChangedWorld(a_Entity, a_World))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result)
{
FIND_HOOK(HOOK_EXECUTE_COMMAND);
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index d8c886b62..2c3eaa75f 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -85,6 +85,8 @@ public:
HOOK_DISCONNECT,
HOOK_PLAYER_ANIMATION,
HOOK_ENTITY_ADD_EFFECT,
+ HOOK_ENTITY_CHANGE_WORLD,
+ HOOK_ENTITY_CHANGED_WORLD,
HOOK_EXECUTE_COMMAND,
HOOK_EXPLODED,
HOOK_EXPLODING,
@@ -200,6 +202,8 @@ public:
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier);
bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition);
+ bool CallHookEntityChangeWorld (cEntity & a_Entity, cWorld & a_World);
+ bool CallHookEntityChangedWorld (cEntity & a_Entity, cWorld & a_World);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result); // If a_Player == nullptr, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 4a909a1fd..bc2b3e93e 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1403,14 +1403,25 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false;
}
+ // Ask the plugins if the entity is allowed to change the world
+ if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World))
+ {
+ // A Plugin doesn't allow the entity to change the world
+ return false;
+ }
+
// Remove all links to the old world
SetWorldTravellingFrom(GetWorld()); // cChunk::Tick() handles entity removal
GetWorld()->BroadcastDestroyEntity(*this);
// Queue add to new world
a_World->AddEntity(this);
+ cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD
SetWorld(a_World);
+ // Entity changed the world, call the hook
+ cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld);
+
return true;
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 607a663de..01ad26297 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1606,6 +1606,12 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false;
}
+ if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World))
+ {
+ // A Plugin doesn't allow the player to change the world
+ return false;
+ }
+
// Send the respawn packet:
if (a_ShouldSendRespawn && (m_ClientHandle != nullptr))
{
@@ -1621,6 +1627,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
// Queue adding player to the new world, including all the necessary adjustments to the object
a_World->AddPlayer(this);
+ cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD
SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
// Update the view distance.
@@ -1635,6 +1642,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
// Broadcast the player into the new world.
a_World->BroadcastSpawnEntity(*this);
+ // Player changed the world, call the hook
+ cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld);
+
return true;
}