summaryrefslogtreecommitdiff
path: root/src/plugins/sample.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sample.c')
-rw-r--r--src/plugins/sample.c155
1 files changed, 140 insertions, 15 deletions
diff --git a/src/plugins/sample.c b/src/plugins/sample.c
index 7f7528cb7..84df88e06 100644
--- a/src/plugins/sample.c
+++ b/src/plugins/sample.c
@@ -3,10 +3,19 @@
// Sample Hercules Plugin
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+
#include "../common/HPMi.h"
-#include "../map/script.h"
+#include "../common/malloc.h"
+#include "../common/mmo.h"
+#include "../common/socket.h"
+#include "../common/strlib.h"
+#include "../map/clif.h"
#include "../map/pc.h"
+#include "../map/script.h"
+
+#include "../common/HPMDataCheck.h" /* should always be the last file included! (if you don't make it last, it'll intentionally break compile time) */
HPExport struct hplugin_info pinfo = {
"Sample", // Plugin name
@@ -26,18 +35,108 @@ BUILDIN(sample) {//script command 'sample(num);' - 1 param: struct script_state*
CPCMD(sample) {//console command 'sample' - 1 param: char *line
ShowInfo("I'm being run! arg -> '%s'\n",line?line:"NONE");
}
-struct script_interface *script;/* used by script commands */
+struct sample_data_struct {
+ struct point lastMSGPosition;
+ unsigned int someNumber;
+};
+
+/* sample packet implementation */
+/* cmd 0xf3 - it is a client-server existent id, for clif_parse_GlobalMessage */
+/* in this sample we do nothing and simply redirect */
+void sample_packet0f3(int fd) {
+ struct map_session_data *sd = session[fd]->session_data;
+ struct sample_data_struct *data;
+
+ if( !sd ) return;/* socket didn't fully log-in? this packet shouldn't do anything then! */
+
+ ShowInfo("sample_packet0f3: Hello World! received 0xf3 for '%s', redirecting!\n",sd->status.name);
+
+ /* sample usage of appending data to a socket_data (session[]) entry */
+ if( !(data = getFromSession(session[fd],0)) ) {
+ CREATE(data,struct sample_data_struct,1);
+
+ data->lastMSGPosition.map = sd->status.last_point.map;
+ data->lastMSGPosition.x = sd->status.last_point.x;
+ data->lastMSGPosition.y = sd->status.last_point.y;
+ data->someNumber = rand()%777;
+
+ ShowInfo("Created Appended session[] data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber);
+ addToSession(session[fd],data,0,true);
+ } else {
+ ShowInfo("Existent Appended session[] data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber);
+ if( rand()%4 == 2 ) {
+ ShowInfo("Removing Appended session[] data\n");
+ removeFromSession(session[fd],0);
+ }
+ }
+
+ /* sample usage of appending data to a map_session_data (sd) entry */
+ if( !(data = getFromMSD(sd,0)) ) {
+ CREATE(data,struct sample_data_struct,1);
+
+ data->lastMSGPosition.map = sd->status.last_point.map;
+ data->lastMSGPosition.x = sd->status.last_point.x;
+ data->lastMSGPosition.y = sd->status.last_point.y;
+ data->someNumber = rand()%777;
+
+ ShowInfo("Created Appended map_session_data data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber);
+ addToMSD(sd,data,0,true);
+ } else {
+ ShowInfo("Existent Appended map_session_data data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber);
+ if( rand()%4 == 2 ) {
+ ShowInfo("Removing Appended map_session_data data\n");
+ removeFromMSD(sd,0);
+ }
+ }
+
+
+ clif->pGlobalMessage(fd,sd);
+}
+int my_pc_dropitem_storage;/* storage var */
+/* my custom prehook for pc_dropitem, checks if amount of item being dropped is higher than 1 and if so cap it to 1 and store the value of how much it was */
+int my_pc_dropitem_pre(struct map_session_data *sd,int *n,int *amount) {
+ my_pc_dropitem_storage = 0;
+ if( *amount > 1 ) {
+ my_pc_dropitem_storage = *amount;
+ *amount = 1;
+ }
+ return 0;
+}
+/* postHook receive retVal as the first param, allows posthook to act accordingly to whatever the original was going to return */
+int my_pc_dropitem_post(int retVal, struct map_session_data *sd,int *n,int *amount) {
+ if( retVal != 1 ) return retVal;/* we don't do anything if pc_dropitem didn't return 1 (success) */
+ if( my_pc_dropitem_storage ) {/* signs whether pre-hook did this */
+ char output[99];
+ safesnprintf(output,99,"[ Warning ] you can only drop 1 item at a time, capped from %d to 1",my_pc_dropitem_storage);
+ clif->colormes(sd->fd,COLOR_RED,output);
+ }
+ return 1;
+}
+void parse_my_setting(const char *val) {
+ ShowDebug("Received 'my_setting:%s'\n",val);
+ /* do anything with the var e.g. config_switch(val) */
+}
/* run when server starts */
HPExport void plugin_init (void) {
char *server_type;
char *server_name;
-
- //get the symbols from the server
+
+ /* core vars */
server_type = GET_SYMBOL("SERVER_TYPE");
server_name = GET_SYMBOL("SERVER_NAME");
+ /* core interfaces */
+ iMalloc = GET_SYMBOL("iMalloc");
+
+ /* map-server interfaces */
script = GET_SYMBOL("script");
-
+ clif = GET_SYMBOL("clif");
+ pc = GET_SYMBOL("pc");
+ strlib = GET_SYMBOL("strlib");
+
+ /* session[] */
+ session = GET_SYMBOL("session");
+
ShowInfo ("Server type is ");
switch (*server_type) {
@@ -48,17 +147,43 @@ HPExport void plugin_init (void) {
ShowInfo ("I'm being run from the '%s' filename\n", server_name);
- if( HPMi->addCommand != NULL ) {//link our '@sample' command
- HPMi->addCommand("sample",ACMD_A(sample));
- }
+ /* addAtcommand("command-key",command-function) tells map server to call ACMD(sample) when "sample" command is used */
+ /* - it will print a warning when used on a non-map-server plugin */
+ addAtcommand("sample",sample);//link our '@sample' command
- if( HPMi->addScript != NULL ) {//link our 'sample' script command
- HPMi->addScript("sample","i",BUILDIN_A(sample));
- }
+ /* addScriptCommand("script-command-name","script-command-params-info",script-function) tells map server to call BUILDIN(sample) for the "sample(i)" command */
+ /* - it will print a warning when used on a non-map-server plugin */
+ addScriptCommand("sample","i",sample);
- if( HPMi->addCPCommand != NULL ) {//link our 'sample' console command
- HPMi->addCPCommand("this:is:a:sample",CPCMD_A(sample));
- }
+ /* addCPCommand("console-command-name",command-function) tells server to call CPCMD(sample) for the 'this is a sample <optional-args>' console call */
+ /* in "console-command-name" usage of ':' indicates a category, for example 'this:is:a:sample' translates to 'this is a sample',
+ * therefore 'this -> is -> a -> sample', it can be used to aggregate multiple commands under the same category or to append commands to existing categories
+ * categories inherit the special keyword 'help' which prints the subsequent commands, e.g. 'server help' prints all categories and commands under 'server'
+ * therefore 'this help' would inform about 'is (category) -> a (category) -> sample (command)'*/
+ addCPCommand("this:is:a:sample",sample);
+
+ /* addPacket(packetID,packetLength,packetFunction,packetIncomingPoint) */
+ /* adds packetID of packetLength (-1 for dynamic length where length is defined in the packet { packetID (2 Byte) , packetLength (2 Byte) , ... })
+ * to trigger packetFunction in the packetIncomingPoint section ( available points listed in enum HPluginPacketHookingPoints within src/common/HPMi.h ) */
+ addPacket(0xf3,-1,sample_packet0f3,hpClif_Parse);
+
+ /* in this sample we add a PreHook to pc->dropitem */
+ /* to identify whether the item being dropped is on amount higher than 1 */
+ /* if so, it stores the amount on a variable (my_pc_dropitem_storage) and changes the amount to 1 */
+ addHookPre("pc->dropitem",my_pc_dropitem_pre);
+
+ /* in this sample we add a PostHook to pc->dropitem */
+ /* if the original pc->dropitem was successful and the amount stored on my_pc_dropitem_storage is higher than 1, */
+ /* our posthook will display a message to the user about the cap */
+ /* - by checking whether it was successful (retVal value) it allows for the originals conditions to take place */
+ addHookPost("pc->dropitem",my_pc_dropitem_post);
+}
+/* triggered when server starts loading, before any server-specific data is set */
+HPExport void server_preinit (void) {
+ /* makes map server listen to mysetting:value in any "battleconf" file (including imported or custom ones) */
+ /* value is not limited to numbers, its passed to our plugins handler (parse_my_setting) as const char *,
+ * and thus can be manipulated at will */
+ addBattleConf("my_setting",parse_my_setting);
}
/* run when server is ready (online) */
HPExport void server_online (void) {
@@ -67,4 +192,4 @@ HPExport void server_online (void) {
/* run when server is shutting down */
HPExport void plugin_final (void) {
ShowInfo ("%s says ~Bye world\n",pinfo.name);
-} \ No newline at end of file
+}