diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/AllToLua.pkg | 2 | ||||
-rw-r--r-- | source/Bindings.cpp | 4 | ||||
-rw-r--r-- | source/Bindings.h | 2 | ||||
-rw-r--r-- | source/_OLD_SquirrelBindings.cpp (renamed from source/SquirrelBindings.cpp) | 280 | ||||
-rw-r--r-- | source/_OLD_SquirrelBindings.h (renamed from source/SquirrelBindings.h) | 30 | ||||
-rw-r--r-- | source/cBlockArea.cpp (renamed from source/BlockArea.cpp) | 2 | ||||
-rw-r--r-- | source/cBlockArea.h (renamed from source/BlockArea.h) | 0 | ||||
-rw-r--r-- | source/cChunk.cpp | 2 | ||||
-rw-r--r-- | source/cPluginManager.cpp | 36 | ||||
-rw-r--r-- | source/cPlugin_Squirrel.cpp | 352 | ||||
-rw-r--r-- | source/cPlugin_Squirrel.h | 42 | ||||
-rw-r--r-- | source/cVine.h | 1 | ||||
-rw-r--r-- | source/main.cpp | 7 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelBindings.cpp | 52 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelBindings.h | 13 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelFunctions.cpp | 65 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelFunctions.h | 6 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelObject.h | 24 | ||||
-rw-r--r-- | source/squirrelbindings/cSquirrelBaseClass.h | 29 |
19 files changed, 759 insertions, 190 deletions
diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index b6ee64579..4e4cfb4b5 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -45,7 +45,7 @@ $cfile "cCuboid.h" $cfile "cMCLogger.h" $cfile "cTracer.h" $cfile "cGroup.h" -$cfile "BlockArea.h" +$cfile "cBlockArea.h" $cfile "packets/cPacket_Login.h" $cfile "packets/cPacket_BlockDig.h" $cfile "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 485f37dc0..772013b25 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/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:12. */ #ifndef __cplusplus @@ -54,7 +54,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "cMCLogger.h" #include "cTracer.h" #include "cGroup.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "packets/cPacket_Login.h" #include "packets/cPacket_BlockDig.h" #include "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.h b/source/Bindings.h index a47b5e463..097fe7e64 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/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:13. */ /* Exported function */ diff --git a/source/SquirrelBindings.cpp b/source/_OLD_SquirrelBindings.cpp index d8f513370..532b19950 100644 --- a/source/SquirrelBindings.cpp +++ b/source/_OLD_SquirrelBindings.cpp @@ -1,140 +1,140 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SquirrelBindings.h" -#if USE_SQUIRREL -#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus -#pragma warning(disable:4127) - -#include <sqplus/sqplus.h> -#include <sqplus/SquirrelObject.h> -#include <../squirrel/sqstate.h> -#include <../squirrel/sqvm.h> - -#include "cPlugin.h" -#include "cPluginManager.h" -#include "cRoot.h" -#include "cPlayer.h" - - - - - -bool SquirrelBindings::IsBound = false; - -bool IsTopClosure( HSQUIRRELVM v ) -{ - return ( v->_stack[0]._type == OT_CLOSURE ); -} - -class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel -{ -public: - template<typename T> - static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) - { - LOG("ConstructAndDestruct()"); - - StackHandler sa(v); - HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE - SquirrelObject instance(ho); - SqPlus::PopulateAncestry(v, instance, a_Instance); - a_Instance->vm = v; - a_Instance->obj = instance; - - sq_setinstanceup(v, 1, a_Instance); - sq_setreleasehook(v, 1, a_ReleaseHook); - return TRUE; - } - - HSQUIRRELVM vm; - SquirrelObject obj; -}; - -class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class -{ -public: - cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } - - bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance - { - SqPlus::SquirrelFunction<bool> InitFunc(obj, "Initialize"); - if( !InitFunc.func.IsNull() ) - return InitFunc(); - LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented - return false; - } - - static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr<cPlugin__Squirrel>::release ); } - - virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) - { - if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) - { //Called from C++ - return SqPlus::SquirrelFunction<bool>(obj, "OnChat")(a_Chat, a_Player); - } - else // Called from Squirrel - { - return cPlugin::OnChat(a_Chat, a_Player); - } - } -}; - -static void printFunc(HSQUIRRELVM v,const SQChar * s,...) -{ - (void)v; - va_list vl; - va_start(vl,s); - cMCLogger::GetInstance()->Log( s, vl ); - va_end(vl); -} - -DECLARE_INSTANCE_TYPE( cRoot ); -DECLARE_INSTANCE_TYPE( cPluginManager ); -DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); -DECLARE_INSTANCE_TYPE( cPlugin ); -DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); - -DECLARE_INSTANCE_TYPE( cEntity ); -DECLARE_INSTANCE_TYPE( cPawn ); -DECLARE_INSTANCE_TYPE( cPlayer ); - -void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) -{ - IsBound = true; - - sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); - - - SqPlus::SQClassDefNoConstructor<cEntity>("cEntity"); - SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity"); - SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one - func(&cPlayer::GetName, "GetName"); - - SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin"). - func(&cPlugin::SetName, "SetName"). - func(&cPlugin::GetName, "GetName"). - func(&cPlugin::GetVersion, "GetVersion"). - func(&cPlugin::OnChat, "OnChat"); - - - SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin"). - staticFunc(&cPlugin__Squirrel::constructor, "constructor"); - - - SqPlus::SQClassDefNoConstructor<cRoot>("cRoot"). - staticFunc(&cRoot::Get, "Get"). - func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager"); - - - SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager"). - overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin"). - func(&cPluginManager::GetPlugin, "GetPlugin"). - func(&cPluginManager::AddHook, "AddHook"). - enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); - - - -} - -#endif +
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "SquirrelBindings.h"
+#if USE_SQUIRREL
+//#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus
+//#pragma warning(disable:4127)
+
+#include <sqplus/sqplus.h>
+#include <sqplus/SquirrelObject.h>
+#include <../squirrel/sqstate.h>
+#include <../squirrel/sqvm.h>
+
+#include "cPlugin.h"
+#include "cPluginManager.h"
+#include "cRoot.h"
+#include "cPlayer.h"
+
+
+
+
+
+bool SquirrelBindings::IsBound = false;
+
+bool IsTopClosure( HSQUIRRELVM v )
+{
+ return ( v->_stack[0]._type == OT_CLOSURE );
+}
+
+class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel
+{
+public:
+ template<typename T>
+ static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook )
+ {
+ LOG("ConstructAndDestruct()");
+
+ StackHandler sa(v);
+ HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE
+ SquirrelObject instance(ho);
+ SqPlus::PopulateAncestry(v, instance, a_Instance);
+ a_Instance->vm = v;
+ a_Instance->obj = instance;
+
+ sq_setinstanceup(v, 1, a_Instance);
+ sq_setreleasehook(v, 1, a_ReleaseHook);
+ return TRUE;
+ }
+
+ HSQUIRRELVM vm;
+ SquirrelObject obj;
+};
+
+class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class
+{
+public:
+ cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); }
+
+ bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance
+ {
+ SqPlus::SquirrelFunction<bool> InitFunc(obj, "Initialize");
+ if( !InitFunc.func.IsNull() )
+ return InitFunc();
+ LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented
+ return false;
+ }
+
+ static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr<cPlugin__Squirrel>::release ); }
+
+ virtual bool OnChat( const char* a_Chat, cPlayer* a_Player )
+ {
+ if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!)
+ { //Called from C++
+ return SqPlus::SquirrelFunction<bool>(obj, "OnChat")(a_Chat, a_Player);
+ }
+ else // Called from Squirrel
+ {
+ return cPlugin::OnChat(a_Chat, a_Player);
+ }
+ }
+};
+
+static void printFunc(HSQUIRRELVM v,const SQChar * s,...)
+{
+ (void)v;
+ va_list vl;
+ va_start(vl,s);
+ cMCLogger::GetInstance()->Log( s, vl );
+ va_end(vl);
+}
+
+DECLARE_INSTANCE_TYPE( cRoot );
+DECLARE_INSTANCE_TYPE( cPluginManager );
+DECLARE_ENUM_TYPE( cPluginManager::PluginHook );
+DECLARE_INSTANCE_TYPE( cPlugin );
+DECLARE_INSTANCE_TYPE( cPlugin__Squirrel );
+
+DECLARE_INSTANCE_TYPE( cEntity );
+DECLARE_INSTANCE_TYPE( cPawn );
+DECLARE_INSTANCE_TYPE( cPlayer );
+
+void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM )
+{
+ IsBound = true;
+
+ sq_setprintfunc(a_SquirrelVM, printFunc, printFunc);
+
+
+ SqPlus::SQClassDefNoConstructor<cEntity>("cEntity");
+ SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity");
+ SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one
+ func(&cPlayer::GetName, "GetName");
+
+ SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin").
+ func(&cPlugin::SetName, "SetName").
+ func(&cPlugin::GetName, "GetName").
+ func(&cPlugin::GetVersion, "GetVersion").
+ func(&cPlugin::OnChat, "OnChat");
+
+
+ SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin").
+ staticFunc(&cPlugin__Squirrel::constructor, "constructor");
+
+
+ SqPlus::SQClassDefNoConstructor<cRoot>("cRoot").
+ staticFunc(&cRoot::Get, "Get").
+ func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager");
+
+
+ SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager").
+ overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin").
+ func(&cPluginManager::GetPlugin, "GetPlugin").
+ func(&cPluginManager::AddHook, "AddHook").
+ enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT");
+
+
+
+}
+
+#endif
diff --git a/source/SquirrelBindings.h b/source/_OLD_SquirrelBindings.h index 06a3df716..26f125746 100644 --- a/source/SquirrelBindings.h +++ b/source/_OLD_SquirrelBindings.h @@ -1,15 +1,15 @@ -#pragma once - -#define USE_SQUIRREL 0 - -#if USE_SQUIRREL - -struct SQVM; -class SquirrelBindings -{ -public: - static void Bind( SQVM* a_SquirrelVM ); - static bool IsBound; -}; - -#endif +#pragma once
+
+#define USE_SQUIRREL 1
+
+#if USE_SQUIRREL
+
+struct SQVM;
+class SquirrelBindings
+{
+public:
+ static void Bind( SQVM* a_SquirrelVM );
+ static bool IsBound;
+};
+
+#endif
diff --git a/source/BlockArea.cpp b/source/cBlockArea.cpp index 7750b94fb..810503f04 100644 --- a/source/BlockArea.cpp +++ b/source/cBlockArea.cpp @@ -5,7 +5,7 @@ // The object also supports writing the blockdata back into cWorld, even into other coords
#include "Globals.h"
-#include "BlockArea.h"
+#include "cBlockArea.h"
#include "cWorld.h"
diff --git a/source/BlockArea.h b/source/cBlockArea.h index 5abdab3bb..5abdab3bb 100644 --- a/source/BlockArea.h +++ b/source/cBlockArea.h diff --git a/source/cChunk.cpp b/source/cChunk.cpp index cd94e3413..489af5cc9 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -27,7 +27,7 @@ #include "cBlockToPickup.h" #include "MersenneTwister.h" #include "cPlayer.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "cPluginManager.h" #include "packets/cPacket_DestroyEntity.h" diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index f152911e8..4cf21c850 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -5,6 +5,7 @@ #include "cPlugin.h" #include "cPlugin_Lua.h" #include "cPlugin_NewLua.h" +#include "cPlugin_Squirrel.h" #include "cWebAdmin.h" #include "cItem.h" #include "cRoot.h" @@ -12,10 +13,12 @@ #include "../iniFile/iniFile.h" #include "tolua++.h" -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" +#include "squirrelbindings/SquirrelFunctions.h" + #if USE_SQUIRREL #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include <sqplus/sqplus.h> + #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) #endif @@ -70,11 +73,8 @@ void cPluginManager::ReloadPluginsNow() UnloadPluginsNow(); #if USE_SQUIRREL - if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script - { - SquirrelVM::Init(); - SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); - } + CloseSquirrelVM(); + OpenSquirrelVM(); #endif // USE_SQUIRREL cIniFile IniFile("settings.ini"); @@ -129,26 +129,11 @@ void cPluginManager::ReloadPluginsNow() if( !PluginFile.empty() ) { LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); - try - { - SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); - try - { - SquirrelVM::RunScript( SquirrelScript ); - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); - } - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); - } + + this->AddPlugin(new cPlugin_Squirrel(PluginFile.c_str())); } } #endif // USE_SQUIRREL - } } @@ -195,7 +180,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) if (a_Hook == HOOK_CHAT) { if (a_NumArgs != 2) - { + { return false; } va_list argptr; @@ -221,6 +206,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) return true; } } + return false; } diff --git a/source/cPlugin_Squirrel.cpp b/source/cPlugin_Squirrel.cpp new file mode 100644 index 000000000..aa7f7f023 --- /dev/null +++ b/source/cPlugin_Squirrel.cpp @@ -0,0 +1,352 @@ +#include "Globals.h"
+#include "cPlugin_Squirrel.h"
+#include "squirrelbindings/SquirrelFunctions.h"
+#include "squirrelbindings/SquirrelBindings.h"
+#include "squirrelbindings/cSquirrelBaseClass.h"
+
+
+cPlugin_Squirrel::cPlugin_Squirrel( const char* a_PluginName )
+{
+ SetLanguage( cPlugin::E_SQUIRREL );
+ m_PluginName = a_PluginName;
+}
+
+cPlugin_Squirrel::~cPlugin_Squirrel()
+{
+ delete m_PluginName;
+ delete m_Plugin;
+}
+
+bool cPlugin_Squirrel::Initialize()
+{
+ cCSLock Lock(m_CriticalSection);
+
+ std::string PluginPath = std::string("Plugins/") + m_PluginName + ".nut";
+
+ Sqrat::Script script;
+ script.CompileFile(PluginPath);
+ if(script.IsNull())
+ {
+ LOGERROR("Unable to run script \"%s\"", m_PluginName);
+ }
+
+ try {
+ script.Run();
+
+ Sqrat::Function construct(Sqrat::RootTable(), m_PluginName);
+
+ if(construct.IsNull())
+ {
+ LOGERROR("Constructor for Plugin \"%s\" not found.", m_PluginName);
+ return false;
+ }
+
+ Sqrat::Object obj = construct.Evaluate<Sqrat::Object>();
+
+ ((cSquirrelBaseClass *) obj.GetInstanceUP())->setInstance(this);
+
+ m_Plugin = new SquirrelObject(obj);
+
+
+ Sqrat::Object PluginName = obj.GetSlot("name");
+ if(!PluginName.IsNull())
+ {
+ this->SetName(PluginName.Cast<const char*>());
+ }
+
+ Sqrat::Function init = m_Plugin->GetFunction("Initialize");
+ if(init.IsNull())
+ {
+ LOGERROR("Can not initialize plugin \"%s\"", m_PluginName);
+ return false;
+ }
+
+ return init.Evaluate<bool>();
+
+ } catch(Sqrat::Exception &e)
+ {
+ LOGERROR("Initialisation of \"%s\" failed: %s", m_PluginName, e.Message().c_str());
+ return false;
+ }
+}
+
+
+
+
+
+void cPlugin_Squirrel::OnDisable()
+{
+ cCSLock Lock(m_CriticalSection);
+
+ m_Plugin->GetFunction("OnDisable").Execute();
+}
+
+
+
+
+
+void cPlugin_Squirrel::Tick(float a_Dt)
+{
+ cCSLock Lock( m_CriticalSection );
+
+ m_Plugin->GetFunction("OnTick").Execute(a_Dt);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnCollectItem").Evaluate<bool>(a_Pickup, a_Player);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnDisconnect(const AString & a_Reason, cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+
+ return m_Plugin->GetFunction("OnDisconnect").Evaluate<bool>(a_Reason, a_Player);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnBlockPlace").Evaluate<bool>(a_PacketData, a_Player);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnBlockDig").Evaluate<bool>(a_PacketData, a_Player, a_PickupItem);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnChat( const char* a_Chat, cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnChat").Evaluate<bool>(a_Chat, a_Player);
+
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnLogin( cPacket_Login* a_PacketData )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnLogin").Evaluate<bool>(a_PacketData);
+}
+
+
+
+
+
+void cPlugin_Squirrel::OnPlayerSpawn( cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnPlayerSpawn").Execute(a_Player);
+
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnPlayerJoin( cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnPlayerJoin").Evaluate<bool>(a_Player);
+}
+
+
+
+
+
+void cPlugin_Squirrel::OnPlayerMove( cPlayer* a_Player )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnPlayerMove").Execute(a_Player);
+
+}
+
+
+
+
+
+void cPlugin_Squirrel::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnTakeDamage")(a_Pawn, a_TakeDamageInfo);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnKilled( cPawn* a_Killed, cEntity* a_Killer )
+{
+ cCSLock Lock( m_CriticalSection );
+
+ return m_Plugin->GetFunction("OnKilled").Evaluate<bool>(a_Killed, a_Killer);
+}
+
+
+
+
+
+void cPlugin_Squirrel::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
+{
+ cCSLock Lock(m_CriticalSection);
+
+ return m_Plugin->GetFunction("OnChunkGenerated")(a_World, a_ChunkX, a_ChunkZ);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk)
+{
+ cCSLock Lock(m_CriticalSection);
+
+ return m_Plugin->GetFunction("OnChunkGenerating").Evaluate<bool>(a_World, a_ChunkX, a_ChunkZ, a_pLuaChunk);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
+{
+ cCSLock Lock(m_CriticalSection);
+
+ return m_Plugin->GetFunction("OnPreCrafting").Evaluate<bool>((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe);
+
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
+{
+ cCSLock Lock(m_CriticalSection);
+
+ return m_Plugin->GetFunction("OnCraftingNoRecipe").Evaluate<bool>((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
+{
+ cCSLock Lock(m_CriticalSection);
+
+
+ return m_Plugin->GetFunction("OnPostCrafting").Evaluate<bool>((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnBlockToPickup(
+ BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
+ const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups
+)
+{
+ cCSLock Lock(m_CriticalSection);
+
+
+ return m_Plugin->GetFunction("OnBlockToPickup").Evaluate<bool>(a_BlockType, a_BlockMeta, (cPlayer *) a_Player, a_EquippedItem, a_Pickups);
+
+}
+
+
+
+
+
+bool cPlugin_Squirrel::OnWeatherChanged(cWorld * a_World)
+{
+ cCSLock Lock(m_CriticalSection);
+
+
+ return m_Plugin->GetFunction("OnWeatherChanged").Evaluate<bool>(a_World);
+}
+
+
+
+
+
+bool cPlugin_Squirrel::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
+)
+{
+ cCSLock Lock(m_CriticalSection);
+
+
+ return m_Plugin->GetFunction("OnUpdatingSign")
+ .Evaluate<bool>(
+ a_World,
+ a_BlockX,
+ a_BlockY,
+ a_BlockZ,
+ a_Line1,
+ a_Line2,
+ a_Line3,
+ a_Line4
+ );
+}
+
+
+
+
+
+bool cPlugin_Squirrel::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
+)
+{
+ return m_Plugin->GetFunction("OnUpdatedSign")
+ .Evaluate<bool>(
+ a_World,
+ a_BlockX,
+ a_BlockY,
+ a_BlockZ,
+ a_Line1,
+ a_Line2,
+ a_Line3,
+ a_Line4
+ );
+}
diff --git a/source/cPlugin_Squirrel.h b/source/cPlugin_Squirrel.h new file mode 100644 index 000000000..cd05e117a --- /dev/null +++ b/source/cPlugin_Squirrel.h @@ -0,0 +1,42 @@ +#pragma once
+#include "cPlugin.h"
+#include <sqrat.h>
+#include "squirrelbindings/SquirrelObject.h"
+
+class cPlugin_Squirrel : public cPlugin
+{
+public:
+ cPlugin_Squirrel(const char* a_PluginName);
+ ~cPlugin_Squirrel();
+
+ void OnDisable();
+ bool Initialize();
+
+ void Tick(float a_Dt);
+
+ bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
+ bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
+ bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override;
+ bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override;
+ bool OnChat (const char* a_Chat, cPlayer* a_Player ) override;
+ bool OnLogin (cPacket_Login* a_PacketData ) override;
+ void OnPlayerSpawn (cPlayer* a_Player ) override;
+ bool OnPlayerJoin (cPlayer* a_Player ) override;
+ void OnPlayerMove (cPlayer* a_Player ) override;
+ void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override;
+ bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
+ void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
+ bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override;
+ bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
+ bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
+ bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
+ bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
+ bool OnWeatherChanged (cWorld * a_World) override;
+ 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) override;
+ 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) override;
+
+protected:
+ const char * m_PluginName;
+ cCriticalSection m_CriticalSection;
+ SquirrelObject *m_Plugin;
+};
\ No newline at end of file diff --git a/source/cVine.h b/source/cVine.h index a99a98aca..d4bc99c1a 100644 --- a/source/cVine.h +++ b/source/cVine.h @@ -19,6 +19,5 @@ public: default: return 0xf; }; - return 0xf; } //tolua_export }; //tolua_export
\ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index d379fdd17..03dea6f01 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -6,16 +6,17 @@ #include <exception> //std::exception #include <csignal> //std::signal #include <stdlib.h> //exit() +#include "squirrelbindings/SquirrelFunctions.h" #ifdef _WIN32 #include <dbghelp.h> #endif // _WIN32 -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" #if USE_SQUIRREL #pragma warning(push) #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include <sqplus/sqplus.h> + #pragma warning(pop) #endif @@ -189,7 +190,7 @@ int main( int argc, char **argv ) } #if USE_SQUIRREL - SquirrelVM::Shutdown(); + CloseSquirrelVM(); #endif #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) diff --git a/source/squirrelbindings/SquirrelBindings.cpp b/source/squirrelbindings/SquirrelBindings.cpp new file mode 100644 index 000000000..27a82c306 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.cpp @@ -0,0 +1,52 @@ +#include "Globals.h"
+#include "SquirrelBindings.h"
+#include "SquirrelFunctions.h"
+
+#include "cSquirrelBaseClass.h"
+
+#include "../cPlayer.h"
+
+using namespace Sqrat;
+
+
+
+void BindSquirrel(HSQUIRRELVM vm)
+{
+ RootTable()
+ .Bind("Plugin", Class<cSquirrelBaseClass>()
+ .Func("AddHook", &cSquirrelBaseClass::AddHook)
+ );
+ RootTable().Bind("cPlayer", Class<cPlayer, NoConstructor>()
+ .Func("GetName", &cPlayer::GetName)
+ );
+
+
+ RootTable().Func("print", &sqPrint);
+
+
+ ConstTable().Enum("Hook", Enumeration()
+ .Const("Tick", cPluginManager::HOOK_TICK)
+ .Const("Chat", cPluginManager::HOOK_CHAT)
+ .Const("CollectItem", cPluginManager::HOOK_COLLECT_ITEM)
+ .Const("BlockDig", cPluginManager::HOOK_BLOCK_DIG)
+ .Const("BlockPlace", cPluginManager::HOOK_BLOCK_PLACE)
+ .Const("Disconnect", cPluginManager::HOOK_DISCONNECT)
+ .Const("Handshake", cPluginManager::HOOK_HANDSHAKE)
+ .Const("Login", cPluginManager::HOOK_LOGIN)
+ .Const("PlayerSpawn", cPluginManager::HOOK_PLAYER_SPAWN)
+ .Const("PlayerJoin", cPluginManager::HOOK_PLAYER_JOIN)
+ .Const("PlayerMove", cPluginManager::HOOK_PLAYER_MOVE)
+ .Const("TakeDamage", cPluginManager::HOOK_TAKE_DAMAGE)
+ .Const("Killed", cPluginManager::HOOK_KILLED)
+ .Const("ChunkGenerated", cPluginManager::HOOK_CHUNK_GENERATED)
+ .Const("ChunkGenerating", cPluginManager::HOOK_CHUNK_GENERATING)
+ .Const("BlockToDrops", cPluginManager::HOOK_BLOCK_TO_DROPS)
+ .Const("PreCrafting", cPluginManager::HOOK_PRE_CRAFTING)
+ .Const("CraftingNoRecipe", cPluginManager::HOOK_CRAFTING_NO_RECIPE)
+ .Const("PostCrafting", cPluginManager::HOOK_POST_CRAFTING)
+ .Const("BlockToPickup", cPluginManager::HOOK_BLOCK_TO_PICKUP)
+ .Const("WeatherChanged", cPluginManager::HOOK_WEATHER_CHANGED)
+ .Const("UpdatingSign", cPluginManager::HOOK_UPDATING_SIGN)
+ .Const("UpdatedSign", cPluginManager::HOOK_UPDATED_SIGN));
+
+}
\ No newline at end of file diff --git a/source/squirrelbindings/SquirrelBindings.h b/source/squirrelbindings/SquirrelBindings.h new file mode 100644 index 000000000..1b71f5e86 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.h @@ -0,0 +1,13 @@ +#pragma once
+
+
+#define USE_SQUIRREL 1
+
+#if USE_SQUIRREL
+
+#include <squirrel.h>
+#include <sqrat.h>
+
+void BindSquirrel(HSQUIRRELVM vm);
+
+#endif
diff --git a/source/squirrelbindings/SquirrelFunctions.cpp b/source/squirrelbindings/SquirrelFunctions.cpp new file mode 100644 index 000000000..88871369d --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.cpp @@ -0,0 +1,65 @@ +
+#include "Globals.h"
+#include "SquirrelFunctions.h"
+#include "SquirrelBindings.h"
+
+static HSQUIRRELVM squirrelvm = NULL;
+
+SQInteger runtimeErrorHandler(HSQUIRRELVM a_VM)
+{
+ const SQChar *sErr = 0;
+ if(sq_gettop(a_VM) >= 1)
+ {
+ if(SQ_SUCCEEDED(sq_getstring(a_VM, 2, &sErr)))
+ {
+ LOGERROR("Squirrel Error: %s", sErr);
+ }
+ else
+ {
+ LOGERROR("Squirrel Error: Unknown Error");
+ }
+ }
+ return 0;
+}
+
+void compilerErrorHandler(HSQUIRRELVM v,
+ const SQChar* a_Desc,
+ const SQChar* a_Source,
+ SQInteger a_Line,
+ SQInteger a_Column)
+{
+
+ LOGERROR("Squirrel Error: %s (%d:%d) %s", a_Source, a_Line, a_Column, a_Desc);
+}
+
+HSQUIRRELVM OpenSquirrelVM()
+{
+ if(!squirrelvm)
+ {
+ squirrelvm = sq_open(1024);
+ Sqrat::DefaultVM::Set(squirrelvm);
+
+ sq_newclosure(squirrelvm, runtimeErrorHandler, 0);
+ sq_seterrorhandler(squirrelvm);
+
+ sq_setcompilererrorhandler(squirrelvm, compilerErrorHandler);
+
+ BindSquirrel(squirrelvm);
+ }
+ return squirrelvm;
+}
+
+void CloseSquirrelVM()
+{
+ if(squirrelvm)
+ {
+ sq_close(squirrelvm);
+ squirrelvm = NULL;
+ }
+}
+
+
+void sqPrint(SQChar * text)
+{
+ LOGINFO("%s", text);
+}
\ No newline at end of file diff --git a/source/squirrelbindings/SquirrelFunctions.h b/source/squirrelbindings/SquirrelFunctions.h new file mode 100644 index 000000000..0d08a726c --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.h @@ -0,0 +1,6 @@ +#pragma once
+#include <sqrat.h>
+HSQUIRRELVM OpenSquirrelVM();
+void CloseSquirrelVM();
+
+void sqPrint(SQChar * text);
\ No newline at end of file diff --git a/source/squirrelbindings/SquirrelObject.h b/source/squirrelbindings/SquirrelObject.h new file mode 100644 index 000000000..1ac6fa105 --- /dev/null +++ b/source/squirrelbindings/SquirrelObject.h @@ -0,0 +1,24 @@ +#pragma once
+#include <sqrat.h>
+
+class SquirrelObject
+{
+public:
+ SquirrelObject(Sqrat::Object a_Obj)
+ {
+ m_SquirrelObject = a_Obj;
+ }
+
+ Sqrat::Function GetFunction(const char *methodName)
+ {
+ if(m_SquirrelObject.IsNull())
+ return Sqrat::Function();
+
+ Sqrat::Function method(m_SquirrelObject, methodName);
+ return method;
+ }
+
+protected:
+ Sqrat::Object m_SquirrelObject;
+
+};
\ No newline at end of file diff --git a/source/squirrelbindings/cSquirrelBaseClass.h b/source/squirrelbindings/cSquirrelBaseClass.h new file mode 100644 index 000000000..e06301555 --- /dev/null +++ b/source/squirrelbindings/cSquirrelBaseClass.h @@ -0,0 +1,29 @@ +#pragma once
+#include "SquirrelBindings.h"
+#include "../cPlugin_Squirrel.h"
+#include "../cPluginManager.h"
+#include "cRoot.h"
+
+//The baseclass for squirrel plugins
+class cSquirrelBaseClass
+{
+public:
+ cSquirrelBaseClass()
+ : m_Instance(0)
+ {
+ }
+
+ void setInstance(cPlugin_Squirrel *a_Instance)
+ {
+ m_Instance = a_Instance;
+ }
+
+ void AddHook(short a_Hook)
+ {
+ if(m_Instance)
+ cRoot::Get()->GetPluginManager()->AddHook(m_Instance, (cPluginManager::PluginHook) a_Hook);
+ }
+
+protected:
+ cPlugin_Squirrel *m_Instance;
+};
\ No newline at end of file |