<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://wiki.herc.ws/w/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.herc.ws/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jftaas</id>
		<title>Hercules Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.herc.ws/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jftaas"/>
		<link rel="alternate" type="text/html" href="https://wiki.herc.ws/wiki/Special:Contributions/Jftaas"/>
		<updated>2026-05-03T07:15:38Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.21.11</generator>

	<entry>
		<id>https://wiki.herc.ws/wiki/Hercules_Plugin_Manager</id>
		<title>Hercules Plugin Manager</title>
		<link rel="alternate" type="text/html" href="https://wiki.herc.ws/wiki/Hercules_Plugin_Manager"/>
				<updated>2014-06-04T11:14:40Z</updated>
		
		<summary type="html">&lt;p&gt;Jftaas: /* Other Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often referred to as the [[HPM]], the '''Hercules Plugin Manager''' is yet another [[Hercules Original]]&lt;br /&gt;
= Building a plugin =&lt;br /&gt;
While the [[C]] code for the plugin normally won't have discrepancies, in order to [[compile]] the plugin certain criteria must be met depending on your Operating System, there are 2 guides below, one for windows and other for everything else (which should work on any *nix distro, as well as on OSX).&lt;br /&gt;
;Windows&lt;br /&gt;
: [[Building HPM Plugin for MSVC]]&lt;br /&gt;
;All Others&lt;br /&gt;
: [[Building HPM Plugin for gcc]]&lt;br /&gt;
&lt;br /&gt;
= Creating a plugin =&lt;br /&gt;
After following the [[#Building_a_plugin|building a plugin]] guide, all thats left is for your plugin's code to be made, the following will guide you through the basics of how a [[HPM]] plugin works.&lt;br /&gt;
== HPM Events ==&lt;br /&gt;
Events are functions in a plugin that are triggered by the '''Hercules Plugin Mananger''' when they meet certain criteria.&amp;lt;br/&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;void plugin_init (void)&amp;lt;/code&amp;gt;&lt;br /&gt;
** Triggered when the server starts&lt;br /&gt;
* &amp;lt;code&amp;gt;void plugin_final (void)&amp;lt;/code&amp;gt;&lt;br /&gt;
** Triggered when the server starts to shut itself down&lt;br /&gt;
* &amp;lt;code&amp;gt;void server_ready (void)&amp;lt;/code&amp;gt;&lt;br /&gt;
** Triggered after the server is done starting, and is online.&lt;br /&gt;
* &amp;lt;code&amp;gt;void server_post_final (void)&amp;lt;/code&amp;gt;&lt;br /&gt;
** Triggered after the server's main shutdown procedures are complete, core functionality such as memory manager, timer, and sockets are still available at this point.&lt;br /&gt;
With the [[HPM]] you only need to code the events your plugin will use.&lt;br /&gt;
== HPM Hooks ==&lt;br /&gt;
In Hercules, hooking is a simple operation, it is possible to hook an infinite number of times to the over 2k hookable functions (all the interfaced ones, accounting for over 99% of map server)&amp;lt;br/&amp;gt;&lt;br /&gt;
 HPExport void plugin_init (void) {&lt;br /&gt;
 	addHookPre(&amp;quot;pc-&amp;gt;dropitem&amp;quot;,my_pc_dropitem_preHook);  /* int my_pc_dropitem_preHook(struct map_session_data *sd,int *n,int *amount) */&lt;br /&gt;
 	addHookPost(&amp;quot;pc-&amp;gt;dropitem&amp;quot;,my_pc_dropitem_postHook);/* int my_pc_dropitem_postHook(int retVal, struct map_session_data *sd,int *n,int *amount) */&lt;br /&gt;
 }&lt;br /&gt;
Hooks receive all function params as pointers, whereas the original may be&lt;br /&gt;
 int pc_dropitem(struct map_session_data *sd,int n,int amount)&lt;br /&gt;
the one for the hook shall be&lt;br /&gt;
 (struct map_session_data *sd,int *n,int *amount)&lt;br /&gt;
which allows for hooks to modify any and all data as it pleases.&amp;lt;br/&amp;gt;&lt;br /&gt;
postHooks receive one additional param, which accounts for the result of the original function,&lt;br /&gt;
 int &amp;lt;name&amp;gt;(int retVal, struct map_session_data *sd,int *n,int *amount)&lt;br /&gt;
In this case it'd allow for the postHook to react properly to what the original returned, in this case (for pc_dropitem) 0 (failure) or 1 (success)&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
== HPM @commands ==&lt;br /&gt;
The [[HPM]] makes it very simple to provide [[@commands]] through plugins.&amp;lt;br/&amp;gt;&lt;br /&gt;
You define a new atcommand exactly as it'd normally be done in {{git|src/map/atcommand.c}}&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 ACMD(sample) {//@sample command - 5 params: const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info&lt;br /&gt;
 	clif-&amp;gt;message(fd,&amp;quot;You used the @sample command!&amp;quot;);&lt;br /&gt;
 	ShowDebug(&amp;quot;I'm being run! message -&amp;gt; '%s' by '%s'\n&amp;quot;,message,sd-&amp;gt;status.name);&lt;br /&gt;
 	return true;&lt;br /&gt;
 }&lt;br /&gt;
After that you just have to link your new command, to do that you use the &amp;lt;code&amp;gt;void plugin_init (void)&amp;lt;/code&amp;gt; event.&lt;br /&gt;
 addAtcommand(&amp;quot;sample&amp;quot;,sample);&lt;br /&gt;
and voila, your plugin now adds the '''@sample''' command.&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
&lt;br /&gt;
As of [https://github.com/HerculesWS/Hercules/commit/778facb21f822cea549939c8dbee886e1cd342aa 778facb21f], atcommands loaded via plugins will overwrite default/original commands with the same name.&lt;br /&gt;
&lt;br /&gt;
== HPM Script Commands ==&lt;br /&gt;
The [[HPM]] makes it very simple to provide [[Category:Script_Command|script commands]] through plugins.&amp;lt;br/&amp;gt;&lt;br /&gt;
You define a new script command exactly as it'd normally be done in {{git|src/map/script.c}}&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 BUILDIN(sample) {//script command 'sample(num);' - 1 param: struct script_state* st&lt;br /&gt;
 	int arg = script_getnum(st,2);&lt;br /&gt;
 	ShowInfo(&amp;quot;I'm being run! arg -&amp;gt; '%d'\n&amp;quot;,arg);&lt;br /&gt;
 	return true;&lt;br /&gt;
 }&lt;br /&gt;
After that you just have to link your new script command, to do that you use the &amp;lt;code&amp;gt;void plugin_init (void)&amp;lt;/code&amp;gt; event.&lt;br /&gt;
 addScriptCommand(&amp;quot;sample&amp;quot;,&amp;quot;i&amp;quot;,sample); //note the 2nd param is this commands' arg-types (in this case, a number)&lt;br /&gt;
and voila, your plugin now adds the '''sample''' script command.&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
&lt;br /&gt;
== HPM Console Commands ==&lt;br /&gt;
The [[HPM]] makes it very simple to provide [[Category:Console_Command|console commands]] through plugins.&amp;lt;br/&amp;gt;&lt;br /&gt;
You define a new console command exactly as it'd normally be done in {{git|src/common/console.c}}&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 CPCMD(sample) {//console command 'sample' - 1 param: char *line&lt;br /&gt;
 	ShowInfo(&amp;quot;I'm being run! arg -&amp;gt; '%s'\n&amp;quot;,line?line:&amp;quot;NONE&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
After that you just have to link your new script command, to do that you use the &amp;lt;code&amp;gt;void plugin_init (void)&amp;lt;/code&amp;gt; event.&lt;br /&gt;
 addCPCommand(&amp;quot;this:is:a:sample&amp;quot;,CPCMD_A(sample)); // note the first param is the path to this command, in this case it translates to 'this is a sample' and everything afterwards is the commands' params&lt;br /&gt;
and voila, your plugin now adds the '''sample''' console command.&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
== HPM Custom Packets ==&lt;br /&gt;
The HPM makes it possible for a plugin to add or override packets within all 3 servers&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 /* sample packet implementation */&lt;br /&gt;
 /* cmd 0xf3 - it is a client-server existent id, for clif_parse_GlobalMessage */&lt;br /&gt;
 /* in this sample we do nothing and simply redirect */&lt;br /&gt;
 void sample_packet0f3(int fd) {&lt;br /&gt;
 	struct map_session_data *sd = session[fd]-&amp;gt;session_data;&lt;br /&gt;
  	&lt;br /&gt;
 	if( !sd ) return;/* socket didn't fully log-in? this packet shouldn't do anything then! */&lt;br /&gt;
 &lt;br /&gt;
 	ShowInfo(&amp;quot;sample_packet0f3: Hello World! received 0xf3 for '%s', redirecting!\n&amp;quot;,sd-&amp;gt;status.name);&lt;br /&gt;
 &lt;br /&gt;
 	clif-&amp;gt;pGlobalMessage(fd,sd);&lt;br /&gt;
 }&lt;br /&gt;
 void plugin_init(void) {&lt;br /&gt;
 	addPacket(0xf3,-1,sample_packet0f3,hpClif_Parse);&lt;br /&gt;
 }&lt;br /&gt;
and voila, your plugin just changed the map server's '''0xf3''' packet to pass by '''sample_packet0f3''' prior to being sent to '''clif_parse_GlobalMessage'''&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
&lt;br /&gt;
== HPM Custom Data Structs ==&lt;br /&gt;
The HPM makes it possible for a plugin to create and append structs to existent data, this feature is currently supported on player units (map_session_data) and network pipes (socket_data)&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 /* can be of any size, using any data types */&lt;br /&gt;
 struct sample_data_struct {&lt;br /&gt;
 	struct point lastMSGPosition;&lt;br /&gt;
 	unsigned int someNumber;&lt;br /&gt;
 };&lt;br /&gt;
 /* appends/reads sample_data_struct in a network session data entry (socket_data) */&lt;br /&gt;
 void some_function_receiving_a_socket_fd(int fd) {&lt;br /&gt;
 	struct sample_data_struct *data;&lt;br /&gt;
 &lt;br /&gt;
 	if( !(data = HPMi-&amp;gt;getFromSession(session[fd],HPMi-&amp;gt;pid,0)) ) {&lt;br /&gt;
 		CREATE(data,struct sample_data_struct,1);&lt;br /&gt;
 		&lt;br /&gt;
 		data-&amp;gt;lastMSGPosition.map = 1;&lt;br /&gt;
 		data-&amp;gt;lastMSGPosition.x = 150;&lt;br /&gt;
 		data-&amp;gt;lastMSGPosition.y = 150;&lt;br /&gt;
 		data-&amp;gt;someNumber = rand()%777;&lt;br /&gt;
 		&lt;br /&gt;
 		ShowInfo(&amp;quot;Created Appended session[] data, %d %d %d %d\n&amp;quot;,data-&amp;gt;lastMSGPosition.map,data-&amp;gt;lastMSGPosition.x,data-&amp;gt;lastMSGPosition.y,data-&amp;gt;someNumber);&lt;br /&gt;
 		HPMi-&amp;gt;addToSession(session[fd],data,HPMi-&amp;gt;pid,0,true);&lt;br /&gt;
 	} else {&lt;br /&gt;
 		ShowInfo(&amp;quot;Existent Appended session[] data, %d %d %d %d\n&amp;quot;,data-&amp;gt;lastMSGPosition.map,data-&amp;gt;lastMSGPosition.x,data-&amp;gt;lastMSGPosition.y,data-&amp;gt;someNumber);&lt;br /&gt;
 		if( rand()%4 == 2 ) {&lt;br /&gt;
 			ShowInfo(&amp;quot;Removing Appended session[] data\n&amp;quot;);&lt;br /&gt;
 			HPMi-&amp;gt;removeFromSession(session[fd],HPMi-&amp;gt;pid,0);&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
and voila, your plugin becomes capable of appending and handling your custom struct data&amp;lt;br/&amp;gt;&lt;br /&gt;
A full usage of this is demonstrated in the [[HPM]]'s sample {{git|src/plugins/sample.c}}&lt;br /&gt;
== HPM Function Overloading ==&lt;br /&gt;
Thanks to [[Hercules Renewal Phase One]], you're capable of overloading all functions covered by the [[Hercules Renewal Phase One]] interfaces, with your plugin.&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example:'''&lt;br /&gt;
 int my_custom_check_target_function( struct block_list *src, struct block_list *target,int flag) {&lt;br /&gt;
 	//&amp;lt;...&amp;gt; code&lt;br /&gt;
 }&lt;br /&gt;
 void server_ready(void) {&lt;br /&gt;
 	battle = GET_SYMBOL(&amp;quot;battle&amp;quot;);&lt;br /&gt;
 	battle-&amp;gt;check_target = &amp;amp;my_custom_check_target_function;&lt;br /&gt;
 }&lt;br /&gt;
and voila, your plugin just overloaded the game server's '''battle_check_target''' function with your plugin's own, this is greatly handy to ensure your customs do not create conflicts when updating your [[Hercules|Hercules Repository]]&lt;br /&gt;
= Other Features =&lt;br /&gt;
Is there something you'd like to do with your plugin that requires modifications to [[HPM]]'s core? [http://hercules.ws/board/forum/55-suggestions/ let us know], and we'll do our best to make it happen.&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://hercules.ws/board/forum/55-suggestions/ Post your suggestions here]&lt;br /&gt;
&lt;br /&gt;
= Support =&lt;br /&gt;
Need help writing your plugin? [http://hercules.ws/board/forum/26-source-support/ post your question on our support forum]&lt;/div&gt;</summary>
		<author><name>Jftaas</name></author>	</entry>

	</feed>