summaryrefslogtreecommitdiff
path: root/src/common/plugins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/plugins.c')
-rw-r--r--src/common/plugins.c415
1 files changed, 0 insertions, 415 deletions
diff --git a/src/common/plugins.c b/src/common/plugins.c
deleted file mode 100644
index 5e021f35e..000000000
--- a/src/common/plugins.c
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include "../common/mmo.h"
-#include "../common/core.h"
-#include "../common/timer.h"
-#include "../common/utils.h" // findfile()
-#include "../common/socket.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-#include "plugins.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
-//////////////////////////////////////////////
-
-typedef struct _Plugin_Event {
- struct _Plugin_Event* next;
- Plugin_Event_Func* func;
-} Plugin_Event;
-
-typedef struct _Plugin_Event_List {
- struct _Plugin_Event_List* next;
- char* name;
- struct _Plugin_Event* events;
-} Plugin_Event_List;
-
-static int auto_search = 0;
-static int load_priority = 0;
-Plugin_Event_List* event_head = NULL;
-Plugin* plugin_head = NULL;
-
-static Plugin_Info default_info = { "Unknown", PLUGIN_ALL, "0", PLUGIN_VERSION, "Unknown" };
-
-void** plugin_call_table;
-static size_t call_table_size = 0;
-static size_t max_call_table = 0;
-
-////// Plugin Events Functions //////////////////
-
-int register_plugin_func(char* name)
-{
- Plugin_Event_List* evl;
- if( name ){
- //ShowDebug("register_plugin_func(%s)\n", name);
- CREATE(evl, Plugin_Event_List, 1);
- evl->next = event_head;
- evl->name = aStrdup(name);
- evl->events = NULL;
- event_head = evl;
- }
- return 0;
-}
-
-static Plugin_Event_List* search_plugin_func(char* name)
-{
- Plugin_Event_List* evl = event_head;
- while( evl ){
- if( strcmpi(evl->name,name) == 0 )
- return evl;
- evl = evl->next;
- }
- return NULL;
-}
-
-int register_plugin_event(Plugin_Event_Func* func, char* name)
-{
- Plugin_Event_List* evl = search_plugin_func(name);
- //ShowDebug("register_plugin_event(0x%x, %s)\n", func, name);
- if( !evl )
- {// event does not exist, register
- register_plugin_func(name);
- // get the new event list
- evl = search_plugin_func(name);
- }
- if( evl ){
- Plugin_Event* ev;
-
- CREATE(ev, Plugin_Event, 1);
- ev->func = func;
- ev->next = NULL;
-
- // insert event at the end of the linked list
- if( evl->events == NULL )
- evl->events = ev;
- else {
- Plugin_Event* last_ev = evl->events;
- while( last_ev ){
- if( last_ev->next == NULL ){
- last_ev->next = ev;
- break;
- }
- last_ev = last_ev->next;
- }
- }
- }
- return 0;
-}
-
-int plugin_event_trigger(char* name)
-{
- int c = 0;
- Plugin_Event_List* evl = search_plugin_func(name);
- //ShowDebug("plugin_event_trigger(%s)\n", name);
- if( evl ){
- Plugin_Event* ev = evl->events;
- while( ev ){
- ev->func();
- //ShowDebug("plugin_event_trigger: Executing function 0x%x.\n", ev->func);
- ev = ev->next;
- ++c;
- }
- }
- return c;
-}
-
-////// Plugins Call Table Functions /////////
-
-int export_symbol(void* var, size_t offset)
-{
- //ShowDebug("export_symbol(0x%x,%d)\n", var,offset);
-
- // add to the end of the list
- if( offset < 0 )
- offset = call_table_size;
-
- if( offset >= max_call_table )
- {// realloc if not large enough
- max_call_table = 1 + offset;
- RECREATE(plugin_call_table, void*, max_call_table);
-
- // clear the new alloced block
- memset(plugin_call_table + call_table_size, 0, (max_call_table-call_table_size)*sizeof(void*));
- }
-
- // the new table size is delimited by the new element at the end
- if( offset >= call_table_size )
- call_table_size = offset+1;
-
- // put the pointer at the selected place
- plugin_call_table[offset] = var;
- return 0;
-}
-
-////// Plugins Core /////////////////////////
-
-static int plugin_iscompatible(char* version)
-{
- int req_major = 0;
- int req_minor = 0;
- int major = 0;
- int minor = 0;
-
- if( version == NULL )
- return 0;
- sscanf(version, "%d.%d", &req_major, &req_minor);
- sscanf(PLUGIN_VERSION, "%d.%d", &major, &minor);
- return ( req_major == major && req_minor <= minor );
-}
-
-Plugin* plugin_open(const char* filename)
-{
- Plugin* plugin;
- Plugin_Info* info;
- Plugin_Event_Table* events;
- void** procs;
- int init_flag = 1;
-
- //ShowDebug("plugin_open(%s)\n", filename);
-
- // Check if the plugin has been loaded before
- plugin = plugin_head;
- while (plugin) {
- // returns handle to the already loaded plugin
- if( plugin->state && strcmpi(plugin->filename, filename) == 0 ){
- ShowWarning("plugin_open: not loaded (duplicate) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
- return plugin;
- }
- plugin = plugin->next;
- }
-
- CREATE(plugin, Plugin, 1);
- plugin->state = -1; // not loaded
-
- plugin->dll = DLL_OPEN(filename);
- if( !plugin->dll ){
- ShowWarning("plugin_open: not loaded (invalid file) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
- plugin_unload(plugin);
- return NULL;
- }
-
- // Retrieve plugin information
- plugin->state = 0; // initialising
- info = (Plugin_Info*)DLL_SYM(plugin->dll, "plugin_info");
- // For high priority plugins (those that are explicitly loaded from the conf file)
- // we'll ignore them even (could be a 3rd party dll file)
- if( !info )
- {// foreign plugin
- //ShowDebug("plugin_open: plugin_info not found\n");
- if( load_priority == 0 )
- {// not requested
- //ShowDebug("plugin_open: not loaded (not requested) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
- plugin_unload(plugin);
- return NULL;
- }
- } else if( !plugin_iscompatible(info->req_version) )
- {// incompatible version
- ShowWarning("plugin_open: not loaded (incompatible version '%s' -> '%s') : '"CL_WHITE"%s"CL_RESET"'\n", info->req_version, PLUGIN_VERSION, filename);
- plugin_unload(plugin);
- return NULL;
- } else if( (info->type != PLUGIN_ALL && info->type != PLUGIN_CORE && info->type != SERVER_TYPE) ||
- (info->type == PLUGIN_CORE && SERVER_TYPE != PLUGIN_LOGIN && SERVER_TYPE != PLUGIN_CHAR && SERVER_TYPE != PLUGIN_MAP) )
- {// not for this server
- //ShowDebug("plugin_open: not loaded (incompatible) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
- plugin_unload(plugin);
- return NULL;
- }
-
- plugin->info = ( info != NULL ? info : &default_info );
- plugin->filename = aStrdup(filename);
-
- // Initialise plugin call table (For exporting procedures)
- procs = (void**)DLL_SYM(plugin->dll, "plugin_call_table");
- if( procs )
- *procs = plugin_call_table;
- //else ShowDebug("plugin_open: plugin_call_table not found\n");
-
- // Register plugin events
- events = (Plugin_Event_Table*)DLL_SYM(plugin->dll, "plugin_event_table");
- if( events ){
- int i = 0;
- //ShowDebug("plugin_open: parsing plugin_event_table\n");
- while( events[i].func_name ){
- if( strcmpi(events[i].event_name, EVENT_PLUGIN_TEST) == 0 ){
- Plugin_Test_Func* test_func;
- test_func = (Plugin_Test_Func*)DLL_SYM(plugin->dll, events[i].func_name);
- //ShowDebug("plugin_open: invoking "EVENT_PLUGIN_TEST" with %s()\n", events[i].func_name);
- if( test_func && test_func() == 0 ){
- // plugin has failed test, disabling
- //ShowDebug("plugin_open: disabled (failed test) : %s\n", filename);
- init_flag = 0;
- }
- } else {
- Plugin_Event_Func* func;
- func = (Plugin_Event_Func*)DLL_SYM(plugin->dll, events[i].func_name);
- if (func)
- register_plugin_event(func, events[i].event_name);
- else
- ShowError("Failed to locate function '%s' in '%s'.\n", events[i].func_name, filename);
- }
- i++;
- }
- }
- //else ShowDebug("plugin_open: plugin_event_table not found\n");
-
- plugin->next = plugin_head;
- plugin_head = plugin;
-
- plugin->state = init_flag; // fully loaded
- ShowStatus("Done loading plugin '"CL_WHITE"%s"CL_RESET"'\n", (info) ? plugin->info->name : filename);
-
- return plugin;
-}
-
-void plugin_load(const char* filename)
-{
- plugin_open(filename);
-}
-
-void plugin_unload(Plugin* plugin)
-{
- if( plugin == NULL )
- return;
- if( plugin->filename )
- aFree(plugin->filename);
- if( plugin->dll )
- DLL_CLOSE(plugin->dll);
- aFree(plugin);
-}
-
-#ifdef WIN32
-char *DLL_ERROR(void)
-{
- static char dllbuf[80];
- DWORD dw = GetLastError();
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, 0, dllbuf, 80, NULL);
- return dllbuf;
-}
-#endif
-
-////// Initialize/Finalize ////////////////////
-
-static int plugins_config_read(const char *cfgName)
-{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- fp = fopen(cfgName, "r");
- if( fp == NULL ){
- ShowError("File not found: %s\n", cfgName);
- return 1;
- }
- while( fgets(line, sizeof(line), fp) )
- {
- if( line[0] == '/' && line[1] == '/' )
- continue;
- if( sscanf(line,"%[^:]: %[^\r\n]",w1,w2) != 2 )
- continue;
-
- if( strcmpi(w1,"auto_search") == 0 ){
- if( strcmpi(w2,"yes") == 0 )
- auto_search = 1;
- else if( strcmpi(w2,"no") == 0 )
- auto_search = 0;
- else
- auto_search = atoi(w2);
- } else if( strcmpi(w1,"plugin") == 0 ){
- char filename[128];
- sprintf(filename, "plugins/%s%s", w2, DLL_EXT);
- plugin_load(filename);
- } else if( strcmpi(w1,"import") == 0 )
- plugins_config_read(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
- }
- fclose(fp);
- return 0;
-}
-
-void plugins_init(void)
-{
- // Sugested functionality:
- // add atcommands/script commands (Borf)
- char* PLUGIN_CONF_FILENAME = "conf/plugin_athena.conf";
- //ShowDebug("plugins_init()\n");
- register_plugin_func(EVENT_PLUGIN_INIT);
- register_plugin_func(EVENT_PLUGIN_FINAL);
- register_plugin_func(EVENT_ATHENA_INIT);
- register_plugin_func(EVENT_ATHENA_FINAL);
-
- // networking
- EXPORT_SYMBOL(RFIFOSKIP, SYMBOL_RFIFOSKIP);
- EXPORT_SYMBOL(WFIFOSET, SYMBOL_WFIFOSET);
- EXPORT_SYMBOL(do_close, SYMBOL_DELETE_SESSION);
- EXPORT_SYMBOL(session, SYMBOL_SESSION);
- EXPORT_SYMBOL(&fd_max, SYMBOL_FD_MAX);
- EXPORT_SYMBOL(addr_, SYMBOL_ADDR);
- // timers
- EXPORT_SYMBOL(get_uptime, SYMBOL_GET_UPTIME);
- EXPORT_SYMBOL(delete_timer, SYMBOL_DELETE_TIMER);
- EXPORT_SYMBOL(add_timer_func_list, SYMBOL_ADD_TIMER_FUNC_LIST);
- EXPORT_SYMBOL(add_timer_interval, SYMBOL_ADD_TIMER_INTERVAL);
- EXPORT_SYMBOL(add_timer, SYMBOL_ADD_TIMER);
- EXPORT_SYMBOL((void*)get_svn_revision, SYMBOL_GET_SVN_REVISION);
- EXPORT_SYMBOL(gettick, SYMBOL_GETTICK);
- // core
- EXPORT_SYMBOL(parse_console, SYMBOL_PARSE_CONSOLE);
- EXPORT_SYMBOL(&runflag, SYMBOL_RUNFLAG);
- EXPORT_SYMBOL(arg_v, SYMBOL_ARG_V);
- EXPORT_SYMBOL(&arg_c, SYMBOL_ARG_C);
- EXPORT_SYMBOL(SERVER_NAME, SYMBOL_SERVER_NAME);
- EXPORT_SYMBOL(&SERVER_TYPE, SYMBOL_SERVER_TYPE);
-
- load_priority = 1;
- plugins_config_read(PLUGIN_CONF_FILENAME);
- load_priority = 0;
-
- if( auto_search )
- findfile("plugins", DLL_EXT, plugin_load);
-
- plugin_event_trigger(EVENT_PLUGIN_INIT);
-
- return;
-}
-
-void plugins_final(void)
-{
- Plugin* plugin = plugin_head;
- Plugin* next_plugin;
- Plugin_Event_List* evl = event_head;
- Plugin_Event_List* next_evl;
- Plugin_Event* ev;
- Plugin_Event* next_ev;
-
- //ShowDebug("plugins_final()\n");
- plugin_event_trigger(EVENT_PLUGIN_FINAL);
-
- while( plugin ){
- next_plugin = plugin->next;
- plugin_unload(plugin);
- plugin = next_plugin;
- }
-
- while( evl ){
- ev = evl->events;
- while( ev ){
- next_ev = ev->next;
- aFree(ev);
- ev = next_ev;
- }
- next_evl = evl->next;
- aFree(evl->name);
- aFree(evl);
- evl = next_evl;
- }
-
- aFree(plugin_call_table);
-
- return;
-}