From d82e2449a0282232c6e6acd1a84514ee5332f4db Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Mon, 9 Jul 2012 15:53:17 +0000 Subject: Improved Squirrel Bindings Added AddCommand / BindCommand for Squirrel Plugins git-svn-id: http://mc-server.googlecode.com/svn/trunk@652 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 2 +- source/Bindings.h | 2 +- source/cPluginManager.cpp | 23 +++-- source/cPluginManager.h | 8 +- source/cPlugin_Squirrel.cpp | 1 - source/cSquirrelCommandBinder.cpp | 98 ++++++++++++++++++++ source/cSquirrelCommandBinder.h | 35 ++++++++ source/squirrelbindings/SquirrelArray.h | 36 ++++++++ source/squirrelbindings/SquirrelBindings.cpp | 129 ++++++++++++++++++++++++++- source/squirrelbindings/cSquirrelBaseClass.h | 12 +++ 10 files changed, 334 insertions(+), 12 deletions(-) create mode 100644 source/cSquirrelCommandBinder.cpp create mode 100644 source/cSquirrelCommandBinder.h create mode 100644 source/squirrelbindings/SquirrelArray.h (limited to 'source') diff --git a/source/Bindings.cpp b/source/Bindings.cpp index cabd19661..2636f1336 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:12. +** Generated automatically by tolua++-1.0.92 on 07/09/12 09:01:54. */ #ifndef __cplusplus diff --git a/source/Bindings.h b/source/Bindings.h index 097fe7e64..4dd00606e 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:13. +** Generated automatically by tolua++-1.0.92 on 07/09/12 09:01:55. */ /* Exported function */ diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index 4cf21c850..99523183e 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -1,4 +1,3 @@ - #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "cPluginManager.h" @@ -10,6 +9,7 @@ #include "cItem.h" #include "cRoot.h" #include "cLuaCommandBinder.h" +#include "cSquirrelCommandBinder.h" #include "../iniFile/iniFile.h" #include "tolua++.h" @@ -38,6 +38,7 @@ cPluginManager* cPluginManager::GetPluginManager() cPluginManager::cPluginManager() : m_LuaCommandBinder( new cLuaCommandBinder() ) + , m_SquirrelCommandBinder( new cSquirrelCommandBinder() ) , m_bReloadPlugins(false) { } @@ -51,6 +52,7 @@ cPluginManager::~cPluginManager() UnloadPluginsNow(); delete m_LuaCommandBinder; + delete m_SquirrelCommandBinder; } @@ -130,7 +132,12 @@ void cPluginManager::ReloadPluginsNow() { LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); - this->AddPlugin(new cPlugin_Squirrel(PluginFile.c_str())); + cPlugin_Squirrel *Plugin = new cPlugin_Squirrel(PluginFile.c_str()); + + if( !AddPlugin( Plugin ) ) + { + delete Plugin; + } } } #endif // USE_SQUIRREL @@ -189,6 +196,11 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) cPlayer * Player = va_arg(argptr, cPlayer * ); va_end (argptr); + if (m_SquirrelCommandBinder->HandleCommand( std::string( Message ), Player)) + { + return true; + } + if (m_LuaCommandBinder->HandleCommand( std::string( Message ), Player)) { return true; @@ -644,13 +656,12 @@ void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false if( a_bDelete ) { m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin ); + m_SquirrelCommandBinder->RemoveBindingsForPlugin( a_Plugin ); m_Plugins.remove( a_Plugin ); RemoveHooks( a_Plugin ); a_Plugin->OnDisable(); - if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself! - { - delete a_Plugin; - } + + delete a_Plugin; } else { diff --git a/source/cPluginManager.h b/source/cPluginManager.h index e40b00dcf..2e50b2005 100644 --- a/source/cPluginManager.h +++ b/source/cPluginManager.h @@ -5,6 +5,7 @@ struct lua_State; class cLuaCommandBinder; +class cSquirrelCommandBinder; class cPlugin; class cPlugin_Lua; @@ -109,8 +110,10 @@ public: //tolua_export void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export void RemoveLuaPlugin( std::string a_FileName ); //tolua_export cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export - + cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; } + + cSquirrelCommandBinder* GetSquirrelCommandBinder() { return m_SquirrelCommandBinder; } bool HasPlugin( cPlugin* a_Plugin ) const; private: @@ -127,8 +130,9 @@ private: void ReloadPluginsNow(); void UnloadPluginsNow(); - + cLuaCommandBinder* m_LuaCommandBinder; + cSquirrelCommandBinder* m_SquirrelCommandBinder; bool m_bReloadPlugins; }; //tolua_export diff --git a/source/cPlugin_Squirrel.cpp b/source/cPlugin_Squirrel.cpp index aa7f7f023..892e8e433 100644 --- a/source/cPlugin_Squirrel.cpp +++ b/source/cPlugin_Squirrel.cpp @@ -13,7 +13,6 @@ cPlugin_Squirrel::cPlugin_Squirrel( const char* a_PluginName ) cPlugin_Squirrel::~cPlugin_Squirrel() { - delete m_PluginName; delete m_Plugin; } diff --git a/source/cSquirrelCommandBinder.cpp b/source/cSquirrelCommandBinder.cpp new file mode 100644 index 000000000..e2a34dfb6 --- /dev/null +++ b/source/cSquirrelCommandBinder.cpp @@ -0,0 +1,98 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSquirrelCommandBinder.h" +#include "cPlayer.h" +#include "cPlugin.h" +#include "cPlugin_Squirrel.h" +#include "squirrelbindings/SquirrelArray.h" + + +cSquirrelCommandBinder::cSquirrelCommandBinder() +{ +} + +cSquirrelCommandBinder::~cSquirrelCommandBinder() +{ +} + +void cSquirrelCommandBinder::ClearBindings() +{ + m_BoundCommands.clear(); +} + +void cSquirrelCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin ) +{ + for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); ) + { + if( itr->second.Plugin == a_Plugin ) + { + LOGINFO("Unbinding %s ", itr->first.c_str( ) ); + CommandMap::iterator eraseme = itr; + ++itr; + m_BoundCommands.erase( eraseme ); + continue; + } + ++itr; + } +} + +bool cSquirrelCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, Sqrat::Function a_Callback ) +{ + if( !a_Plugin->CanBindCommands() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() ); + return false; + } + if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() ); + return false; + } + LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() ); + + BoundFunction Callback; + Callback.Callback = a_Callback; + Callback.Plugin = a_Plugin; + Callback.Permission = a_Permission; + + m_BoundCommands[ a_Command ] = Callback; + return true; +} + +bool cSquirrelCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player ) +{ + AStringVector Split = StringSplit(a_Command, " "); + if (Split.size() == 0) + { + return false; + } + + CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] ); + if( FoundCommand != m_BoundCommands.end() ) + { + const BoundFunction & func = FoundCommand->second; + if( func.Permission.size() > 0 ) + { + if( !a_Player->HasPermission( func.Permission.c_str() ) ) + { + return false; + } + } + + + // Push the split + SquirrelStringArray SplitData; + + std::vector::const_iterator iter = Split.begin(); + while(iter != Split.end()) { + SplitData.Add(*iter); + ++iter; + } + + // Push player + Sqrat::Function callback = func.Callback; + return callback.Evaluate(&SplitData, a_Player); + } + return false; +} diff --git a/source/cSquirrelCommandBinder.h b/source/cSquirrelCommandBinder.h new file mode 100644 index 000000000..50e026d06 --- /dev/null +++ b/source/cSquirrelCommandBinder.h @@ -0,0 +1,35 @@ +#pragma once +#include +#include + +class cPlugin; +class cPlayer; + +class cSquirrelCommandBinder +{ +public: + cSquirrelCommandBinder(); + ~cSquirrelCommandBinder(); + + bool HandleCommand( const std::string & a_Command, cPlayer* a_Player ); + + bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, Sqrat::Function a_Callback); + + void ClearBindings(); + void RemoveBindingsForPlugin( cPlugin* a_Plugin ); +private: + struct BoundFunction + { + Sqrat::Function Callback; + cPlugin *Plugin; + std::string Permission; + }; + + typedef std::map< std::string, BoundFunction > CommandMap; + CommandMap m_BoundCommands; +}; + + + + + diff --git a/source/squirrelbindings/SquirrelArray.h b/source/squirrelbindings/SquirrelArray.h new file mode 100644 index 000000000..0c2e34f7f --- /dev/null +++ b/source/squirrelbindings/SquirrelArray.h @@ -0,0 +1,36 @@ +#pragma once +#include + +template +class SquirrelArray +{ +public: + SquirrelArray() + { + } + + unsigned int Size() + { + return m_Values.size(); + } + + T Get(unsigned int a_Index) + { + if(m_Values.size() < a_Index) + { + return T(); + } + return m_Values.at(a_Index); + } + + void Add(T a_Value) + { + m_Values.push_back(a_Value); + } + +protected: + std::vector m_Values; + +}; + +class SquirrelStringArray : public SquirrelArray { }; \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelBindings.cpp b/source/squirrelbindings/SquirrelBindings.cpp index 27a82c306..f0291b39b 100644 --- a/source/squirrelbindings/SquirrelBindings.cpp +++ b/source/squirrelbindings/SquirrelBindings.cpp @@ -3,6 +3,7 @@ #include "SquirrelFunctions.h" #include "cSquirrelBaseClass.h" +#include "SquirrelArray.h" #include "../cPlayer.h" @@ -15,9 +16,135 @@ void BindSquirrel(HSQUIRRELVM vm) RootTable() .Bind("Plugin", Class() .Func("AddHook", &cSquirrelBaseClass::AddHook) + .Func("AddCommand", &cSquirrelBaseClass::AddCommand) + .Func("BindCommand", &cSquirrelBaseClass::BindCommand) ); - RootTable().Bind("cPlayer", Class() + + RootTable().Bind("Vector3f", Class() + .Func("Set", &Vector3f::Set) + .Func("Normalize", &Vector3f::Normalize) + .Func("Length", &Vector3f::Length) + .Func("SqrLength", &Vector3f::SqrLength) + .Var("x", &Vector3f::x) + .Var("y", &Vector3f::y) + .Var("z", &Vector3f::z) + ); + + RootTable().Bind("Vector3d", Class() + .Func("Set", &Vector3d::Set) + .Func("Normalize", &Vector3d::Normalize) + .Func("Length", &Vector3d::Length) + .Func("SqrLength", &Vector3d::SqrLength) + .Var("x", &Vector3d::x) + .Var("y", &Vector3d::y) + .Var("z", &Vector3d::z) + ); + + RootTable().Bind("cEntity", Class() + .Func("GetEntityType", &cEntity::GetEntityType) + .Func("IsA", &cEntity::IsA) + .Func("GetWorld", &cEntity::GetWorld) + .Func("GetPosition", &cEntity::GetPosition) + .Func("GetPosX", &cEntity::GetPosX) + .Func("GetPosY", &cEntity::GetPosY) + .Func("GetPosZ", &cEntity::GetPosZ) + .Func("GetRot", &cEntity::GetRot) + .Func("GetRotation", &cEntity::GetRotation) + .Func("GetPitch", &cEntity::GetPitch) + .Func("GetRoll", &cEntity::GetRoll) + .Func("SetRotation", &cEntity::SetRotation) + .Func("SetPitch", &cEntity::SetPitch) + .Func("SetRoll", &cEntity::SetRoll) + .Func("GetLookVector", &cEntity::GetLookVector) + .Func("GetChunkX", &cEntity::GetChunkX) + .Func("GetChunkY", &cEntity::GetChunkY) + .Func("GetChunkZ", &cEntity::GetChunkZ) + .Func("SetPosX", &cEntity::SetPosX) + .Func("SetPosY", &cEntity::SetPosY) + .Func("SetPosZ", &cEntity::SetPosZ) + .Func("SetPosition", &cEntity::SetPosition) + .Func("GetUniqueID", &cEntity::GetUniqueID) + .Func("IsDestroyed", &cEntity::IsDestroyed) + .Func("Destroy", &cEntity::Destroy) + .Func("SpawnOn", &cEntity::SpawnOn) + + ); + + ConstTable().Enum("MetaData", Enumeration() + .Const("Normal", cPawn::NORMAL) + .Const("Burning", cPawn::BURNING) + .Const("Crouched", cPawn::CROUCHED) + .Const("Riding", cPawn::RIDING) + .Const("Sprinting", cPawn::SPRINTING) + .Const("Eating", cPawn::EATING) + .Const("Blocking", cPawn::BLOCKING) + ); + + RootTable().Bind("cPawn", DerivedClass() + .Func("TeleportToEntity", &cPawn::TeleportToEntity) + .Func("TeleportTo", &cPawn::TeleportTo) + .Func("Heal", &cPawn::Heal) + .Func("TakeDamage", &cPawn::TakeDamage) + .Func("KilledBy", &cPawn::KilledBy) + .Func("GetHealth", &cPawn::GetHealth) + .Func("SetMetaData", &cPawn::SetMetaData) + .Func("GetMetaData", &cPawn::GetMetaData) + .Func("SetMaxHealth", &cPawn::SetMaxHealth) + .Func("GetMaxHealth", &cPawn::GetMaxHealth) + .Func("GetMaxFood", &cPawn::GetMaxFood) + .Func("GetFood", &cPawn::GetFood) + .Func("GetMaxFoodSaturation", &cPawn::GetMaxFoodSaturation) + .Func("GetFoodSaturation", &cPawn::GetFoodSaturation) + .Func("SetMaxFoodLevel", &cPawn::SetMaxFoodLevel) + .Func("GetMaxFoodLevel", &cPawn::SetMaxFoodLevel) + ); + + RootTable().Bind("cPlayer", DerivedClass() .Func("GetName", &cPlayer::GetName) + .Func("SetTouchGround", &cPlayer::SetTouchGround) + .Func("SetStance", &cPlayer::SetStance) + .Func("GetEyeHeight", &cPlayer::GetEyeHeight) + .Func("GetEyePosition", &cPlayer::GetEyePosition) + .Func("GetFlying", &cPlayer::GetFlying) + .Func("GetStance", &cPlayer::GetStance) + //TODO .Func("GetInventory", &cPlayer::GetInventory) + .Func("TeleportTo", &cPlayer::TeleportTo) + .Func("GetGameMode", &cPlayer::GetGameMode) + .Func("GetIP", &cPlayer::GetIP) + .Func("GetLastBlockActionTime", &cPlayer::GetLastBlockActionTime) + .Func("GetLastBlockActionCnt", &cPlayer::GetLastBlockActionCnt) + .Func("SetLastBlockActionCnt", &cPlayer::SetLastBlockActionCnt) + .Func("SetLastBlockActionTime", &cPlayer::SetLastBlockActionTime) + .Func("SetGameMode", &cPlayer::SetGameMode) + .Func("LoginSetGameMode", &cPlayer::LoginSetGameMode) + .Func("SetIP", &cPlayer::SetIP) + .Func("MoveTo", &cPlayer::MoveTo) + .Func("GetClientHandle", &cPlayer::GetClientHandle) + .Func("SendMessage", &cPlayer::SendMessage) + .Func("AddToGroup", &cPlayer::AddToGroup) + .Func("CanUseCommand", &cPlayer::CanUseCommand) + .Func("HasPermission", &cPlayer::HasPermission) + .Func("IsInGroup", &cPlayer::IsInGroup) + .Func("GetColor", &cPlayer::GetColor) + .Func("TossItem", &cPlayer::TossItem) + .Func("Heal", &cPlayer::Heal) + .Func("Feed", &cPlayer::Feed) + .Func("TakeDamage", &cPlayer::TakeDamage) + .Func("KilledBy", &cPlayer::KilledBy) + .Func("Respawn", &cPlayer::Respawn) + .Func("SetVisible", &cPlayer::SetVisible) + .Func("IsVisible", &cPlayer::IsVisible) + .Func("MoveToWorld", &cPlayer::MoveToWorld) + .Func("GetLoadedWorldName", &cPlayer::GetLoadedWorldName) + .Func("UseEquippedItem", &cPlayer::UseEquippedItem) + .Func("EatItem", &cPlayer::EatItem) + + ); + + RootTable().Bind("StringArray", Class() + .Func("Get", &SquirrelStringArray::Get) + .Func("Add", &SquirrelStringArray::Add) + .Func("Size", &SquirrelStringArray::Size) ); diff --git a/source/squirrelbindings/cSquirrelBaseClass.h b/source/squirrelbindings/cSquirrelBaseClass.h index a66ca7ddd..279c47027 100644 --- a/source/squirrelbindings/cSquirrelBaseClass.h +++ b/source/squirrelbindings/cSquirrelBaseClass.h @@ -3,6 +3,7 @@ #include "../cPlugin_Squirrel.h" #include "../cPluginManager.h" #include "../cRoot.h" +#include "../cSquirrelCommandBinder.h" //The baseclass for squirrel plugins class cSquirrelBaseClass @@ -24,6 +25,17 @@ public: cRoot::Get()->GetPluginManager()->AddHook(m_Instance, (cPluginManager::PluginHook) a_Hook); } + void AddCommand( std::string a_Command, std::string a_Description, std::string a_Permission ) + { + if(m_Instance) m_Instance->AddCommand(a_Command, a_Description, a_Permission); + } + + bool BindCommand( const std::string a_Command, const std::string a_Permission, Sqrat::Function a_Callback) + { + if(!m_Instance) return false; + return cRoot::Get()->GetPluginManager()->GetSquirrelCommandBinder()->BindCommand(a_Command, a_Permission, m_Instance, a_Callback); + } + protected: cPlugin_Squirrel *m_Instance; }; \ No newline at end of file -- cgit v1.2.3