mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-04 01:37:47 +00:00
refactor script api, base script loading impl
This commit is contained in:
parent
076b2591d4
commit
a4453a378e
8 changed files with 236 additions and 30 deletions
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(Sapphire_Script)
|
||||
|
||||
file(GLOB SCRIPT_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
|
||||
|
@ -7,21 +7,20 @@ file(GLOB_RECURSE SCRIPT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
|||
include_directories("../../src/servers/")
|
||||
include_directories("../../src/servers/Server_Zone/")
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/")
|
||||
|
||||
foreach(_sourcefile "${SCRIPT_FILES}")
|
||||
get_filename_component(_file "${_sourcefile}" NAME_WE)
|
||||
add_library("${_file}" MODULE "${_sourcefile}" "${SCRIPT_INCLUDE_FILES}")
|
||||
message("adding library ${_file}")
|
||||
|
||||
add_dependencies("${_file}" server_zone)
|
||||
|
||||
set_target_properties("${_file}" PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
)
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/compiledscripts/"
|
||||
)
|
||||
endforeach(_sourcefile "${SCRIPT_FILES}")
|
15
scripts/native/skill/AbilityScript3.cpp
Normal file
15
scripts/native/skill/AbilityScript3.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
//#include "../ScriptObject.h"
|
||||
//
|
||||
//class AbilityScript3 : public AbilityScript
|
||||
//{
|
||||
//public:
|
||||
// AbilityScript3() : AbilityScript( "AbilityScript3", 3 )
|
||||
// {}
|
||||
//
|
||||
// virtual void onCastFinish( Core::Entity::Player player, Core::Entity::ActorPtr targetActor )
|
||||
// {
|
||||
// player.addStatusEffectByIdIfNotExist( 50, 20000, player, 30 );
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//EXPORT_ABILITYSCRIPT( AbilityScript3 )
|
|
@ -6,10 +6,11 @@ public:
|
|||
StatusEffect50() : StatusEffectScript( "StatusEffect50", 50 )
|
||||
{}
|
||||
|
||||
virtual void onTick( Core::Entity::ActorPtr actor )
|
||||
{
|
||||
|
||||
}
|
||||
// virtual void onTick( Core::Entity::ActorPtr actor )
|
||||
// {
|
||||
// if( actor->isPlayer() )
|
||||
// actor->getAsPlayer()->sendDebug( "tick tock bitch" );
|
||||
// }
|
||||
};
|
||||
|
||||
EXPORT_STATUSEFFECTSCRIPT( StatusEffect50 )
|
|
@ -11,9 +11,9 @@ namespace Core {
|
|||
return m_statusEffectScripts.at( statusId );
|
||||
}
|
||||
|
||||
AbilityScript* NativeScript::getAbilityScript( uint32_t abilityId )
|
||||
ActionScript* NativeScript::getAbilityScript( uint32_t abilityId )
|
||||
{
|
||||
return m_abilityScripts.at( abilityId );
|
||||
return m_actionScripts.at( abilityId );
|
||||
}
|
||||
|
||||
QuestScript* NativeScript::getQuestScript( uint32_t questId )
|
||||
|
@ -38,7 +38,7 @@ namespace Core {
|
|||
|
||||
void NativeScript::removeAbilityScript( uint32_t abilityId )
|
||||
{
|
||||
m_abilityScripts.erase( abilityId );
|
||||
m_actionScripts.erase( abilityId );
|
||||
}
|
||||
|
||||
void NativeScript::removeQuestScript( uint32_t questId )
|
||||
|
@ -51,8 +51,39 @@ namespace Core {
|
|||
m_battleNpcScripts.erase( npcId );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NativeScript::loadScript( std::string path )
|
||||
{
|
||||
// auto handle = m_loader.loadModule( path );
|
||||
// if( handle )
|
||||
// {
|
||||
// // todo: this is shit
|
||||
// if( auto script = m_loader.getScriptObject< StatusEffectScript >( handle ) )
|
||||
// {
|
||||
// m_statusEffectScripts.insert( std::make_pair( script->getEffectId(), script ) );
|
||||
// }
|
||||
// else if( auto script = m_loader.getScriptObject< ActionScript >( handle ) )
|
||||
// {
|
||||
// m_actionScripts.insert( std::make_pair( script->getActionId(), script ) );
|
||||
// }
|
||||
// else if( auto script = m_loader.getScriptObject< QuestScript >( handle ) )
|
||||
// {
|
||||
// m_questScripts.insert( std::make_pair( script->getQuestId(), script ) );
|
||||
// }
|
||||
// else if( auto script = m_loader.getScriptObject< BattleNpcScript >( handle ) )
|
||||
// {
|
||||
// m_battleNpcScripts.insert( std::make_pair( script->getNpcId(), script ) );
|
||||
// }
|
||||
// else if( auto script = m_loader.getScriptObject< ZoneScript >( handle ) )
|
||||
// {
|
||||
// m_zoneScripts.insert( std::make_pair( script->getZoneId(), script ) );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // unload anything which doesn't have a suitable export
|
||||
// m_loader.unloadScript( handle );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr< NativeScript > create_script_engine( )
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <Server_Common/Crypt/md5.h>
|
||||
|
||||
#include "NativeScriptApi.h"
|
||||
#include "ScriptLoader.h"
|
||||
|
||||
namespace Core {
|
||||
namespace Scripting {
|
||||
|
@ -18,16 +19,18 @@ namespace Core {
|
|||
{
|
||||
protected:
|
||||
std::unordered_map< uint32_t, StatusEffectScript* > m_statusEffectScripts;
|
||||
std::unordered_map< uint32_t, AbilityScript* > m_abilityScripts;
|
||||
std::unordered_map< uint32_t, ActionScript* > m_actionScripts;
|
||||
std::unordered_map< uint32_t, QuestScript* > m_questScripts;
|
||||
std::unordered_map< uint32_t, BattleNpcScript* > m_battleNpcScripts;
|
||||
std::unordered_map< uint32_t, ZoneScript* > m_zoneScripts;
|
||||
|
||||
ScriptLoader m_loader;
|
||||
|
||||
public:
|
||||
NativeScript( );
|
||||
|
||||
StatusEffectScript* getStatusEffectScript( uint32_t statusId );
|
||||
AbilityScript* getAbilityScript( uint32_t abilityId );
|
||||
ActionScript* getAbilityScript( uint32_t abilityId );
|
||||
QuestScript* getQuestScript( uint32_t questId );
|
||||
BattleNpcScript* getBattleNpcScript( uint32_t npcId );
|
||||
ZoneScript* getZoneScript( uint32_t zoneId );
|
||||
|
@ -38,6 +41,8 @@ namespace Core {
|
|||
void removeBattleNpcScript( uint32_t npcId );
|
||||
|
||||
|
||||
void loadScript( std::string );
|
||||
void unloadScript( std::string );
|
||||
void clearAllScripts();
|
||||
};
|
||||
|
||||
|
|
|
@ -60,24 +60,24 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class AbilityScript : public ScriptObject
|
||||
class ActionScript : public ScriptObject
|
||||
{
|
||||
protected:
|
||||
const uint32_t m_abilityId;
|
||||
const uint32_t m_actionId;
|
||||
|
||||
public:
|
||||
AbilityScript( std::string name, uint32_t abilityId ) :
|
||||
ActionScript( std::string name, uint32_t abilityId ) :
|
||||
ScriptObject( name ),
|
||||
m_abilityId( abilityId )
|
||||
m_actionId( abilityId )
|
||||
{ }
|
||||
|
||||
const uint32_t GetAbilityId( )
|
||||
const uint32_t getActionId()
|
||||
{
|
||||
return m_abilityId;
|
||||
return m_actionId;
|
||||
}
|
||||
|
||||
virtual void onStart( Core::Entity::Actor sourceActor, Core::Entity::Actor targetActor ) { }
|
||||
virtual void onCastFinish(Core::Entity::Player player, Core::Entity::ActorPtr targetActor) { }
|
||||
virtual void onStart( Core::Entity::Actor sourceActor, Core::Entity::ActorPtr targetActor ) { }
|
||||
virtual void onCastFinish( Core::Entity::Player player, Core::Entity::ActorPtr targetActor ) { }
|
||||
virtual void onInterrupt( Core::Entity::Actor sourceActor/*, Core::Entity::Actor targetActor*/ ) { }
|
||||
};
|
||||
|
||||
|
@ -132,6 +132,10 @@ public:
|
|||
m_zoneId( zoneId )
|
||||
{ }
|
||||
|
||||
const uint32_t getZoneId()
|
||||
{
|
||||
return m_zoneId;
|
||||
}
|
||||
|
||||
virtual void onZoneInit() { }
|
||||
virtual void onEnterZone( Core::Entity::Player pPlayer, uint32_t eventId, uint16_t param1, uint16_t param2 ) { }
|
||||
|
|
107
src/servers/Server_Zone/Script/ScriptLoader.cpp
Normal file
107
src/servers/Server_Zone/Script/ScriptLoader.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
#include "ScriptLoader.h"
|
||||
|
||||
#include <Server_Common/Logging/Logger.h>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
extern Core::Logger g_log;
|
||||
|
||||
const std::string Core::Scripting::ScriptLoader::getModuleExtension()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return ".dll";
|
||||
#elif __APPLE__
|
||||
return ".dylib";
|
||||
#else
|
||||
return ".so";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Core::Scripting::ScriptLoader::unloadModule( ModuleHandle handle )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool success = FreeLibrary( handle ) != 0;
|
||||
#else
|
||||
bool success = dlclose( handle ) == 0;
|
||||
#endif
|
||||
|
||||
if( !success )
|
||||
{
|
||||
g_log.fatal( "Failed to unload module @ 0x" + boost::str( boost::format( "%|08X|" ) % handle ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
g_log.debug( "Unloaded module @ 0x" + boost::str( boost::format( "%|08X|" ) % handle ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ModuleHandle Core::Scripting::ScriptLoader::loadModule( std::string path )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ModuleHandle handle = LoadLibrary( path.c_str() );
|
||||
#else
|
||||
ModuleHandle handle = dlopen( path.c_str(), RTLD_LAZY );
|
||||
#endif
|
||||
|
||||
if( !handle )
|
||||
{
|
||||
g_log.error( "Failed to load module from: " + path );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_log.info( "Loaded module from '" + path + "' @ 0x" + boost::str( boost::format( "%|08X|" ) % handle ) );
|
||||
|
||||
boost::filesystem::path f( path );
|
||||
m_moduleMap.insert( std::make_pair( f.stem().string(), handle ) );
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
T* Core::Scripting::ScriptLoader::getScriptObject( ModuleHandle handle )
|
||||
{
|
||||
typedef T* (*getScriptObjectType)();
|
||||
|
||||
auto fn = boost::str( boost::format( "get%1%" ) % typeid( T ).name() );
|
||||
g_log.info( "getting symbol: " + fn );
|
||||
|
||||
#ifdef _WIN32
|
||||
getScriptObjectType func = reinterpret_cast< getScriptObjectType >( GetProcAddress( handle, fn.c_str() ) );
|
||||
#else
|
||||
getScriptObjectType func = reinterpret_cast< getScriptObjectType >( dlsym( handle, fn.c_str() ) );
|
||||
#endif
|
||||
|
||||
if( func )
|
||||
return func();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Core::Scripting::ScriptLoader::unloadScript( std::string name )
|
||||
{
|
||||
auto moduleHandle = m_moduleMap.at( name );
|
||||
if( moduleHandle )
|
||||
{
|
||||
return unloadModule( moduleHandle );
|
||||
}
|
||||
|
||||
g_log.info( "Module '" + name + "' is not loaded" );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Core::Scripting::ScriptLoader::unloadScript( ModuleHandle handle )
|
||||
{
|
||||
for( auto it = m_moduleMap.begin(); it != m_moduleMap.end(); ++it )
|
||||
{
|
||||
if( it->second == handle )
|
||||
{
|
||||
m_moduleMap.erase( it );
|
||||
return unloadModule( handle );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
44
src/servers/Server_Zone/Script/ScriptLoader.h
Normal file
44
src/servers/Server_Zone/Script/ScriptLoader.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef SAPPHIRE_SCRIPTLOADER_H
|
||||
#define SAPPHIRE_SCRIPTLOADER_H
|
||||
|
||||
#include <string>
|
||||
#include "NativeScriptApi.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <unordered_map>
|
||||
|
||||
typedef HMODULE ModuleHandle;
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
typedef void* ModuleHandle;
|
||||
#endif
|
||||
|
||||
namespace Core {
|
||||
namespace Scripting {
|
||||
|
||||
class ScriptLoader {
|
||||
protected:
|
||||
std::unordered_map< std::string, ModuleHandle > m_moduleMap;
|
||||
|
||||
bool unloadModule( ModuleHandle );
|
||||
|
||||
public:
|
||||
ScriptLoader() = default;
|
||||
|
||||
const std::string getModuleExtension();
|
||||
ModuleHandle loadModule( std::string );
|
||||
bool unloadScript( std::string );
|
||||
bool unloadScript( ModuleHandle );
|
||||
|
||||
template< typename T >
|
||||
T* getScriptObject( ModuleHandle );
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //SAPPHIRE_SCRIPTLOADER_H
|
Loading…
Add table
Reference in a new issue