summaryrefslogtreecommitdiff
path: root/src/common/HPM.h
blob: 1d13a178fc50f7b9ede461933113aee16d92987b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file

#ifndef COMMON_HPM_H
#define COMMON_HPM_H

#ifndef HERCULES_CORE
#error You should never include HPM.h from a plugin.
#endif

#include "common/hercules.h"
#include "common/db.h"
#include "common/HPMi.h"

#ifdef WIN32
	#ifndef WIN32_LEAN_AND_MEAN
		#define WIN32_LEAN_AND_MEAN
	#endif
	#include <windows.h>
	#define plugin_open(x)        LoadLibraryA(x)
	#define plugin_import(x,y,z)  (z)GetProcAddress((x),(y))
	#define plugin_close(x)       FreeLibrary(x)
	#define plugin_geterror(buf)  (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buf, sizeof(buf), NULL) ? buf : "Unknown error")

	#define DLL_EXT               ".dll"
	#define DLL                   HINSTANCE
#else // ! WIN32
	#include <dlfcn.h>
	#ifdef RTLD_DEEPBIND // Certain linux distributions require this, but it's not available everywhere
		#define plugin_open(x) dlopen((x),RTLD_NOW|RTLD_DEEPBIND)
	#else // ! RTLD_DEEPBIND
		#define plugin_open(x) dlopen((x),RTLD_NOW)
	#endif // RTLD_DEEPBIND
	#define plugin_import(x,y,z)   (z)dlsym((x),(y))
	#define plugin_close(x)        dlclose(x)
	#define plugin_geterror(buf)   ((void)buf, dlerror())

	#if defined CYGWIN
		#define DLL_EXT        ".dll"
	#elif defined __DARWIN__
		#define DLL_EXT        ".dylib"
	#else
		#define DLL_EXT        ".so"
	#endif

	#define DLL                    void *

	#include <string.h> // size_t

#endif // WIN32

struct hplugin {
	DLL dll;
	unsigned int idx;
	char *filename;
	struct hplugin_info *info;
	struct HPMi_interface *hpi;
};

/**
 * Symbols shared between core and plugins.
 */
struct hpm_symbol {
	const char *name; ///< The symbol name
	void *ptr;        ///< The symbol value
};

struct hplugin_data_entry {
	unsigned int pluginID;
	unsigned int type;
	struct {
		unsigned int free : 1;
	} flag;
	void *data;
};

struct hplugin_data_store {
	struct hplugin_data_entry **array;
	unsigned int count;
};

struct HPluginPacket {
	unsigned int pluginID;
	unsigned short cmd;
	short len;
	void (*receive) (int fd);
};

struct HPMFileNameCache {
	const char *addr;
	char *name;
};

/*  */
struct HPConfListenStorage {
	unsigned int pluginID;
	char key[HPM_ADDCONF_LENGTH];
	void (*func) (const char *val);
};

/* Hercules Plugin Manager Interface */
struct HPM_interface {
	/* vars */
	unsigned int version[2];
	bool off;
	bool hooking;
	/* hooking */
	bool force_return;
	/* data */
	VECTOR_DECL(struct hplugin *) plugins;
	VECTOR_DECL(struct hpm_symbol *) symbols;
	/* packet hooking points */
	VECTOR_DECL(struct HPluginPacket) packets[hpPHP_MAX];
	/* plugin file ptr caching */
	struct {
		// This doesn't use a VECTOR because it needs to exist after the memory manager goes down.
		int count;
		struct HPMFileNameCache *data;
	} filenames;
	/* config listen */
	VECTOR_DECL(struct HPConfListenStorage) config_listeners[HPCT_MAX];
	/** Plugins requested through the command line */
	VECTOR_DECL(char *) cmdline_load_plugins;
	/* funcs */
	void (*init) (void);
	void (*final) (void);
	struct hplugin * (*create) (void);
	struct hplugin * (*load) (const char* filename);
	void (*unload) (struct hplugin* plugin);
	bool (*exists) (const char *filename);
	bool (*iscompatible) (char* version);
	void (*event) (enum hp_event_types type);
	void *(*import_symbol) (char *name, unsigned int pID);
	void (*share) (void *value, const char *name);
	void (*config_read) (void);
	char *(*pid2name) (unsigned int pid);
	unsigned char (*parse_packets) (int fd, enum HPluginPacketHookingPoints point);
	void (*load_sub) (struct hplugin *plugin);
	bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID);
	/* for custom config parsing */
	bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point);
	/* validates plugin data */
	bool (*DataCheck) (struct s_HPMDataCheck *src, unsigned int size, int version, char *name);
	void (*datacheck_init) (const struct s_HPMDataCheck *src, unsigned int length, int version);
	void (*datacheck_final) (void);

	struct hplugin_data_store *(*data_store_create) (void);
	void (*data_store_destroy) (struct hplugin_data_store *store);
	bool (*data_store_validate) (enum HPluginDataTypes type, struct hplugin_data_store **store);
	/* for server-specific HPData e.g. map_session_data */
	bool (*data_store_validate_sub) (enum HPluginDataTypes type, struct hplugin_data_store **store);
};

CMDLINEARG(loadplugin);

extern struct HPM_interface *HPM;

void hpm_defaults(void);

#endif /* COMMON_HPM_H */