Jump to content
  • 0
Like it~*

Plugin errors

Question

autopots.c

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../common/HPMi.h"
#include "../common/timer.h"
#include "../map/script.h"
#include "../map/pc.h"
#include "../map/map.h"
#include "../map/unit.h"
#include "../map/atcommand.h"
#include "../map/itemdb.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) */

#define OPTION_AUTOPOTS 0x40000000


/*
3.1 Plugins Release [Mhalicot]
3.2 Update to Latest Revision [Mhalicot]
4.0 Added autohp, autosp command Rev. 137* [Mhalicot]
4.1 Fixed Compilation error. Rev. 145*** [Mhalicot]
-----------------------------------------------------
Documentation
@autopots <hp_rate> <hp_item id> <sp_rate> <sp_item id>
@autohp <hp_rate> <hp_item id>
@autosp <sp_rate> <sp_item id
// Change autopots/hp/sp timer by replacing +500 in milisec
		timer->add(timer->gettick()+500,autoatpots_timer,sd->bl.id,0);
*/
HPExport struct hplugin_info pinfo = {  
	"autopots",		// Plugin name
	SERVER_TYPE_MAP,	// Which server types this plugin works with?
	"4.0",				// Plugin version
	HPM_VERSION,		// HPM Version (don't change, macro is automatically updated)
};
struct autopots {
unsigned int hp_rate, sp_rate, hp_nameid, sp_nameid;
};
struct autopots autopots;
void autoatpots_clean(struct map_session_data *sd)
{
	if( sd )
	{
		sd->sc.option &= ~OPTION_AUTOPOTS;
		autopots.hp_nameid = 0;
		autopots.hp_rate = 0;
		autopots.sp_nameid = 0;
		autopots.sp_rate = 0;
		clif->changeoption(&sd->bl);
	}
	return;
}
void autoathp_clean(struct map_session_data *sd)
{
	if( sd )
	{
		sd->sc.option &= ~OPTION_AUTOPOTS;
		autopots.hp_nameid = 0;
		autopots.hp_rate = 0;
		clif->changeoption(&sd->bl);
	}
	return;
}
void autoatsp_clean(struct map_session_data *sd)
{
	if( sd )
	{
		sd->sc.option &= ~OPTION_AUTOPOTS;
		autopots.sp_nameid = 0;
		autopots.sp_rate = 0;
		clif->changeoption(&sd->bl);
	}
	return;
}
int autoatpots_timer(int tid, int64 tick, int id, intptr_t data)
{
	struct map_session_data *sd=NULL;
	struct item_data* item = NULL;
	int index;
	sd=map->id2sd(id);
	if( sd == NULL )
		return 0;
	if(sd->sc.option & OPTION_AUTOPOTS)
	{
		unsigned int hp_rate = autopots.hp_rate;
		unsigned int sp_rate = autopots.sp_rate;
		unsigned int hp_nameid = autopots.hp_nameid;
		unsigned int sp_nameid = autopots.sp_nameid;
		if( ( !sp_rate && !hp_rate ) || pc_isdead(sd) )
		{
			if( !hp_rate ) 
			{
				clif->message(sd->fd, "Auto-SP : OFF_");
				autoatsp_clean(sd);
				return 0;
			}else
			if( !sp_rate )
			{
				clif->message(sd->fd, "Auto-HP : OFF_");
				autoathp_clean(sd);
				return 0;
			}
		else{
			clif->message(sd->fd, "Auto-pots : OFF_");
			autoatpots_clean(sd);
			return 0;
			}
		}

		if( ( sd->battle_status.hp*100/sd->battle_status.max_hp ) < hp_rate && hp_nameid && hp_rate )
		{
			ARR_FIND(0, MAX_INVENTORY, index, sd->status.inventory[index].nameid == hp_nameid);
			if( sd->status.inventory[index].nameid == hp_nameid )
				pc->useitem(sd,index);
		}
		if( ( sd->battle_status.sp*100/sd->battle_status.max_sp ) < sp_rate && sp_nameid && sp_rate )
		{
			ARR_FIND(0, MAX_INVENTORY, index, sd->status.inventory[index].nameid == sp_nameid);
			if( sd->status.inventory[index].nameid == sp_nameid )
				pc->useitem(sd,index);
		}
		timer->add(timer->gettick()+500,autoatpots_timer,sd->bl.id,0);
	}
	return 0;
}
ACMD(autopots)
{
	int hp_rate=0, hp_nameid=0, sp_rate=0, sp_nameid=0;
	if( !sd ) return 0;

	if ( !message || !*message || (
		sscanf_s(message, "%d %d %d %d ", &hp_rate, &hp_nameid, &sp_rate, &sp_nameid) < 4) ||
		( hp_rate < 0 || hp_rate > 99 ) ||
		( sp_rate < 0 || sp_rate > 99 ) )
	{
		if ( sscanf_s(message, "%d %d %d %d ", &hp_rate, &hp_nameid, &sp_rate, &sp_nameid) < 4 &&
			sscanf_s(message, "%d %d %d %d ", &hp_rate, &hp_nameid, &sp_rate, &sp_nameid) > 0)
		{
			clif->message(fd, "@autopots <hp_rate> <hp_item id> <sp_rate> <sp_item id>");
			return false;
		}
		clif->message(fd, "Auto-pots : OFF");
		autoatpots_clean(sd);
		return true;
	}

	if (sd->sc.option & OPTION_AUTOPOTS)
	{
		autoatpots_clean(sd);
	}
	if( hp_rate == 0 ) hp_nameid = 0;
	if( sp_rate == 0 ) sp_nameid = 0;
	if( hp_nameid == 0 ) hp_rate = 0;
	if( sp_nameid == 0 ) sp_rate = 0;
	if( itemdb->exists(hp_nameid) == NULL && hp_nameid )
	{
		hp_nameid = 0;
		hp_rate = 0;
		clif->message(fd, "Auto-pots : Invalid item for HP");
	}
	if( itemdb->exists(sp_nameid) == NULL && sp_nameid )
	{
		sp_nameid = 0;
		sp_rate = 0;
		clif->message(fd, "Auto-pots : Invalid item for SP");
		return true;
	}
	clif->message(fd, "Auto-pots : ON");
	sd->sc.option |= OPTION_AUTOPOTS;
	autopots.hp_nameid = hp_nameid;
	autopots.hp_rate = hp_rate;
	autopots.sp_nameid = sp_nameid;
	autopots.sp_rate = sp_rate;
	timer->add(timer->gettick()+200,autoatpots_timer,sd->bl.id,0);

	clif->changeoption(&sd->bl);
	return true;
}
ACMD(autohp)
{
	int hp_rate=0, hp_nameid=0;
	if( !sd ) return 0;

	if (!message || !*message || (
		sscanf_s(message, "%d %d ", &hp_rate, &hp_nameid) < 2) ||
		( hp_rate < 0 || hp_rate > 99 ) )
	{
		if ( sscanf_s(message, "%d %d ", &hp_rate, &hp_nameid) < 2 &&
			sscanf_s(message, "%d %d ", &hp_rate, &hp_nameid) > 0) 
		{
			clif->message(fd, "@autohp <hp_rate> <hp_item id>");
			return true;
		}
		clif->message(fd, "Auto-HP : OFF");
		autoathp_clean(sd);
		return true;
	}

	if (sd->sc.option & OPTION_AUTOPOTS)
	{
		autoathp_clean(sd);
	}
	if( hp_rate == 0 ) hp_nameid = 0;
	if( hp_nameid == 0 ) hp_rate = 0;
	if( itemdb->exists(hp_nameid) == NULL && hp_nameid )
	{
		hp_nameid = 0;
		hp_rate = 0;
		clif->message(fd, "Auto-HP : Invalid item for HP");
		return true;
	}
	clif->message(fd, "Auto-HP : ON");
	sd->sc.option |= OPTION_AUTOPOTS;
	autopots.hp_nameid = hp_nameid;
	autopots.hp_rate = hp_rate;
	timer->add(timer->gettick()+200,autoatpots_timer,sd->bl.id,0);

	clif->changeoption(&sd->bl);
	return true;
}
ACMD(autosp)
{
	int sp_rate=0, sp_nameid=0;
	if( !sd ) return 0;

	if (!message || !*message || (
		sscanf_s(message, "%d %d ", &sp_rate, &sp_nameid) < 2) ||
		( sp_rate < 0 || sp_rate > 99 ) )
	{
		if ( sscanf_s(message, "%d %d ", &sp_rate, &sp_nameid) < 2 &&
			sscanf_s(message, "%d %d ", &sp_rate, &sp_nameid) > 0) 
		{
			clif->message(fd, "@autosp <sp_rate> <sp_item id>");
			return true;
		}
		clif->message(fd, "Auto-SP : OFF");
		autoatsp_clean(sd);
		return true;
	}

	if (sd->sc.option & OPTION_AUTOPOTS)
	{
		autoatsp_clean(sd);
	}
	if( sp_rate == 0 ) sp_nameid = 0;
	if( sp_nameid == 0 ) sp_rate = 0;
	if( itemdb->exists(sp_nameid) == NULL && sp_nameid )
	{
		sp_nameid = 0;
		sp_rate = 0;
		clif->message(fd, "Auto-SP : Invalid item for SP");
		return true;
	}
	clif->message(fd, "Auto-SP : ON");
	sd->sc.option |= OPTION_AUTOPOTS;
	autopots.sp_nameid = sp_nameid;
	autopots.sp_rate = sp_rate;
	timer->add(timer->gettick()+200,autoatpots_timer,sd->bl.id,0);

	clif->changeoption(&sd->bl);
	return true;
}
/* Server Startup */
HPExport void plugin_init (void)
{
	clif = GET_SYMBOL("clif");
    script = GET_SYMBOL("script");
	pc = GET_SYMBOL("pc");
	atcommand = GET_SYMBOL("atcommand");
	map = GET_SYMBOL("map");
	unit = GET_SYMBOL("unit");
	timer = GET_SYMBOL("timer");
	itemdb = GET_SYMBOL("itemdb");

	addAtcommand("autopots",autopots);//link our '@autopots' command
	addAtcommand("autohp",autohp);//link our '@autohp' command
	addAtcommand("autosp",autosp);//link our '@autosp' command
}

 

 

 

maintenance.c

 

 

//===== Hercules Plugin ======================================
//= @Maintenance mod
//===== By: ==================================================
//= AnnieRuru
//===== Current Version: =====================================
//= 1.4
//===== Compatible With: ===================================== 
//= Hercules 2015-12-08
//===== Description: =========================================
//= Turn the server into maintenance mode.
//= -> blocked players from login the game for a set of duration
//= a GM will announce the maintenance, and players will be kicked out after a while for maintenance. 
//= Player below {Group ID can login} will not able to login for the duration
//= but GM99 can always login without restriction
//===== Topic ================================================
//= http://hercules.ws/board/topic/7127-
//===== Additional Comments: =================================  
//= -- AtCommands --
//= @maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>
//= @maintenanceoff
//=
//= -- Script Commands --
//= maintenance <Group ID can stay 1~99>, <duration to kick in minute>, <maintenance duration in minute> { , <reason> };
//=   reason field is optional, default to '*Regular server maintenance*'
//= maintenanceoff { <reason> };
//=   reason field is optional, default to '*maintenanceoff*'
//= maintenancecheck( <type> );
//=   default:
//=	    return 0 if server is normal
//=	    return 1 if server is going to have maintenance
//=	    return 2 if server is having maintenance
//=   type 1:
//=	    return the Group ID that has been denied to login
//=   type 2:
//=     return the time stamp of last/current starting time for the maintenance
//=   type 3:
//=     return the time stamp of last/current ending time for the maintenance
//=   type 4:
//=     return the ID of last used maintenance_countid ( for debugging only )
//=   type 5:
//=     return the ID of last used maintenance_timerid ( for debugging only )
//============================================================

/*	Remember to build a Sql table !
create table maintenance (
	id int(11) primary key auto_increment,
	account_id int(11),
	name varchar(23),
	reason varchar(99),
	minlv2connect tinyint(4),
	order_time datetime,
	start_time datetime,
	end_time datetime
) engine = innodb;
*/

//	change the announcement color
int maintenance_color = 0xFFFF00;
//	If you still want to personalize each announcement to different color, just Ctrl+F 'maintenance_color' below

//	==========================================================

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "common/hercules.h"
#include "map/pc.h"
#include "map/map.h"
#include "map/intif.h"
#include "login/login.h"
#include "common/timer.h"
#include "common/strlib.h"
#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/sql.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"maintenance",	// Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"1.4",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

int maintenance_group = 1;
int maintenance_starttime = 1;
int maintenance_endtime = 1;
int maintenance_countid = INVALID_TIMER;
int maintenance_timerid = INVALID_TIMER;
char maintenance_timeformat[24];

int maintenance_progress( int tid, int64 tick, int id, intptr data ) {
	char output[CHAT_SIZE_MAX];
	timer->delete( maintenance_timerid, maintenance_progress );
	maintenance_timerid = INVALID_TIMER;
	safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode has ended. Players are able to login now." );
	intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	ShowStatus( CL_YELLOW "Maintenance has ended." CL_RESET "\n" );
	return false;
}

int maintenance_countdown( int tid, int64 tick, int id, intptr data ) {
	char output[CHAT_SIZE_MAX];
	int countdown = maintenance_starttime - (int)time(NULL);
	if ( countdown > 90 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d minutes", countdown /60 );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		if ( ( countdown % 60 ) > 0 ) // fine tune the timer
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 60 ) * 1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 60000, maintenance_countdown, 0, 0 );
	}
	else if ( countdown > 15 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d seconds", countdown );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		if ( ( countdown % 10 ) > 0 ) // fine tune the timer
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 10 ) * 1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 10000, maintenance_countdown, 0, 0 );
	}
	else if ( countdown > 0 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d seconds", countdown );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = timer->add( timer->gettick() + 1000, maintenance_countdown, 0, 0 );
	}
	else {
		struct s_mapiterator* iter = mapit->alloc( MAPIT_NORMAL, BL_PC );
		TBL_PC *sd;
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance starts now. Every player will be kick out." );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		for ( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) )
			if ( sd->group_id < maintenance_group )
				clif->authfail_fd( sd->fd, 1 );
		mapit->free(iter);
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
		maintenance_timerid = timer->add( timer->gettick() + ( ( maintenance_endtime - maintenance_starttime )*1000 ), maintenance_progress, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance has started." CL_RESET "\n" );
	}
	return false;
}

HPExport void server_online (void) {
	if ( SQL->Query( map->mysql_handle, "select minlv2connect, unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR )
		Sql_ShowDebug( map->mysql_handle );
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		short weekday = 0, hour = 0, minute = 0;
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3], min_display[3];
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_group = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 5, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
	}
	if ( maintenance_starttime > (int)time(NULL) ) {
		int countdown = maintenance_starttime - (int)time(NULL);
		if ( countdown > 60 )
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 60 )*1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 1000, maintenance_countdown, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance will start in %d min %d sec." CL_RESET "\n", countdown /60, countdown %60 );
	}
	else if ( maintenance_endtime > (int)time(NULL) ) {
		int countdown = maintenance_endtime - (int)time(NULL);
		maintenance_timerid = timer->add( timer->gettick() + ( countdown *1000 ), maintenance_progress, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance will end in %d min %d sec on %s." CL_RESET "\n", countdown/60, countdown %60, maintenance_timeformat );
	}
}

bool pc_authok_pre( struct map_session_data *sd, int *login_id2, time_t *expiration_time, int *group_id, struct mmo_charstatus *st, bool *changing_mapservers ) {
	nullpo_retr( false, sd );
	if ( (int)time(NULL) > maintenance_starttime && maintenance_endtime > (int)time(NULL) && *group_id < maintenance_group ) {
		clif->authfail_fd( sd->fd, 1 );
		hookStop();
		return false;
	}
	return true;
}

void clif_parse_LoadEndAck_pre( int *fd, struct map_session_data *sd ) {
	nullpo_retv(sd);
	if ( sd->state.connect_new ) {
		if ( maintenance_starttime > (int)time(NULL) ) {
			char output[CHAT_SIZE_MAX];
			safesnprintf( output, CHAT_SIZE_MAX, "Maintenance starts in %d min %d sec, last %d minutes. Server up by %s", ( maintenance_starttime - (int)time(NULL) ) /60, ( maintenance_starttime - (int)time(NULL) ) %60, ( maintenance_endtime - maintenance_starttime ) /60, maintenance_timeformat );
			clif->message( sd->fd, output );
		}
		else if ( maintenance_endtime > (int)time(NULL) ) {
			char output[CHAT_SIZE_MAX];
			safesnprintf( output, CHAT_SIZE_MAX, "Server is currently in maintenance mode, will end in %d min %d sec on %s", ( maintenance_endtime - (int)time(NULL) ) /60, ( maintenance_endtime - (int)time(NULL) ) %60, maintenance_timeformat );
			clif->message( sd->fd, output );
		}
	}
	return;
}

ACMD(maintenance) {
	int group_id = 0, kick_duration = 0, maintenance_duration = 0;
	char reason[99], esc_reason[198], esc_name[46], min_display[3], output[CHAT_SIZE_MAX];
	short weekday = 0, hour = 0, minute = 0;
	if ( maintenance_starttime > (int)time(NULL) ) {
		int countdown = maintenance_starttime - (int)time(NULL);
		clif->message( sd->fd, "Type '@maintenanceoff' to turn off maintenance mode." );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will start in %d min %d sec.", countdown /60, countdown %60 );
		clif->message( sd->fd, output );
		return true;
	}
	if ( maintenance_endtime > (int)time(NULL) ) {
		int countdown = maintenance_endtime - (int)time(NULL);
		clif->message( sd->fd, "Type '@maintenanceoff' to turn off maintenance mode." );
		safesnprintf( output, CHAT_SIZE_MAX, "Server is currently in maintenance mode, will end in %d min %d sec on %s", countdown /60, countdown %60, maintenance_timeformat );
		clif->message( sd->fd, output );
		return true;
	}
	if ( !message || !*message ) {
		clif->message( sd->fd, "@maintenance Syntax :" );
		clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
		return false;
	}
//	WTF ! sscanf can't be used ??
//	if ( sscanf( message, "%d %d %d %99[^\n]", &group_id, &kick_duration, &maintenance_duration, &reason ) < 4 ) {
//		clif->message( sd->fd, "@maintenance Syntax :" );
//		clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
//		return false;
//	}
//	now has to do the stupid string calculation 
	{
		int i = 0, j = 0, k = 0, l = strlen( message );
		char *temp = (char*)aMalloc( strlen( message ) +1 );
		while ( i <= l && k < 3 ) {
			if ( message[i] != ' ' && message[i] != '\0' ) {
				temp[j++] = message[i];
			}
			else if ( message[i-1] != ' ' ) {
				temp[j] = '\0';
				if ( k == 0 )
					group_id = atoi( temp );
				else if ( k == 1 )
					kick_duration = atoi( temp );
				else if ( k == 2 )
					maintenance_duration = atoi( temp );
				k++;
				j = 0;
			}
			i++;
		}
		safestrncpy( reason, &message[i], 99 );
		aFree( temp );
		if ( k < 3 ) {
			clif->message( sd->fd, "@maintenance Syntax :" );
			clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
			return false;
		}
	}
	if ( !group_id ) {
		clif->message( sd->fd, "The Group ID field cannot be 0, otherwise normal player able to login." );
		return false;
	}
	if ( group_id < 1 || group_id > 99 ) {
		safesnprintf( output, 255, "Invalid Group ID %d. Range must between 1~99.", group_id );
		clif->message( sd->fd, output );
		return false;
	}
	if ( kick_duration <= 0 ) {
		clif->message( sd->fd, "Kick duration cannot be 0 or negative numbers." );
		return false;
	}
	if ( kick_duration > 1440 ) {
		clif->message( sd->fd, "Kick duration cannot be more than 1 day." );
		return false;
	}
	if ( maintenance_duration <= 0 ) {
		clif->message( sd->fd, "Maintenance duration cannot be 0 or negative numbers." );
		return false;
	}
	if ( maintenance_duration > 10080 ) {
		clif->message( sd->fd, "Maintenance duration cannot be more than 1 week." );
		return false;
	}
	if ( safestrnlen( reason, 99 ) < 4 ) {
		clif->message( sd->fd, "You must input a valid reason for doing this." );
		return false;
	}
	SQL->EscapeString( map->mysql_handle, esc_name, sd->status.name );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, %d, '%s', '%s', %d, now(), timestampadd( minute, %d, now() ), timestampadd( minute, %d, now() ) )", sd->status.account_id, esc_name, esc_reason, group_id, kick_duration, kick_duration + maintenance_duration ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	if ( SQL->Query( map->mysql_handle, "select unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		maintenance_group = group_id;
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		SQL->FreeResult( map->mysql_handle );
	}
	else {
		SQL->FreeResult( map->mysql_handle );
		return false;
	}
	{	// stupid date_format doesn't work
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3];
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will be commence in %d minutes. Players are adviced to log out right now. Maintenance last %d minutes. Server will come back up on %s", kick_duration, maintenance_duration, maintenance_timeformat );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	}
	maintenance_countid = timer->add( timer->gettick() +( ( kick_duration == 1 )? 1000 : 60000 ), maintenance_countdown, 0, 0 );
	ShowStatus( CL_YELLOW "Maintenance will start in %d min by " CL_GREEN "%s" CL_RESET ".\n", kick_duration, sd->status.name );
	return true;
}

ACMD(maintenanceoff) {
	char esc_name[46], output[CHAT_SIZE_MAX];
	if ( maintenance_endtime <= (int)time(NULL) ) {
		clif->message( sd->fd, "The server is currently in not in maintenance mode." );
		return true;
	}
	SQL->EscapeString( map->mysql_handle, esc_name, sd->status.name );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, %d, '%s', '   @maintenanceoff', 0, null, now(), now() )", sd->status.account_id, esc_name ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	if ( maintenance_countid != INVALID_TIMER ) {
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
	}
	if ( maintenance_timerid != INVALID_TIMER ) {
		timer->delete( maintenance_timerid, maintenance_progress );
		maintenance_timerid = INVALID_TIMER;
	}
	safesnprintf( output, CHAT_SIZE_MAX, "%s ended the Maintenance mode. Players are able to login now.", sd->status.name );
	intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	ShowStatus( CL_YELLOW "Maintenance has ended by " CL_GREEN "%s" CL_RESET ".\n", sd->status.name );
	return true;
}

//	maintenance <Group ID can stay 1~99>, <duration to kick in minute>, <maintenance duration in minute> { , <reason> };
BUILDIN(maintenance) {
	int group_id = 0, kick_duration = 0, maintenance_duration = 0;
	char reason[99], esc_reason[198], min_display[3];
	short weekday = 0, hour = 0, minute = 0;
	if ( maintenance_endtime > (int)time(NULL) ) {
		ShowError( "buildin_maintenance: Maintenance is currently ON.\n" );
		return false;
	}
	group_id = script_getnum(st,2);
	kick_duration = script_getnum(st,3);
	maintenance_duration = script_getnum(st,4);
	if ( !group_id ) {
		ShowError( "buildin_maintenance: Group ID field cannot be 0.\n" );
		return false;
	}
	if ( group_id < 1 || group_id > 99 ) {
		ShowError( "buildin_maintenance: Invalid Group ID %d. Range must between 1~99.\n", group_id );
		return false;
	}
	if ( kick_duration <= 0 ) {
		ShowError( "buildin_maintenance: Kick duration cannot be 0 or negative numbers.\n" );
		return false;
	}
	if ( kick_duration > 1440 ) {
		ShowError( "buildin_maintenance: Kick duration cannot be more than 1 day.\n" );
		return false;
	}
	if ( maintenance_duration <= 0 ) {
		ShowError( "buildin_maintenance: Maintenance duration cannot be 0 or negative numbers.\n" );
		return false;
	}
	if ( maintenance_duration > 10080 ) {
		ShowError( "buildin_maintenance: Maintenance duration cannot be more than 1 week.\n" );
		return false;
	}
	safesnprintf( reason, 99, script_hasdata(st,5)? script_getstr(st,5) : "   *Regular server maintenance*" );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, 0, 'NPC', '%s', %d, now(), timestampadd( minute, %d, now() ), timestampadd( minute, %d, now() ) )", esc_reason, group_id, kick_duration, kick_duration + maintenance_duration ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	if ( SQL->Query( map->mysql_handle, "select unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		maintenance_group = group_id;
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		SQL->FreeResult( map->mysql_handle );
	}
	else {
		SQL->FreeResult( map->mysql_handle );
		return false;
	}
	{	// stupid date_format doesn't work
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3], output[CHAT_SIZE_MAX];
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will be commence in %d minutes. Players are adviced to log out right now. Maintenance last %d minutes. Server will come back up on %s", kick_duration, maintenance_duration, maintenance_timeformat );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	}
	maintenance_countid = timer->add( timer->gettick() +( ( kick_duration == 1 )? 1000 : 60000 ), maintenance_countdown, 0, 0 );
	ShowStatus( CL_YELLOW "Maintenance will start in %d min" CL_RESET ".\n", kick_duration );
	return true;
}

BUILDIN(maintenanceoff) {
	char reason[99], esc_reason[198];
	if ( maintenance_endtime <= (int)time(NULL) ) {
		ShowError( "buildin_maintenanceoff: Maintenance is currently OFF.\n" );
		return false;
	}
	safesnprintf( reason, 99, script_hasdata(st,2)? script_getstr(st,2) : "   *maintenance off*" );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, 0, 'NPC', '%s', 0, null, now(), now() )", esc_reason ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	if ( maintenance_countid != INVALID_TIMER ) {
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
	}
	if ( maintenance_timerid != INVALID_TIMER ) {
		timer->delete( maintenance_timerid, maintenance_progress );
		maintenance_timerid = INVALID_TIMER;
	}
	intif->broadcast2( "Maintenance mode has ended. Players are able to login now." , 255, maintenance_color, 0x190, 12, 0, 0);
	ShowStatus( CL_YELLOW "Maintenance has ended" CL_RESET ".\n" );
	return true;
}

BUILDIN(maintenancecheck) {
	int type = script_hasdata(st,2)? script_getnum(st,2) : 0;
	switch( type ) {
	default:
		if ( maintenance_starttime > (int)time(NULL) )
			script_pushint(st, 1);
		else if ( maintenance_endtime > (int)time(NULL) )
			script_pushint(st, 2);
		else
			script_pushint(st, 0);
		return true;
	case 1:
		script_pushint(st, maintenance_group);
		return true;
	case 2:
		script_pushint(st, maintenance_starttime);
		return true;
	case 3:
		script_pushint(st, maintenance_endtime);
		return true;
	case 4:
		script_pushint(st, maintenance_countid);
		return true;
	case 5:
		script_pushint(st, maintenance_timerid);
		return true;
//	case 6: // for some reason this cause memory leak
//		script_pushstr(st, maintenance_timeformat );
//		return true;
	}
}

HPExport void plugin_init (void) {
	addHookPre( "pc->authok", pc_authok_pre );
	addHookPre( "clif->pLoadEndAck", clif_parse_LoadEndAck_pre );

	addAtcommand( "maintenance", maintenance );
	addAtcommand( "maintenanceoff", maintenanceoff );

	addScriptCommand( "maintenance", "iii?", maintenance );
	addScriptCommand( "maintenanceoff", "?", maintenanceoff );
	addScriptCommand( "maintenancecheck", "?", maintenancecheck );
} 

 

 

 

partyscript.c

 

 

// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Mhalicot PartyScript Hercules Plugin
// Special Thanks for Mr. [Hercules/Ind]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/HPMi.h"
#include "common/cbasetypes.h"
#include "common/strlib.h"
#include "common/utils.h"
#include "common/malloc.h"
#include "common/mmo.h"
#include "common/db.h"
#include "map/atcommand.h"
#include "map/script.h"
#include "map/party.h"
#include "map/intif.h"
#include "map/status.h"
#include "map/clif.h"
#include "map/map.h"
#include "map/mapreg.h"
#include "map/pc.h"
#include "map/instance.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) */

#define party_add_member(party_id,sd) party_reply_invite_mine(sd,party_id,1)
#define safestrncpy(dst,src,n)       (strlib->safestrncpy((dst),(src),(n)))
#define idb_remove(db,k)    ( (db)->remove((db),DB->i2key(k),NULL) )
/*
1.0 Initial HPM Release [Mhalicot]
1.1 Rewrite party_delmember, removemember2 dropped.
1.2 Update Compatibility to latest Revision 137**
2.0 Update codes, Drop some useless codes.
2.1 Fixed Map crash when using designate in Party Window
2.2 Resolved crashing issue when leaving party from instance. [Mumbles / Haru]
3.0 Added @leaveparty Command [Mhalicot]
3.1 Fixed Various Compile Warnings and some logic [Dastgir]
---------------------------------------
Documentation
---------------------------------------

*party_create("<party name>"{,<character id>{,<item share>,<item share type>}});

Organizes a party with the attached or specified character as leader. If
successful, the command returns 1 and sets the global temporary variable
"$@party_create_id" to the ID of the party created.

Additionally, item sharing options can be provided:
 - Item Share: 0-Each Take (default), 1-Party Share
 - Item Share Type: 0-Each Take (default), 1-Even Share

These values are returned upon failure:
 0: Unknown error.
-1: Player not found.
-2: Player already has a party.
-3: Party name exists.

---------------------------------------

*party_destroy(<party id>);

Disbands a party. The command returns 1 upon success and 0 upon failure.

---------------------------------------

*party_addmember(<party id>,<character id>);

Adds a player to an existing party.

The command returns 1 upon success, and these values upon failure:
 0: Unknown error.
-1: Player not found.
-2: Player already has a party.
-3: Party not found.
-4: Party is full.

---------------------------------------

*party_delmember({<character id>}); 
 
Removes a player from his/her party. If no player is specified, the command 
will run for the invoking player. If that player is the only party member 
remaining, the party will be disbanded. 
 
The command returns 1 upon success, and these values upon failure: 
 0: Unknown error. 
-1: Player not found. 
-2: Player is not in the party. 

---------------------------------------

*party_changeleader(<party id>,<character id>);

Transfers leadership of a party to the specified character. The original
party leader doesn't need be online.

The command returns 1 upon success, and these values upon failure:
 0: Unknown error.
-1: Party not found.
-2: Player not found.
-3: Player is not in the party.
-4: Player is already party leader

---------------------------------------

*party_changeoption(<party id>,<option>,<flag>);

Changes a party option.

Valid options are:
 0 - Exp Share (flags: 0-Each Take, 1-Even Share)
 1 - Item Share (flags: 0-Each Take, 1-Party Share)
 2 - Item Share Type (flags: 0-Each Take, 1-Even Share)

The command returns 1 upon success, and these values upon failure:
 0: Invalid option.
-1: Party not found.
*/
HPExport struct hplugin_info pinfo = {
        "partyscript",		// Plugin name
        SERVER_TYPE_MAP,	// Which server types this plugin works with?
        "2.2",				// Plugin version
        HPM_VERSION,		// HPM Version (don't change, macro is automatically updated)
};

int create_byscript;
int party_change_leader_val = 0;
struct party_data *party_change_leader_p = NULL;

int party_create_mine(struct map_session_data *sd,char *name,int item,int item2) {
	struct party_member leader;
	char tname[NAME_LENGTH];

	safestrncpy(tname, name, NAME_LENGTH);
	trim(tname);

	if( !tname[0] ) {// empty name
		return 0;
	}

	if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating ) {// already associated with a party
		clif->party_created(sd,2);
		return -2;
	}

	sd->party_creating = true;

	party->fill_member(&leader, sd, 1);

	intif->create_party(&leader,name,item,item2);
	return 1;
}

void party_created_mine(int account_id,int char_id,int fail,int party_id,char *name) {
	struct map_session_data *sd;
	sd=map->id2sd(account_id);

	if (!sd || sd->status.char_id != char_id || !sd->party_creating ) {
		//Character logged off before creation ack?
		if (!fail) //break up party since player could not be added to it.
			intif->party_leave(party_id,account_id,char_id);
		return;
	}

	sd->party_creating = false;

	if( !fail ) {
		sd->status.party_id = party_id;
		clif->party_created(sd,0); //Success message
		//We don't do any further work here because the char-server sends a party info packet right after creating the party 
		if(create_byscript) {     //returns party id in $@party_create_id if party is created by script 
		  mapreg->setreg(script->add_str("$@party_create_id"),party_id); 
		  create_byscript = 0; 
		}
	} else 
		clif->party_created(sd,1); // "party name already exists"
}

int party_reply_invite_mine(struct map_session_data *sd,int party_id,int flag) {
	struct map_session_data* tsd;
	struct party_member member;

	if( sd->party_invite != party_id ) {// forged
		sd->party_invite = 0;
		sd->party_invite_account = 0;
		return 0;
	}
	tsd = map->id2sd(sd->party_invite_account);

	if( flag == 1 && !sd->party_creating && !sd->party_joining ) {// accepted and allowed
		sd->party_joining = true;
		party->fill_member(&member, sd, 0);
		intif->party_addmember(sd->party_invite, &member);
		return 1;
	} else {// rejected or failure
		sd->party_invite = 0;
		sd->party_invite_account = 0;
		if( tsd != NULL )
			clif->party_inviteack(tsd,sd->status.name,1);
		return 0;
	}
	return 0;
}

void party_reply_invite_overload(struct map_session_data *sd,int party_id,int flag) {
	party_reply_invite_mine(sd,party_id,flag);
}

//options: 0-exp, 1-item share, 2-pickup distribution
int party_setoption(struct party_data *pdata, int option, int flag) {
	int i;
	ARR_FIND(0,MAX_PARTY,i,pdata->party.member[i].leader);
	if(i >= MAX_PARTY)
		return 0;
	switch(option) {
		case 0:
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,flag,pdata->party.item);
			break;
		case 1:
			if(flag) flag = pdata->party.item|1;
			else flag = pdata->party.item&~1;
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,pdata->party.exp,flag);
			break;
		case 2:
			if(flag) flag = pdata->party.item|2;
			else flag = pdata->party.item&~2;
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,pdata->party.exp,flag);
			break;
		default:
			return 0;
			break;
	}
	return 1;
}

bool party_changeleader_mine(struct map_session_data *sd, struct map_session_data *tsd) {
	int mi, tmi;
	struct party_data *p = party_change_leader_p;

	party_change_leader_p = NULL;

	if ( !p ) {
		if (!sd || !sd->status.party_id) {
			party_change_leader_val = -1;
			return false;
		}

		if (!tsd || tsd->status.party_id != sd->status.party_id) {
			clif->message(sd->fd, "Target character must be online and in your current party.");
			party_change_leader_val = -3;
			return false;
		}

		if ( map->list[sd->bl.m].flag.partylock ) {
			clif->message(sd->fd, "You cannot change party leaders on this map.");
			party_change_leader_val = 0;
			return false;
		}

		if ((p = party->search(sd->status.party_id)) == NULL ) {
			party_change_leader_val = -1;
			return false;
		}

		ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
		if (mi == MAX_PARTY) {
			party_change_leader_val = 0; //Shouldn't happen
			return false;
		}

		if (!p->party.member[mi].leader) {
			clif->message(sd->fd, "You need to be a party leader to use this command.");
			party_change_leader_val = 0;
			return false;
		}

		ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
		if (tmi == MAX_PARTY) {
			party_change_leader_val = 0; //Shouldn't happen
			return false;
		}
	} else {
		ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader);
		ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd ==  tsd);
	}

	if (!p->party.member[mi].leader) {
		clif->message(sd->fd, "You need to be a party leader to use this command.");
		party_change_leader_val = 0;
		return false;
	}

	ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
	if (tmi == MAX_PARTY) {
		party_change_leader_val = 0; //Shouldn't happen
		return false;
	}

	//Change leadership.
	p->party.member[mi].leader = 0;
	if (p->data[mi].sd && p->data[mi].sd->fd)
		clif->message(p->data[mi].sd->fd, "Leadership transferred.");

	p->party.member[tmi].leader = 1;
	if (p->data[tmi].sd && p->data[tmi].sd->fd)
		clif->message(p->data[tmi].sd->fd, "You've become the party leader.");

	//Update info.
	intif->party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
	clif->party_info(p,NULL);
	party_change_leader_val = 1;
	return true;
}

/*==========================================
 * party_create "<party name>"{,<char id>{,<item share: 0-no. 1-yes>{,<item share type: 0-favorite. 1-shared>}}};
 * Return values:
 *      -3      - party name is exist
 *      -2      - player is in party already
 *      -1      - player is not found
 *      0       - unknown error
 *      1       - success, will return party id $@party_create_id
 *------------------------------------------*/
BUILDIN(party_create) {
	char party_name[NAME_LENGTH];
	int item1 = 0, item2 = 0;
	TBL_PC *sd = NULL;

	if( (!script_hasdata(st,3) && !(sd = script->rid2sd(st))) || (script_hasdata(st,3) && !(sd = map->charid2sd(script_getnum(st,3)))) ) {
		script_pushint(st,-1);
		return false;
	}

	if( sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	safestrncpy(party_name,script_getstr(st,2),NAME_LENGTH);
	trim(party_name);
	if( party->searchname(party_name) ) {
		script_pushint(st,-3);
		return false;
	}

	if( script_getnum(st,4) )
		item1 = 1;

	if( script_getnum(st,5) )
		item2 = 1;

	create_byscript = 1;
	script_pushint(st,party_create_mine(sd,party_name,item1,item2));
	return true;
}

/*==========================================
 * party_addmember <party id>,<char id>;
 * Adds player to specified party
 * Return values:
 *      -4      - party is full
 *      -3      - party is not found
 *      -2      - player is in party already
 *      -1      - player is not found
 *      0       - unknown error
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_addmember) {
	int party_id = script_getnum(st,2);
	TBL_PC *sd;
	struct party_data *pty;

	if( !(sd = map->charid2sd(script_getnum(st,3))) ) {
		script_pushint(st,-1);
		return false;
	}

	if( sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	if( !(pty = party->search(party_id)) ) {
		script_pushint(st,-3);
		return false;
	}

	if( pty->party.count >= MAX_PARTY ) {
		script_pushint(st,-4);
		return false;
	}

	sd->party_invite = party_id;
	script_pushint(st,party_add_member(party_id,sd));
	return true;
}

/*==========================================
 * party_delmember {<char id>}; 
 * Removes player from his/her party 
 * Return values: 
 *      -2      - player is not in party 
 *      -1      - player is not found 
 *      0       - unknown error 
 *      1       - success 
 *------------------------------------------*/
BUILDIN(party_delmember) {
	TBL_PC *sd = NULL;

	if( (!script_hasdata(st,2) && !(sd = script->rid2sd(st))) || 
		(script_hasdata(st,2) && !(sd = map->charid2sd(script_getnum(st,2))))
	  ){
		script_pushint(st,-1);
		return false;
	}

	if( !sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	script_pushint(st,party->leave(sd));
	return true;
}

/*==========================================
 * party_changeleader <party id>,<char id>;
 * Can change party leader even the leader is not online
 * Return values:
 *      -4      - player is party leader already 
 *      -3      - player is not in this party
 *      -2      - player is not found
 *      -1      - party is not found
 *      0       - unknown error
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_changeleader) {
	int i, party_id = script_getnum(st,2);
	TBL_PC *sd = NULL;
	TBL_PC *tsd = NULL;
	struct party_data *pty = NULL;

	if( !(pty = party->search(party_id)) ) {
		script_pushint(st,-1);
		return false;
	}

	if( !(tsd = map->charid2sd(script_getnum(st,3))) ) {
		script_pushint(st,-2);
		return false;
	}

	if( tsd->status.party_id != party_id ) {
		script_pushint(st,-3);
		return false;
	}

	ARR_FIND(0,MAX_PARTY,i,pty->party.member[i].leader);
	if( i >= MAX_PARTY ) {  //this is should impossible!
		script_pushint(st,0);
		return false;
	}

	if( pty->data[i].sd == tsd ) {
		script_pushint(st,-4);
		return false;
	}

	party_change_leader_p = pty;
	party_changeleader_mine(sd,tsd);

	script_pushint(st,party_change_leader_val);
	return true;
}

/*==========================================
 * party_changeoption <party id>,<option>,<flag>;
 * Return values:
 *      -1      - party is not found
 *      0       - invalid option
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_changeoption) {
	struct party_data *pty;

	if( !(pty = party->search(script_getnum(st,2))) ) {
		script_pushint(st,-1);
		return true;
	}

	script_pushint(st,party_setoption(pty,script_getnum(st,3),script_getnum(st,4)));
	return true;
}

/*==========================================
 * party_destroy <party id>;
 * Destroys party with party id. 
 * Return values:
 *      0       - failed
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_destroy) {
	int i;
	struct party_data *pty;

	if( !(pty = party->search(script_getnum(st,2))) ) {
		script_pushint(st,0);
	}

	ARR_FIND(0,MAX_PARTY,i,pty->party.member[i].leader);
	if( i >= MAX_PARTY || !pty->data[i].sd ) { //leader not online
		int j;
		for( j = 0; j < MAX_PARTY; j++ ) {
			TBL_PC *sd = pty->data[j].sd;
			if(sd)
				party->member_withdraw(pty->party.party_id,sd->status.account_id,sd->status.char_id);
			else if( pty->party.member[j].char_id )
			intif->party_leave(pty->party.party_id,pty->party.member[j].account_id,pty->party.member[j].char_id);
		}
		//party_broken_mine(pty->party.party_id);
		party->broken(pty->party.party_id);
		script_pushint(st,1);
	}
	else    //leader leave = party broken
		script_pushint(st,party->leave(pty->data[i].sd));
	return true;
}

/*==========================================
 *
 *------------------------------------------*/
ACMD(party) {
	char party_name[NAME_LENGTH];

	memset(party_name, '\0', sizeof(party_name));

	if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
		clif->message(fd, "Please enter a party name (usage: @party <party_name>).");
		return false;
	}

	party_create_mine(sd, party_name, 0, 0);
	return true;
}

ACMD(leaveparty) {

	if( !sd->status.party_id ) {
		clif->message(fd, "You must have a party to use this command");
		return false;
	}

	party->leave(sd);
	return true;
}
ACMD(partyoption) {
	struct party_data *p;
	int mi, option;
	char w1[16], w2[16];

	if (sd->status.party_id == 0 || (p = party->search(sd->status.party_id)) == NULL) {
		clif->message(fd, "You need to be a party leader to use this command.");
		return false;
	}

	ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
	if (mi == MAX_PARTY)
		return false; //Shouldn't happen

	if (!p->party.member[mi].leader) {
		clif->message(fd, "You need to be a party leader to use this command.");
		return false;
	}

	if(!message || !*message || sscanf(message, "%15s %15s", w1, w2) < 2) {
		clif->message(fd, "Usage: @partyoption <pickup share: yes/no> <item distribution: yes/no>");
		return false;
	}

	option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0);

	//Change item share type.
	if (option != p->party.item)
		party->changeoption(sd, p->party.exp, option);
	else
		clif->message(fd, "There's been no change in the setting.");

	return true;
}

/* Server Startup */
HPExport void plugin_init (void) {
	instance = GET_SYMBOL("instance");
    script = GET_SYMBOL("script");
	mapreg = GET_SYMBOL("mapreg");
	strlib = GET_SYMBOL("strlib");
	party = GET_SYMBOL("party");
	intif = GET_SYMBOL("intif");
    clif = GET_SYMBOL("clif");
	map = GET_SYMBOL("map");
	DB = GET_SYMBOL("DB");

	//Commands
	addAtcommand("partyoption",partyoption);
	addAtcommand("leaveparty",leaveparty);
	addAtcommand("party",party);
	
	//Scripts
	addScriptCommand("party_changeoption","iii",party_changeoption);
	addScriptCommand("party_changeleader","ii",party_changeleader);
	addScriptCommand("party_addmember","ii",party_addmember);
	addScriptCommand("party_delmember","?",party_delmember);
	addScriptCommand("party_create","s???",party_create);
	addScriptCommand("party_destroy","i",party_destroy);

	party->changeleader = &party_changeleader_mine;
	party->reply_invite = &party_reply_invite_overload;
	party->created = &party_created_mine;
	party->create = &party_create_mine;
};
 

 

 

 

 

noitem.c

 

 

//===== Hercules Plugin ======================================
//= noitem mapflag
//===== By: ==================================================
//= AnnieRuru
//===== Current Version: =====================================
//= 1.3
//===== Compatible With: ===================================== 
//= Hercules 2015-11-12
//===== Description: =========================================
//= block players from using items
//===== Topic ================================================
//= http://herc.ws/board/topic/4830-noitem-mapflag/
//===== Additional Comments: =================================  
//= prontera   mapflag   noitem   IT_WEAPON,IT_ARMOR
//= block players from equipping weapon and armor
//============================================================

#include "common/hercules.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "map/pc.h"
#include "common/memmgr.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"noitem", // Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"1.3",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

struct mapflag_data {
	int noitem;
	int noitemlist[50];
};

//	flush all noitem mapflag back to default upon @reloadscript
void map_flags_init_pre(void) {
	int i;
	for ( i = 0; i < map->count; i++ ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[i], 0 );
		if ( mf )
			removeFromMAPD( &map->list[i], 0 );
	}
	return;
}

void npc_parse_unknown_mapflag_pre( const char *name, char *w3, char *w4, const char* start, const char* buffer, const char* filepath, int *retval ) {
	if ( !strcmp(w3,"noitem") ) {
		int id = 0, i = 0, j = 0, k = 0, l = strlen(w4);
		char *temp = (char*)aMalloc( strlen(w4) +1 );
		struct item_data *i_data;
		struct mapflag_data *mf;
		if ( l ) {
			int16 m = map->mapname2mapid( name );
			CREATE( mf, struct mapflag_data, 1 );
			while ( i <= l && k < 50 ) {
				if ( w4[i] != ' ' && w4[i] != '	' && w4[i] != ',' && w4[i] != '\0' ) {
					temp[j++] = w4[i];
				}
				else if ( w4[i-1] != ' ' && w4[i-1] != '	' && w4[i-1] != ',' ) {
					temp[j] = '\0';
					if ( !strcmp( temp, "IT_HEALING" ) || !strcmp( temp, "0" ) )
						mf->noitemlist[k] = 0;
					else if ( !strcmp( temp, "IT_USABLE" ) || !strcmp( temp, "2" ) )
						mf->noitemlist[k] = 2;
					else if ( !strcmp( temp, "IT_WEAPON" ) || !strcmp( temp, "4" ) )
						mf->noitemlist[k] = 4;
					else if ( !strcmp( temp, "IT_ARMOR" ) || !strcmp( temp, "5" ) )
						mf->noitemlist[k] = 5;
					else if ( !strcmp( temp, "IT_CARD" ) || !strcmp( temp, "6" ) )
						mf->noitemlist[k] = 6;
					else if ( !strcmp( temp, "IT_DELAYCONSUME" ) || !strcmp( temp, "11" ) )
						mf->noitemlist[k] = 11;
					else if ( !strcmp( temp, "IT_CASH" ) || !strcmp( temp, "18" ) )
						mf->noitemlist[k] = 18;
					else if ( atoi(temp) == 0 ) {
						i_data = itemdb->search_name( temp );
						if ( i_data )
							mf->noitemlist[k] = i_data->nameid;
						else {
							ShowWarning("npc_parse_mapflag: Item name \"%s\" does not exist.\n    Mapflag noitem: At %s (file '%s', line '%d').\n", temp, name, filepath, strline(buffer,start-buffer) );
							mf->noitemlist[k] = -1;
						}
					}
					else {
						id = atoi(temp);
						if ( itemdb->exists(id) )
							mf->noitemlist[k] = id;
						else {
							ShowWarning("npc_parse_mapflag: Item ID \"%s\" does not exist.\n    Mapflag noitem: At %s (file '%s', line '%d').\n", temp, name, filepath, strline(buffer,start-buffer) );
							mf->noitemlist[k] = -1;
						}
					}
					k++;
					j = 0;
				}
				i++;
			}
			mf->noitem = k;
			addToMAPD( &map->list[m], mf, 0, true );
		}
		else
			ShowWarning("npc_parse_mapflag: no Item ID/type input.\n           Mapflag noitem: At %s (file '%s', line '%d').\n", name, filepath, strline(buffer,start-buffer));
		aFree(temp);
		hookStop();
	}
	return;
}

int pc_isequip_post( int retVal, struct map_session_data *sd, int *n ) {
	if ( retVal == 1 ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
		if ( mf && mf->noitem ) {
			struct item_data *item = sd->inventory_data[*n];
			int i = 0, slot = 0;
			ARR_FIND( 0, mf->noitem, i, item->nameid == mf->noitemlist[i] || item->type == mf->noitemlist[i] );
			if ( i < mf->noitem )
				return 0;
			if ( !itemdb_isspecial( sd->status.inventory[*n].card[0] ) ) {
				for ( slot = 0; slot < MAX_SLOTS; slot++ ) {
					if ( sd->status.inventory[*n].card[slot] ) {
						struct item_data *i_data = itemdb->exists( sd->status.inventory[*n].card[slot] );
						ARR_FIND( 0, mf->noitem, i, i_data->nameid == mf->noitemlist[i] || i_data->type == mf->noitemlist[i] );
						if ( i < mf->noitem )
							return 0;
					}
				}
			}
		}
	}
	return retVal;
}

int pc_isUseitem_post( int retVal, struct map_session_data *sd, int *n ) {
	if ( retVal == 1 ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
		if ( mf && mf->noitem ) {
			struct item_data *item = sd->inventory_data[*n];
			int i = 0;
			ARR_FIND( 0, mf->noitem, i, mf->noitemlist[i] == sd->status.inventory[*n].nameid || item->type == mf->noitemlist[i] );
			if ( i < mf->noitem )
				return 0;
		}
	}
	return retVal;
}

int pc_checkitem_post( int retVal, struct map_session_data *sd ) {
	struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
	int i, calc_flag = 0;
	if ( sd->state.vending )
		return 0;
	if ( mf && mf->noitem ) {
		for ( i = 0; i < MAX_INVENTORY; i++ ) {
			int j = 0, slot = 0;
			struct item_data *i_data = itemdb->exists( sd->status.inventory[i].nameid );
			if ( sd->status.inventory[i].nameid == 0 || !sd->status.inventory[i].equip )
				continue;
			ARR_FIND( 0, mf->noitem, j, mf->noitemlist[j] == i_data->type || mf->noitemlist[j] == sd->status.inventory[i].nameid );
			if ( j < mf->noitem ) {
				pc->unequipitem(sd, i, 2);
				calc_flag = 1;
				continue;
			}
			if ( !itemdb_isspecial( sd->status.inventory[i].card[0] ) ) {
				for ( slot = 0; slot < MAX_SLOTS; slot++ ) {
					if ( sd->status.inventory[i].card[slot] ) {
						struct item_data *i_datac = itemdb->exists( sd->status.inventory[i].card[slot] );
						ARR_FIND( 0, mf->noitem, j, mf->noitemlist[j] == i_datac->type || mf->noitemlist[j] == sd->status.inventory[i].card[slot] );
						if ( j < mf->noitem ) {
							pc->unequipitem(sd, i, 2);
							calc_flag = 1;
							break;
						}
					}
				}
			}
		}
		if ( calc_flag && sd->state.active ) {
			pc->checkallowskill(sd);
			status_calc_pc( sd,SCO_NONE );
		}
	}
	return retVal;
}

HPExport void plugin_init (void) {
	addHookPre( "map->flags_init", map_flags_init_pre );
	addHookPre( "npc->parse_unknown_mapflag", npc_parse_unknown_mapflag_pre );
	addHookPost( "pc->isequip", pc_isequip_post );
	addHookPost( "pc->isUseitem", pc_isUseitem_post );
	addHookPost( "pc->checkitem", pc_checkitem_post );
} 

 

 

 

market.c

 

 

//===== Hercules Plugin ======================================
//= @market clone
//===== By: ==================================================
//= AnnieRuru
//= Credit - Dastgir -> http://hercules.ws/board/topic/7188-market/
//===== Current Version: =====================================
//= 1.5
//===== Compatible With: ===================================== 
//= Hercules 2016-1-1
//===== Description: =========================================
//= Create a market clone, to leave a message for other players
//= while the player can go hunting/questing/events
//===== Topic ================================================
//= http://hercules.ws/board/topic/7242-market-clone/
//===== Additional Comments: =================================  
//= -- AtCommands --
//= @market "<Title>" "<Message>" <Color>
//=   create a market clone with a chat room titled -> "<Title>"
//=   when players tries to join the chat room, it refuse the joining, but instead leave a message -> "<Message>" <- with their own desired <Color>
//= @marketkill
//=   kill the market clone without logging off
//=
//= a GM doing a @killmonster @killmonster2, or *killmonster *kilmonsterall script command will not remove the clone
//= but @reloadscript, however, will remove it
//============================================================

//	how many seconds delay from creating another market clone ?
//	Note: if you set it too low like 1 second, player might spawn the clone all over the town, unit->free doesn't act fast enough to remove them, 10 seconds is ideal
int market_clone_delay = 10; // 10 seconds

//	the zeny cost for creating a market clone
int market_clone_zenycost = 0;

//	if the player has cart/riding/ward/falcon, will these objects cloned as well ?
int market_clone_companion = 0; // set to 1 to enable

//============================================================

#include "common/hercules.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "map/pc.h"
#include "map/mob.h"
#include "map/npc.h"
#include "map/chat.h"
#include "map/clif.h"
#include "map/guild.h"
#include "map/skill.h"
#include "map/unit.h"
#include "map/battle.h"
#include "common/memmgr.h"
#include "common/strlib.h"
#include "common/socket.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"marketclone",
	SERVER_TYPE_MAP,
	"1.5",
	HPM_VERSION,
};

struct player_data {
	int market_clone_id;
	int market_clone_delay;
};

struct monster_data {
	int uid;
	int market_pushcart;
	int market_chat_id;
	int market_msg_color;
	char market_message[CHAT_SIZE_MAX];
};

void color_list(int fd) {
	clif->messagecolor_self(fd, 0x00FFFF, "0  - Aqua (default)");
	clif->messagecolor_self(fd, 0x000001, "1  - Black");
	clif->messagecolor_self(fd, 0x0000FF, "2  - Blue");
	clif->messagecolor_self(fd, 0x808080, "3  - Grey");
	clif->messagecolor_self(fd, 0x008000, "4  - Green");
	clif->messagecolor_self(fd, 0x00FF00, "5  - Lime");
	clif->messagecolor_self(fd, 0x800000, "6  - Maroon");
	clif->messagecolor_self(fd, 0x000080, "7  - Navy");
	clif->messagecolor_self(fd, 0x808000, "8  - Olive");
	clif->messagecolor_self(fd, 0xFFA500, "9  - Orange");
	clif->messagecolor_self(fd, 0x800080, "10 - Purple");
	clif->messagecolor_self(fd, 0xFF0000, "11 - Red");
	clif->messagecolor_self(fd, 0xC0C0C0, "12 - Silver");
	clif->messagecolor_self(fd, 0x008080, "13 - Teal");
	clif->messagecolor_self(fd, 0xFFFFFF, "14 - White");
	clif->messagecolor_self(fd, 0xFFC0CB, "15 - Pink");
	clif->messagecolor_self(fd, 0xD2691E, "16 - Chocolate");
	clif->messagecolor_self(fd, 0xFFD700, "17 - Gold");
	clif->messagecolor_self(fd, 0xEE82EE, "18 - Violet");
	return;
}
//	I was thinking of using array before ... but I guess, this kind of implementation is easier for you guys to add custom color
//	if want to remove a color, just comment/delete that line. If want to add, well, you can guess the format XD
void color_message(int fd, int msg_color, char market_msg[]) {
	switch (msg_color) {
		default: clif->messagecolor_self(fd, 0x00FFFF, market_msg); break;
		case 1: clif->messagecolor_self(fd, 0x000001, market_msg); break;
		case 2: clif->messagecolor_self(fd, 0x0000FF, market_msg); break;
		case 3: clif->messagecolor_self(fd, 0x808080, market_msg); break;
		case 4: clif->messagecolor_self(fd, 0x008000, market_msg); break;
		case 5: clif->messagecolor_self(fd, 0x00FF00, market_msg); break;
		case 6: clif->messagecolor_self(fd, 0x800000, market_msg); break;
		case 7: clif->messagecolor_self(fd, 0x000080, market_msg); break;
		case 8: clif->messagecolor_self(fd, 0x808000, market_msg); break;
		case 9: clif->messagecolor_self(fd, 0xFFA500, market_msg); break;
		case 10: clif->messagecolor_self(fd, 0x800080, market_msg); break;
		case 11: clif->messagecolor_self(fd, 0xFF0000, market_msg); break;
		case 12: clif->messagecolor_self(fd, 0xC0C0C0, market_msg); break;
		case 13: clif->messagecolor_self(fd, 0x008080, market_msg); break;
		case 14: clif->messagecolor_self(fd, 0xFFFFFF, market_msg); break;
		case 15: clif->messagecolor_self(fd, 0xFFC0CB, market_msg); break;
		case 16: clif->messagecolor_self(fd, 0xD2691E, market_msg); break;
		case 17: clif->messagecolor_self(fd, 0xFFD700, market_msg); break;
		case 18: clif->messagecolor_self(fd, 0xEE82EE, market_msg); break;
	}
	return;
}

int mob_clone_spawn_market(struct map_session_data *sd, int16 m, int16 x, int16 y, char market_title[], char market_msg[], int msg_color) { //Copy of mob_clone_spawn with some modification.
	int class_;
	struct mob_data *md;
	struct monster_data *mmd;
	struct mob_db* db;
	struct status_data *mstatus;
	struct chat_data* cd;

	ARR_FIND(MOB_CLONE_START, MOB_CLONE_END, class_, mob->db_data[class_] == NULL);
	if (class_ >= MOB_CLONE_END)
		return 0;

	db = mob->db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
	mstatus = &db->status;
	safestrncpy(db->sprite, sd->status.name, NAME_LENGTH);
	safestrncpy(db->name, sd->status.name, NAME_LENGTH);
	safestrncpy(db->jname, sd->status.name, NAME_LENGTH);
	db->lv = status->get_lv(&sd->bl);
	memcpy(mstatus, &sd->base_status, sizeof(struct status_data));
	mstatus->rhw.atk = mstatus->rhw.atk2 = mstatus->lhw.atk = mstatus->lhw.atk2 = mstatus->hp = mstatus->max_hp = mstatus->sp = mstatus->max_sp =  1;
	mstatus->mode = 0;
	memcpy(&db->vd, &sd->vd, sizeof(struct view_data));
	db->base_exp = db->job_exp = db->range2 = db->range3 = 1;
	db->option = 0;

	md = mob->once_spawn_sub(&sd->bl, m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
	if (!md)
		return 0;
	md->special_state.clone = 1;
	mob->spawn(md);
	unit->setdir(&md->bl, unit->getdir(&sd->bl));
	cd = chat->create(&md->bl, market_title, "", 1, false, 0, "", 0, 1, MAX_LEVEL);
	if (!cd)
		return 0;
	mmd = getFromMOBDATA(md,0);
	CREATE(mmd, struct monster_data, 1);
	mmd->market_chat_id = cd->bl.id;
	safestrncpy(mmd->market_message, market_msg, CHAT_SIZE_MAX);
	mmd->uid = md->bl.id;
	addToMOBDATA(md, mmd, 0, true);
	clif->dispchat(cd, 0);
	if (sd->vd.dead_sit == 2)
		clif->sitting(&md->bl);
	if (market_clone_companion) {
		if (sd->sc.data[SC_PUSH_CART]) {
			mmd->market_pushcart = sd->sc.data[SC_PUSH_CART]->val1;
			clif->sc_load(&md->bl, mmd->uid, AREA, SI_ON_PUSH_CART, mmd->market_pushcart, 0, 0);
		}
		if (pc_hasmount(sd) || pc_isfalcon(sd)) {
			int option = sd->sc.option & (OPTION_RIDING|OPTION_DRAGON|OPTION_WUGRIDER|OPTION_FALCON|OPTION_MADOGEAR);
			md->sc.option |= option;
			clif->changeoption(&md->bl);
		}
	}
	mmd->market_msg_color = msg_color;
	return md->bl.id;
}

ACMD(market){
	struct player_data *ssd = getFromMSD(sd,0);
	char title[CHAT_SIZE_MAX], msg[CHAT_SIZE_MAX], atcmd_output[CHAT_SIZE_MAX];
	int color = 0;
	if (!ssd) {
		CREATE(ssd, struct player_data, 1);
		ssd->market_clone_id = 0;
		ssd->market_clone_delay = 0;
		addToMSD(sd, ssd, 0, true);
	}
	if (ssd->market_clone_id) {
		clif->message(fd, "You already have a Market clone summoned. Type '@marketkill' to remove that clone.");
		return false;
	}
	if (ssd->market_clone_delay + market_clone_delay > (int)time(NULL)) {
		safesnprintf(atcmd_output, CHAT_SIZE_MAX, "You must wait %d seconds before using this command again.", ssd->market_clone_delay + market_clone_delay - (int)time(NULL));
		clif->message(fd, atcmd_output);
		return false;
	}
	if (!map->list[sd->bl.m].flag.town) {
		clif->message(fd, "You can only use @market in a town.");
		return false;
	}
	if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNOCHAT)) {
		clif->message(fd, "You cannot use @market in this area.");
		return false;
	}
	if (sd->status.zeny < market_clone_zenycost) {
		safesnprintf(atcmd_output, CHAT_SIZE_MAX, "You must have at least %d zeny to have a Market clone.", market_clone_zenycost);
		clif->message(fd, atcmd_output);
		return false;
	}
	if (pc_isdead(sd)) {
		clif->message(fd, "You can't create a Market clone while you are dead.");
		return false;
	}
	if (sd->chat_id) {
		clif->message(fd, "You can't create a Market clone while you already open a chatroom.");
		return false;
	}
	if (sd->state.vending) {
		clif->message(fd, "You can't create a Market clone while you are vending.");
		return false;
	}
	if (sd->sc.option & OPTION_INVISIBLE) {
		clif->message(fd, "You can't create a Market clone while you are using @hide.");
		return false;
	}
	if (npc->isnear(&sd->bl)) {
		clif->message(fd, "You can't create a Market clone too near to an npc.");
		return false;
	}
	if (!*message) {
		clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
		clif->message(fd, "The <Color> field is optional. Examples:-");
		color_list(fd);
		return false;
	}
//	if (sscanf(message, "\"%[^\"]\" \"%[^\"]\"", title, msg) < 2) {
//		clif->message(fd, "Remember the Quotation Mark -> \"");
//		clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\"");
//		return false;
//	} no more f*cking sscanf
	{ // say hello to the dirties string calculation ~ Hooray ~ !!
		int i = 0, j = 0;
		size_t l = strlen(message) + 1;
		char *temp = (char*)aMalloc(strlen(message) +1);
		if (message[0] != '\"') {
			clif->message(fd, "Remember the <Title> should start with a Quotation Mark -> \"");
			clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
			aFree(temp);
			return false;
		}
		i = 1;
		while (i <= l) {
			if (message[i] == '\"' || message[i] == '\0')
				break;
			else
				temp[j++] = message[i];
			++i;
		}
		if (message[i] != '\"') {
			clif->message(fd, "Remember the <Title> should end with a Quotation Mark -> \"");
			clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
			aFree(temp);
			return false;
		}
		temp[j] = '\0';
		safestrncpy(title, temp, CHAT_SIZE_MAX);		
		++i;
		if (message[i] != ' ') {
			clif->message(fd, "Remember the [Space] between the <Title> and <Message>.");
			clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
			aFree(temp);
			return false;
		}
		++i;
		if (message[i] != '\"') {
			clif->message(fd, "Remember the <Message> should start with a Quotation Mark -> \"");
			clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
			aFree(temp);
			return false;
		}
		++i;
		j = 0;
		while (i <= l) {
			if (message[i] == '\"' || message[i] == '\0')
				break;
			else
				temp[j++] = message[i];
			++i;
		}
		if (message[i] != '\"') {
			clif->message(fd, "Remember the <Message> should end with a Quotation Mark -> \"");
			clif->message(fd, "Syntax: @market \"<Title>\" \"<Message>\" <Color>");
			aFree(temp);
			return false;
		}
		temp[j] = '\0';
		safestrncpy(msg, temp, CHAT_SIZE_MAX);
		++i;
		if (message[i] == ' ') {
			j = 0;
			++i;
			while (i <= l) {
				if (message[i] == '\0')
					break;
				else
					temp[j++] = message[i];
				++i;
			}
			temp[j] = '\0';
			if (strlen(temp) > 2) {
				clif->message(fd, "Please input a valid number from the list.");
				color_list(fd);
				aFree(temp);
				return false;
			}
			color = atoi(temp);
		}
		aFree(temp);
	}
	if (strlen(title) < 4) {
		clif->message(fd, "The Title must more than 4 characters.");
		return false;
	}
	if (strlen(title) >= CHATROOM_TITLE_SIZE) {
		safesnprintf(atcmd_output, CHAT_SIZE_MAX, "The Title must not more than %d characters.", CHATROOM_TITLE_SIZE);
		clif->message(fd, atcmd_output);
		return false;
	}
	if (strlen(msg) < 4) {
		clif->message(fd, "The Message must more than 4 characters.");
		return false;
	}
	ssd->market_clone_id = mob_clone_spawn_market(sd, sd->bl.m, sd->bl.x, sd->bl.y, title, msg, color);
	if (!ssd->market_clone_id) {
		clif->message(fd, "Market clone Cannot be Created.");
		return false;
	}
	if (market_clone_zenycost)
		pc->payzeny(sd, market_clone_zenycost, LOG_TYPE_COMMAND, NULL);
	clif->message(fd, "Market clone Created.");
	return true;
}

ACMD(marketkill){
	struct player_data *ssd = getFromMSD(sd,0);
	if (!ssd) {
		CREATE(ssd, struct player_data, 1);
		ssd->market_clone_id = 0;
		ssd->market_clone_delay = 0;
		addToMSD(sd, ssd, 0, true);
	}
	if (!ssd->market_clone_id) {
		clif->message(fd, "You don't have a market clone yet. Type '@market \"<title>\" \"<message>\"' to create one.");
		return false;
	}
	status_kill(map->id2bl(ssd->market_clone_id));
	clif->message(fd, "Your market clone has removed.");
	ssd->market_clone_id = 0;
	ssd->market_clone_delay = (int)time(NULL);
	return true;
}

int npc_reload_pre(void) {
	TBL_PC *sd;
	struct player_data *ssd;
	struct s_mapiterator *iter;
	iter = mapit->alloc(MAPIT_NORMAL, BL_PC);
	for (sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter)) {
		if ((ssd = getFromMSD(sd,0))) {
			if (ssd->market_clone_id) {
				status_kill(map->id2bl(ssd->market_clone_id));
				ssd->market_clone_id = 0;
				ssd->market_clone_delay = (int)time(NULL);
			}
		}
	}
	mapit->free(iter);
	return 0;	
}

int battle_check_target_post(int retVal, struct block_list *src, struct block_list *target, int flag) {
	if (retVal == 1 && target->type == BL_MOB) {
		struct monster_data *mmd = getFromMOBDATA((TBL_MOB*)target, 0);
		if (mmd)
			return -1;
	}
	return retVal;
}

bool chat_joinchat_pre(struct map_session_data **sd_, int *chat_id, const char **pass) {
	struct map_session_data *sd = *sd_;
	struct chat_data* cd = (struct chat_data*)map->id2bl(*chat_id);
	if(cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->state.vending || sd->state.buyingstore || sd->chat_id || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit) {
		clif->joinchatfail(sd,0); // room full
		hookStop();
		return false;
	}
	if (cd->owner->type == BL_MOB) {
		struct mob_data *md = (TBL_MOB*)cd->owner;
		struct monster_data *mmd = getFromMOBDATA(md,0);
		if (mmd) {
			char output[CHAT_SIZE_MAX];
			safesnprintf(output, CHAT_SIZE_MAX, "%s : %s", md->name, mmd->market_message);
			color_message(sd->fd, mmd->market_msg_color, output);
			hookStop();
			return true;
		}
	}
	return true;
}

void clif_getareachar_unit_post(struct map_session_data *sd, struct block_list *bl) {
	if (bl->type == BL_MOB) {
		struct monster_data *mmd = getFromMOBDATA((TBL_MOB*)bl, 0);
		if (mmd) {
			clif->dispchat((struct chat_data*)map->id2bl(mmd->market_chat_id), sd->fd);
			if (market_clone_companion && mmd->market_pushcart)
				clif->sc_load(&sd->bl, mmd->uid, SELF, SI_ON_PUSH_CART, mmd->market_pushcart, 0, 0);
		}
	}
	return;
}

void clif_charnameack_pre(int *fd, struct block_list **bl) {
	if ((*bl)->type == BL_MOB) {
		TBL_MOB *md = (TBL_MOB*)(*bl);
		if (md->guardian_data && md->guardian_data->g)
			return;
		else if (battle->bc->show_mob_info) {
			struct monster_data *mmd = getFromMOBDATA(md,0);
			if (!mmd)
				return;
			else {
				char buf[103];
				WBUFW(buf, 0) = 0x95;
				WBUFL(buf,2) = md->bl.id;
				memcpy(WBUFP(buf,6), md->name, NAME_LENGTH);
				if (*fd == 0)
					clif->send(buf, 30, *bl, AREA);
				else {
					WFIFOHEAD(*fd, 30);
					memcpy(WFIFOP(*fd, 0), buf, 30);
					WFIFOSET(*fd, 30);
				}
				hookStop();
				return;
			}
		}
	}
}

int map_quit_pre(struct map_session_data **sd) {
	struct player_data *ssd = getFromMSD(*sd, 0);
	if (ssd && ssd->market_clone_id)
		status_kill(map->id2bl(ssd->market_clone_id));
	return 0;
}

int killmonster_sub_pre(struct block_list **bl, va_list ap) {
	struct mob_data *md = BL_CAST(BL_MOB, *bl);
	struct monster_data *mmd = getFromMOBDATA(md, 0);
	if (mmd)
		hookStop();
	return 0;
}

int skillnotok_pre(uint16 *skill_id, struct map_session_data **sd) {
	struct player_data *ssd = getFromMSD(*sd,0);
	if (ssd && ssd->market_clone_id && ((*skill_id) == MC_VENDING || (*skill_id) == ALL_BUYING_STORE)) {
		clif->messagecolor_self((*sd)->fd, COLOR_RED, "You can't use vending while you already have a market clone.");
		hookStop();
		return 1;
	}
	return 0;
}

HPExport void plugin_init (void) {
	addAtcommand("market", market);
	addAtcommand("marketkill", marketkill);

	addHookPre(npc, reload, npc_reload_pre);
	addHookPost(battle, check_target, battle_check_target_post);
	addHookPre(chat, join, chat_joinchat_pre);
	addHookPost(clif, getareachar_unit, clif_getareachar_unit_post);
	addHookPre(clif, charnameack, clif_charnameack_pre);
	addHookPre(map, quit, map_quit_pre);
	addHookPre(atcommand, atkillmonster_sub, killmonster_sub_pre);
	addHookPre(script, buildin_killmonster_sub_strip, killmonster_sub_pre);
	addHookPre(script, buildin_killmonster_sub, killmonster_sub_pre);
	addHookPre(script, buildin_killmonsterall_sub_strip, killmonster_sub_pre);
	addHookPre(script, buildin_killmonsterall_sub, killmonster_sub_pre);
	addHookPre(skill, not_ok, skillnotok_pre);
}
HPExport void server_online (void) {
	ShowInfo ("'%s' Plugin by Dastgir/Hercules. Version '%s'\n",pinfo.name,pinfo.version);
}
 

 

 

 

 

storageadditem

 

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "common/HPMi.h"
#include "map/intif.h"
#include "map/pc.h"
#include "map/storage.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 = {
	"storageadditem", // Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"0.1",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};


/*==========================================
 * storageadditem <item id>,<amount>{,<account id>}
 * Adds items from the target/attached player.
 *==========================================*/
BUILDIN(storageadditem) {
	TBL_PC *sd;
	struct item it;

	if (script_hasdata(st,4)) {
		int account_id = script_getnum(st,4);
		sd = map->id2sd(account_id); // <account id>
		if (sd == NULL) {
			ShowError("script:storageadditem: player not found (AID=%d).\n", account_id);
			st->state = END;
			return false;
		}
	} else {
		sd = script->rid2sd(st);// attached player
		if (sd == NULL)
			return true;
	}

	memset(&it, 0, sizeof(it));
	if (script_isstringtype(st, 2)) {
		const char* item_name = script_getstr(st, 2);
		struct item_data* id = itemdb->search_name(item_name);
		if (id == NULL) {
			ShowError("script:storageadditem: unknown item \"%s\".\n", item_name);
			st->state = END;
			return false;
		}
		it.nameid = id->nameid;// "<item name>"
	} else {
		it.nameid = script_getnum(st, 2);// <item id>
		if (!itemdb->exists(it.nameid)) {
			ShowError("script:storageadditem: unknown item \"%d\".\n", it.nameid);
			st->state = END;
			return false;
		}
	}

	it.amount=script_getnum(st,3);

	if( it.amount <= 0 ) {
		return true;// nothing to do
	}
	if( sd->status.storage.storage_amount > MAX_STORAGE ) {
		return 0; // storage full
	}
	it.identify=1;
	storage->open(sd);
	storage->additem(sd,&it,it.amount);
	storage->close(sd);
}

/* Server Startup */
HPExport void plugin_init (void) {
	addScriptCommand( "storageadditem", "vi?", storageadditem);
} 

 

 

 

Errors and Warnings

 

Severity	Code	Description	Project	File	Line	Suppression State
Warning	C4018	'<=': signed/unsigned mismatch	char-server	hercules\src\char\int_party.c	320	
Warning	C4013	'GET_SYMBOL' undefined; assuming extern returning int	autopots	Hercules\src\plugins\autopots.c	267	
Warning	C4047	'=': 'clif_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	267	
Warning	C4047	'=': 'script_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	268	
Warning	C4047	'=': 'pc_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	269	
Warning	C4047	'=': 'atcommand_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	270	
Warning	C4047	'=': 'map_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	271	
Warning	C4047	'=': 'unit_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	272	
Warning	C4047	'=': 'timer_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	273	
Warning	C4047	'=': 'itemdb_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	274	
Warning	C4013	'hookStop' undefined; assuming extern returning int	maintenance	Hercules\src\plugins\maintenance.c	205	
Warning	C4013	'addHookPre' undefined; assuming extern returning int	maintenance	Hercules\src\plugins\maintenance.c	550	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	259	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	290	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	309	
Warning	C4013	'hookStop' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	107	
Warning	C4013	'addHookPre' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	190	
Warning	C4013	'addHookPost' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	192	
Error	LNK2019	unresolved external symbol _GET_SYMBOL referenced in function _plugin_init	autopots	Hercules\vcproj-14\autopots.obj	1	
Error	MSB6006	"link.exe" exited with code 1120.	maintenance	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	MSB6006	"link.exe" exited with code 1120.	autopots	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	MSB6006	"link.exe" exited with code 1120.	noitem	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	LNK2019	unresolved external symbol _hookStop referenced in function _pc_authok_pre	maintenance	Hercules\vcproj-14\maintenance.obj	1	
Error	LNK1120	1 unresolved externals	autopots	Hercules\plugins\autopots.dll	1	
Error	LNK2019	unresolved external symbol _hookStop referenced in function _npc_parse_unknown_mapflag_pre	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK2019	unresolved external symbol _addHookPre referenced in function _plugin_init	maintenance	Hercules\vcproj-14\maintenance.obj	1	
Error	LNK2019	unresolved external symbol _addHookPre referenced in function _plugin_init	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK1120	2 unresolved externals	maintenance	Hercules\plugins\maintenance.dll	1	
Error	LNK2019	unresolved external symbol _addHookPost referenced in function _plugin_init	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK1120	3 unresolved externals	noitem	Hercules\plugins\noitem.dll	1	
Warning	C4715	'buildin_storageadditem': not all control paths return a value	storageadditem	hercules\src\plugins\storageadditem.c	72	
Error	C1083	Cannot open include file: 'common/malloc.h': No such file or directory	partyscript	Hercules\src\plugins\partyscript.c	13	
Edited by Like it~*

Share this post


Link to post
Share on other sites

17 answers to this question

Recommended Posts

  • 0

It would be wiser to post errors in English, if asking for help in English...

 

I don't speak this language...

Edited by Habilis

Share this post


Link to post
Share on other sites
  • 0

It would be wiser to post errors in English, if asking for help in English...

 

I don't speak this language...

 

I'm sorry. I had forgotten. Now it has been fixed. Tested with today's version of Hercules.

 

Severity	Code	Description	Project	File	Line	Suppression State
Warning	C4018	'<=': signed/unsigned mismatch	char-server	hercules\src\char\int_party.c	320	
Warning	C4013	'GET_SYMBOL' undefined; assuming extern returning int	autopots	Hercules\src\plugins\autopots.c	267	
Warning	C4047	'=': 'clif_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	267	
Warning	C4047	'=': 'script_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	268	
Warning	C4047	'=': 'pc_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	269	
Warning	C4047	'=': 'atcommand_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	270	
Warning	C4047	'=': 'map_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	271	
Warning	C4047	'=': 'unit_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	272	
Warning	C4047	'=': 'timer_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	273	
Warning	C4047	'=': 'itemdb_interface *' differs in levels of indirection from 'int'	autopots	Hercules\src\plugins\autopots.c	274	
Warning	C4013	'hookStop' undefined; assuming extern returning int	maintenance	Hercules\src\plugins\maintenance.c	205	
Warning	C4013	'addHookPre' undefined; assuming extern returning int	maintenance	Hercules\src\plugins\maintenance.c	550	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	259	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	290	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	309	
Warning	C4013	'hookStop' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	107	
Warning	C4013	'addHookPre' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	190	
Warning	C4013	'addHookPost' undefined; assuming extern returning int	noitem	Hercules\src\plugins\noitem.c	192	
Error	LNK2019	unresolved external symbol _GET_SYMBOL referenced in function _plugin_init	autopots	Hercules\vcproj-14\autopots.obj	1	
Error	MSB6006	"link.exe" exited with code 1120.	maintenance	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	MSB6006	"link.exe" exited with code 1120.	autopots	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	MSB6006	"link.exe" exited with code 1120.	noitem	C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	638	
Error	LNK2019	unresolved external symbol _hookStop referenced in function _pc_authok_pre	maintenance	Hercules\vcproj-14\maintenance.obj	1	
Error	LNK1120	1 unresolved externals	autopots	Hercules\plugins\autopots.dll	1	
Error	LNK2019	unresolved external symbol _hookStop referenced in function _npc_parse_unknown_mapflag_pre	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK2019	unresolved external symbol _addHookPre referenced in function _plugin_init	maintenance	Hercules\vcproj-14\maintenance.obj	1	
Error	LNK2019	unresolved external symbol _addHookPre referenced in function _plugin_init	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK1120	2 unresolved externals	maintenance	Hercules\plugins\maintenance.dll	1	
Error	LNK2019	unresolved external symbol _addHookPost referenced in function _plugin_init	noitem	Hercules\vcproj-14\noitem.obj	1	
Error	LNK1120	3 unresolved externals	noitem	Hercules\plugins\noitem.dll	1	
Warning	C4715	'buildin_storageadditem': not all control paths return a value	storageadditem	hercules\src\plugins\storageadditem.c	72	
Error	C1083	Cannot open include file: 'common/malloc.h': No such file or directory	partyscript	Hercules\src\plugins\partyscript.c	13	

Share this post


Link to post
Share on other sites
  • 0

For example autopot.c

 

 

Replace top of file by

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */

#include "common/HPMi.h"
#include "common/timer.h"
#include "map/script.h"
#include "map/pc.h"
#include "map/map.h"
#include "map/unit.h"
#include "map/atcommand.h"
#include "map/itemdb.h"

#include "plugins/HPMHooking.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) */

#define OPTION_AUTOPOTS 0x40000000

 

 

Then,

 

remove 

	clif = GET_SYMBOL("clif");
    script = GET_SYMBOL("script");
	pc = GET_SYMBOL("pc");
	atcommand = GET_SYMBOL("atcommand");
	map = GET_SYMBOL("map");
	unit = GET_SYMBOL("unit");
	timer = GET_SYMBOL("timer");
	itemdb = GET_SYMBOL("itemdb");

from 

 

HPExport void plugin_init (void) {
 

 

Recompile..

 

samme principle apply to others...

 

 

 

UPD : Maintenance.c

 

add

#include "plugins/HPMHooking.h" 

before

#include "common/HPMDataCheck.h"
Edited by Habilis

Share this post


Link to post
Share on other sites
  • 0

 

For example autopot.c

 

 

Replace top of file by

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */

#include "common/HPMi.h"
#include "common/timer.h"
#include "map/script.h"
#include "map/pc.h"
#include "map/map.h"
#include "map/unit.h"
#include "map/atcommand.h"
#include "map/itemdb.h"

#include "plugins/HPMHooking.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) */

#define OPTION_AUTOPOTS 0x40000000

 

 

Then,

 

remove 

	clif = GET_SYMBOL("clif");
    script = GET_SYMBOL("script");
	pc = GET_SYMBOL("pc");
	atcommand = GET_SYMBOL("atcommand");
	map = GET_SYMBOL("map");
	unit = GET_SYMBOL("unit");
	timer = GET_SYMBOL("timer");
	itemdb = GET_SYMBOL("itemdb");

from 

 

HPExport void plugin_init (void) {
 

 

Recompile..

 

samme principle apply to others...

 

 

 

UPD : Maintenance.c

 

add

#include "plugins/HPMHooking.h" 

before

#include "common/HPMDataCheck.h"

 

Wow. Thank you very much. I solved most of the problems. But there are still some. Look:

 

 

 

Severity	Code	Description	Project	File	Line	Suppression State
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	1071	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2049	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2050	
Warning	C4018	'>=': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2523	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2581	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2587	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	2717	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	3722	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	3724	
Warning	C4018	'<': signed/unsigned mismatch	hBG	Hercules\src\plugins\hBG.c	3862	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	maintenance	Hercules\src\plugins\maintenance.c	551	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	noitem	Hercules\src\plugins\noitem.c	191	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	259	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	290	
Warning	C4018	'<=': signed/unsigned mismatch	market	Hercules\src\plugins\market.c	309	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	191	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	191	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2143	syntax error: missing ')' before 'string'	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	191	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2059	syntax error: ')'	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	192	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2143	syntax error: missing ')' before 'string'	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2059	syntax error: ')'	maintenance	Hercules\src\plugins\maintenance.c	552	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	193	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	194	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	195	
Error	C1083	Cannot open include file: 'common/malloc.h': No such file or directory	partyscript	Hercules\src\plugins\partyscript.c	15	
Warning	C4715	'buildin_storageadditem': not all control paths return a value	storageadditem	hercules\src\plugins\storageadditem.c	74	
Warning	C4267	'initializing': conversion from 'size_t' to 'unsigned short', possible loss of data	vending_extended	Hercules\src\plugins\vending_extended.c	86	 

 

 

 

maintenance.c

 

 

//===== Hercules Plugin ======================================
//= @Maintenance mod
//===== By: ==================================================
//= AnnieRuru
//===== Current Version: =====================================
//= 1.4
//===== Compatible With: ===================================== 
//= Hercules 2015-12-08
//===== Description: =========================================
//= Turn the server into maintenance mode.
//= -> blocked players from login the game for a set of duration
//= a GM will announce the maintenance, and players will be kicked out after a while for maintenance. 
//= Player below {Group ID can login} will not able to login for the duration
//= but GM99 can always login without restriction
//===== Topic ================================================
//= http://hercules.ws/board/topic/7127-
//===== Additional Comments: =================================  
//= -- AtCommands --
//= @maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>
//= @maintenanceoff
//=
//= -- Script Commands --
//= maintenance <Group ID can stay 1~99>, <duration to kick in minute>, <maintenance duration in minute> { , <reason> };
//=   reason field is optional, default to '*Regular server maintenance*'
//= maintenanceoff { <reason> };
//=   reason field is optional, default to '*maintenanceoff*'
//= maintenancecheck( <type> );
//=   default:
//=	    return 0 if server is normal
//=	    return 1 if server is going to have maintenance
//=	    return 2 if server is having maintenance
//=   type 1:
//=	    return the Group ID that has been denied to login
//=   type 2:
//=     return the time stamp of last/current starting time for the maintenance
//=   type 3:
//=     return the time stamp of last/current ending time for the maintenance
//=   type 4:
//=     return the ID of last used maintenance_countid ( for debugging only )
//=   type 5:
//=     return the ID of last used maintenance_timerid ( for debugging only )
//============================================================

/*	Remember to build a Sql table !
create table maintenance (
	id int(11) primary key auto_increment,
	account_id int(11),
	name varchar(23),
	reason varchar(99),
	minlv2connect tinyint(4),
	order_time datetime,
	start_time datetime,
	end_time datetime
) engine = innodb;
*/

//	change the announcement color
int maintenance_color = 0xFFFF00;
//	If you still want to personalize each announcement to different color, just Ctrl+F 'maintenance_color' below

//	==========================================================

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "common/hercules.h"
#include "map/pc.h"
#include "map/map.h"
#include "map/intif.h"
#include "login/login.h"
#include "common/timer.h"
#include "common/strlib.h"
#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/sql.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"maintenance",	// Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"1.4",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

int maintenance_group = 1;
int maintenance_starttime = 1;
int maintenance_endtime = 1;
int maintenance_countid = INVALID_TIMER;
int maintenance_timerid = INVALID_TIMER;
char maintenance_timeformat[24];

int maintenance_progress( int tid, int64 tick, int id, intptr data ) {
	char output[CHAT_SIZE_MAX];
	timer->delete( maintenance_timerid, maintenance_progress );
	maintenance_timerid = INVALID_TIMER;
	safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode has ended. Players are able to login now." );
	intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	ShowStatus( CL_YELLOW "Maintenance has ended." CL_RESET "\n" );
	return false;
}

int maintenance_countdown( int tid, int64 tick, int id, intptr data ) {
	char output[CHAT_SIZE_MAX];
	int countdown = maintenance_starttime - (int)time(NULL);
	if ( countdown > 90 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d minutes", countdown /60 );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		if ( ( countdown % 60 ) > 0 ) // fine tune the timer
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 60 ) * 1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 60000, maintenance_countdown, 0, 0 );
	}
	else if ( countdown > 15 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d seconds", countdown );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		if ( ( countdown % 10 ) > 0 ) // fine tune the timer
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 10 ) * 1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 10000, maintenance_countdown, 0, 0 );
	}
	else if ( countdown > 0 ) {
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance will start in %d seconds", countdown );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = timer->add( timer->gettick() + 1000, maintenance_countdown, 0, 0 );
	}
	else {
		struct s_mapiterator* iter = mapit->alloc( MAPIT_NORMAL, BL_PC );
		TBL_PC *sd;
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance starts now. Every player will be kick out." );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
		for ( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) )
			if ( sd->group_id < maintenance_group )
				clif->authfail_fd( sd->fd, 1 );
		mapit->free(iter);
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
		maintenance_timerid = timer->add( timer->gettick() + ( ( maintenance_endtime - maintenance_starttime )*1000 ), maintenance_progress, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance has started." CL_RESET "\n" );
	}
	return false;
}

HPExport void server_online (void) {
	if ( SQL->Query( map->mysql_handle, "select minlv2connect, unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR )
		Sql_ShowDebug( map->mysql_handle );
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		short weekday = 0, hour = 0, minute = 0;
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3], min_display[3];
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_group = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 5, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
	}
	if ( maintenance_starttime > (int)time(NULL) ) {
		int countdown = maintenance_starttime - (int)time(NULL);
		if ( countdown > 60 )
			maintenance_countid = timer->add( timer->gettick() + ( ( countdown % 60 )*1000 ), maintenance_countdown, 0, 0 );
		else
			maintenance_countid = timer->add( timer->gettick() + 1000, maintenance_countdown, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance will start in %d min %d sec." CL_RESET "\n", countdown /60, countdown %60 );
	}
	else if ( maintenance_endtime > (int)time(NULL) ) {
		int countdown = maintenance_endtime - (int)time(NULL);
		maintenance_timerid = timer->add( timer->gettick() + ( countdown *1000 ), maintenance_progress, 0, 0 );
		ShowStatus( CL_YELLOW "Maintenance will end in %d min %d sec on %s." CL_RESET "\n", countdown/60, countdown %60, maintenance_timeformat );
	}
}

bool pc_authok_pre( struct map_session_data *sd, int *login_id2, time_t *expiration_time, int *group_id, struct mmo_charstatus *st, bool *changing_mapservers ) {
	nullpo_retr( false, sd );
	if ( (int)time(NULL) > maintenance_starttime && maintenance_endtime > (int)time(NULL) && *group_id < maintenance_group ) {
		clif->authfail_fd( sd->fd, 1 );
		hookStop();
		return false;
	}
	return true;
}

void clif_parse_LoadEndAck_pre( int *fd, struct map_session_data *sd ) {
	nullpo_retv(sd);
	if ( sd->state.connect_new ) {
		if ( maintenance_starttime > (int)time(NULL) ) {
			char output[CHAT_SIZE_MAX];
			safesnprintf( output, CHAT_SIZE_MAX, "Maintenance starts in %d min %d sec, last %d minutes. Server up by %s", ( maintenance_starttime - (int)time(NULL) ) /60, ( maintenance_starttime - (int)time(NULL) ) %60, ( maintenance_endtime - maintenance_starttime ) /60, maintenance_timeformat );
			clif->message( sd->fd, output );
		}
		else if ( maintenance_endtime > (int)time(NULL) ) {
			char output[CHAT_SIZE_MAX];
			safesnprintf( output, CHAT_SIZE_MAX, "Server is currently in maintenance mode, will end in %d min %d sec on %s", ( maintenance_endtime - (int)time(NULL) ) /60, ( maintenance_endtime - (int)time(NULL) ) %60, maintenance_timeformat );
			clif->message( sd->fd, output );
		}
	}
	return;
}

ACMD(maintenance) {
	int group_id = 0, kick_duration = 0, maintenance_duration = 0;
	char reason[99], esc_reason[198], esc_name[46], min_display[3], output[CHAT_SIZE_MAX];
	short weekday = 0, hour = 0, minute = 0;
	if ( maintenance_starttime > (int)time(NULL) ) {
		int countdown = maintenance_starttime - (int)time(NULL);
		clif->message( sd->fd, "Type '@maintenanceoff' to turn off maintenance mode." );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will start in %d min %d sec.", countdown /60, countdown %60 );
		clif->message( sd->fd, output );
		return true;
	}
	if ( maintenance_endtime > (int)time(NULL) ) {
		int countdown = maintenance_endtime - (int)time(NULL);
		clif->message( sd->fd, "Type '@maintenanceoff' to turn off maintenance mode." );
		safesnprintf( output, CHAT_SIZE_MAX, "Server is currently in maintenance mode, will end in %d min %d sec on %s", countdown /60, countdown %60, maintenance_timeformat );
		clif->message( sd->fd, output );
		return true;
	}
	if ( !message || !*message ) {
		clif->message( sd->fd, "@maintenance Syntax :" );
		clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
		return false;
	}
//	WTF ! sscanf can't be used ??
//	if ( sscanf( message, "%d %d %d %99[^\n]", &group_id, &kick_duration, &maintenance_duration, &reason ) < 4 ) {
//		clif->message( sd->fd, "@maintenance Syntax :" );
//		clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
//		return false;
//	}
//	now has to do the stupid string calculation 
	{
		int i = 0, j = 0, k = 0, l = strlen( message );
		char *temp = (char*)aMalloc( strlen( message ) +1 );
		while ( i <= l && k < 3 ) {
			if ( message[i] != ' ' && message[i] != '\0' ) {
				temp[j++] = message[i];
			}
			else if ( message[i-1] != ' ' ) {
				temp[j] = '\0';
				if ( k == 0 )
					group_id = atoi( temp );
				else if ( k == 1 )
					kick_duration = atoi( temp );
				else if ( k == 2 )
					maintenance_duration = atoi( temp );
				k++;
				j = 0;
			}
			i++;
		}
		safestrncpy( reason, &message[i], 99 );
		aFree( temp );
		if ( k < 3 ) {
			clif->message( sd->fd, "@maintenance Syntax :" );
			clif->message( sd->fd, "@maintenance <Group ID can stay 1~99> <duration to kick in minute> <maintenance duration in minute> <reason>" );
			return false;
		}
	}
	if ( !group_id ) {
		clif->message( sd->fd, "The Group ID field cannot be 0, otherwise normal player able to login." );
		return false;
	}
	if ( group_id < 1 || group_id > 99 ) {
		safesnprintf( output, 255, "Invalid Group ID %d. Range must between 1~99.", group_id );
		clif->message( sd->fd, output );
		return false;
	}
	if ( kick_duration <= 0 ) {
		clif->message( sd->fd, "Kick duration cannot be 0 or negative numbers." );
		return false;
	}
	if ( kick_duration > 1440 ) {
		clif->message( sd->fd, "Kick duration cannot be more than 1 day." );
		return false;
	}
	if ( maintenance_duration <= 0 ) {
		clif->message( sd->fd, "Maintenance duration cannot be 0 or negative numbers." );
		return false;
	}
	if ( maintenance_duration > 10080 ) {
		clif->message( sd->fd, "Maintenance duration cannot be more than 1 week." );
		return false;
	}
	if ( safestrnlen( reason, 99 ) < 4 ) {
		clif->message( sd->fd, "You must input a valid reason for doing this." );
		return false;
	}
	SQL->EscapeString( map->mysql_handle, esc_name, sd->status.name );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, %d, '%s', '%s', %d, now(), timestampadd( minute, %d, now() ), timestampadd( minute, %d, now() ) )", sd->status.account_id, esc_name, esc_reason, group_id, kick_duration, kick_duration + maintenance_duration ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	if ( SQL->Query( map->mysql_handle, "select unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		maintenance_group = group_id;
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		SQL->FreeResult( map->mysql_handle );
	}
	else {
		SQL->FreeResult( map->mysql_handle );
		return false;
	}
	{	// stupid date_format doesn't work
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3];
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will be commence in %d minutes. Players are adviced to log out right now. Maintenance last %d minutes. Server will come back up on %s", kick_duration, maintenance_duration, maintenance_timeformat );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	}
	maintenance_countid = timer->add( timer->gettick() +( ( kick_duration == 1 )? 1000 : 60000 ), maintenance_countdown, 0, 0 );
	ShowStatus( CL_YELLOW "Maintenance will start in %d min by " CL_GREEN "%s" CL_RESET ".\n", kick_duration, sd->status.name );
	return true;
}

ACMD(maintenanceoff) {
	char esc_name[46], output[CHAT_SIZE_MAX];
	if ( maintenance_endtime <= (int)time(NULL) ) {
		clif->message( sd->fd, "The server is currently in not in maintenance mode." );
		return true;
	}
	SQL->EscapeString( map->mysql_handle, esc_name, sd->status.name );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, %d, '%s', '   @maintenanceoff', 0, null, now(), now() )", sd->status.account_id, esc_name ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	if ( maintenance_countid != INVALID_TIMER ) {
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
	}
	if ( maintenance_timerid != INVALID_TIMER ) {
		timer->delete( maintenance_timerid, maintenance_progress );
		maintenance_timerid = INVALID_TIMER;
	}
	safesnprintf( output, CHAT_SIZE_MAX, "%s ended the Maintenance mode. Players are able to login now.", sd->status.name );
	intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	ShowStatus( CL_YELLOW "Maintenance has ended by " CL_GREEN "%s" CL_RESET ".\n", sd->status.name );
	return true;
}

//	maintenance <Group ID can stay 1~99>, <duration to kick in minute>, <maintenance duration in minute> { , <reason> };
BUILDIN(maintenance) {
	int group_id = 0, kick_duration = 0, maintenance_duration = 0;
	char reason[99], esc_reason[198], min_display[3];
	short weekday = 0, hour = 0, minute = 0;
	if ( maintenance_endtime > (int)time(NULL) ) {
		ShowError( "buildin_maintenance: Maintenance is currently ON.\n" );
		return false;
	}
	group_id = script_getnum(st,2);
	kick_duration = script_getnum(st,3);
	maintenance_duration = script_getnum(st,4);
	if ( !group_id ) {
		ShowError( "buildin_maintenance: Group ID field cannot be 0.\n" );
		return false;
	}
	if ( group_id < 1 || group_id > 99 ) {
		ShowError( "buildin_maintenance: Invalid Group ID %d. Range must between 1~99.\n", group_id );
		return false;
	}
	if ( kick_duration <= 0 ) {
		ShowError( "buildin_maintenance: Kick duration cannot be 0 or negative numbers.\n" );
		return false;
	}
	if ( kick_duration > 1440 ) {
		ShowError( "buildin_maintenance: Kick duration cannot be more than 1 day.\n" );
		return false;
	}
	if ( maintenance_duration <= 0 ) {
		ShowError( "buildin_maintenance: Maintenance duration cannot be 0 or negative numbers.\n" );
		return false;
	}
	if ( maintenance_duration > 10080 ) {
		ShowError( "buildin_maintenance: Maintenance duration cannot be more than 1 week.\n" );
		return false;
	}
	safesnprintf( reason, 99, script_hasdata(st,5)? script_getstr(st,5) : "   *Regular server maintenance*" );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, 0, 'NPC', '%s', %d, now(), timestampadd( minute, %d, now() ), timestampadd( minute, %d, now() ) )", esc_reason, group_id, kick_duration, kick_duration + maintenance_duration ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	if ( SQL->Query( map->mysql_handle, "select unix_timestamp( start_time ), unix_timestamp( end_time ), weekday( end_time ), hour( end_time ), minute( end_time ) from maintenance where id = ( select max(id) from maintenance )" ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	else if ( SQL->NextRow( map->mysql_handle ) == SQL_SUCCESS ) {
		char *data;
		maintenance_group = group_id;
		if ( SQL->GetData( map->mysql_handle, 0, &data, NULL ) == SQL_SUCCESS )
			maintenance_starttime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 1, &data, NULL ) == SQL_SUCCESS )
			maintenance_endtime = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 2, &data, NULL ) == SQL_SUCCESS )
			weekday = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 3, &data, NULL ) == SQL_SUCCESS )
			hour = atoi(data);
		if ( SQL->GetData( map->mysql_handle, 4, &data, NULL ) == SQL_SUCCESS )
			minute = atoi(data);
		SQL->FreeResult( map->mysql_handle );
	}
	else {
		SQL->FreeResult( map->mysql_handle );
		return false;
	}
	{	// stupid date_format doesn't work
		char* weekdayname[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
		char am_pm[3], output[CHAT_SIZE_MAX];
		if ( hour == 0 ) {
			hour = 12;
			safesnprintf( am_pm, 3, "AM" );
		}
		else if ( hour < 12 )
			safesnprintf( am_pm, 3, "AM" );
		else {
			hour = hour - 12;
			safesnprintf( am_pm, 3, "PM" );
		}
		if ( minute < 10 )
			safesnprintf( min_display, 3, "0%d", minute );
		else
			safesnprintf( min_display, 3, "%d", minute );
		safesnprintf( maintenance_timeformat, 24, "%s, %d:%s %s", weekdayname[ weekday ], hour, min_display, am_pm );
		safesnprintf( output, CHAT_SIZE_MAX, "Maintenance mode will be commence in %d minutes. Players are adviced to log out right now. Maintenance last %d minutes. Server will come back up on %s", kick_duration, maintenance_duration, maintenance_timeformat );
		intif->broadcast2( output, strlen(output) +1, maintenance_color, 0x190, 12, 0, 0);
	}
	maintenance_countid = timer->add( timer->gettick() +( ( kick_duration == 1 )? 1000 : 60000 ), maintenance_countdown, 0, 0 );
	ShowStatus( CL_YELLOW "Maintenance will start in %d min" CL_RESET ".\n", kick_duration );
	return true;
}

BUILDIN(maintenanceoff) {
	char reason[99], esc_reason[198];
	if ( maintenance_endtime <= (int)time(NULL) ) {
		ShowError( "buildin_maintenanceoff: Maintenance is currently OFF.\n" );
		return false;
	}
	safesnprintf( reason, 99, script_hasdata(st,2)? script_getstr(st,2) : "   *maintenance off*" );
	SQL->EscapeString( map->mysql_handle, esc_reason, reason );
	if ( SQL->Query( map->mysql_handle, "insert into maintenance values ( null, 0, 'NPC', '%s', 0, null, now(), now() )", esc_reason ) == SQL_ERROR ) {
		Sql_ShowDebug( map->mysql_handle );
		return false;
	}
	maintenance_group = 0;
	maintenance_starttime = (int)time(NULL);
	maintenance_endtime = (int)time(NULL);
	if ( maintenance_countid != INVALID_TIMER ) {
		timer->delete( maintenance_countid, maintenance_countdown );
		maintenance_countid = INVALID_TIMER;
	}
	if ( maintenance_timerid != INVALID_TIMER ) {
		timer->delete( maintenance_timerid, maintenance_progress );
		maintenance_timerid = INVALID_TIMER;
	}
	intif->broadcast2( "Maintenance mode has ended. Players are able to login now." , 255, maintenance_color, 0x190, 12, 0, 0);
	ShowStatus( CL_YELLOW "Maintenance has ended" CL_RESET ".\n" );
	return true;
}

BUILDIN(maintenancecheck) {
	int type = script_hasdata(st,2)? script_getnum(st,2) : 0;
	switch( type ) {
	default:
		if ( maintenance_starttime > (int)time(NULL) )
			script_pushint(st, 1);
		else if ( maintenance_endtime > (int)time(NULL) )
			script_pushint(st, 2);
		else
			script_pushint(st, 0);
		return true;
	case 1:
		script_pushint(st, maintenance_group);
		return true;
	case 2:
		script_pushint(st, maintenance_starttime);
		return true;
	case 3:
		script_pushint(st, maintenance_endtime);
		return true;
	case 4:
		script_pushint(st, maintenance_countid);
		return true;
	case 5:
		script_pushint(st, maintenance_timerid);
		return true;
//	case 6: // for some reason this cause memory leak
//		script_pushstr(st, maintenance_timeformat );
//		return true;
	}
}

HPExport void plugin_init (void) {
	addHookPre( "pc->authok", pc_authok_pre );
	addHookPre( "clif->pLoadEndAck", clif_parse_LoadEndAck_pre );

	addAtcommand( "maintenance", maintenance );
	addAtcommand( "maintenanceoff", maintenanceoff );

	addScriptCommand( "maintenance", "iii?", maintenance );
	addScriptCommand( "maintenanceoff", "?", maintenanceoff );
	addScriptCommand( "maintenancecheck", "?", maintenancecheck );
} 

 

 

 

noitem

 

 

//===== Hercules Plugin ======================================
//= noitem mapflag
//===== By: ==================================================
//= AnnieRuru
//===== Current Version: =====================================
//= 1.3
//===== Compatible With: ===================================== 
//= Hercules 2015-11-12
//===== Description: =========================================
//= block players from using items
//===== Topic ================================================
//= http://herc.ws/board/topic/4830-noitem-mapflag/
//===== Additional Comments: =================================  
//= prontera   mapflag   noitem   IT_WEAPON,IT_ARMOR
//= block players from equipping weapon and armor
//============================================================

#include "common/hercules.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "map/pc.h"
#include "common/memmgr.h"
#include "plugins/HPMHooking.h" 
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"noitem", // Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"1.3",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

struct mapflag_data {
	int noitem;
	int noitemlist[50];
};

//	flush all noitem mapflag back to default upon @reloadscript
void map_flags_init_pre(void) {
	int i;
	for ( i = 0; i < map->count; i++ ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[i], 0 );
		if ( mf )
			removeFromMAPD( &map->list[i], 0 );
	}
	return;
}

void npc_parse_unknown_mapflag_pre( const char *name, char *w3, char *w4, const char* start, const char* buffer, const char* filepath, int *retval ) {
	if ( !strcmp(w3,"noitem") ) {
		int id = 0, i = 0, j = 0, k = 0, l = strlen(w4);
		char *temp = (char*)aMalloc( strlen(w4) +1 );
		struct item_data *i_data;
		struct mapflag_data *mf;
		if ( l ) {
			int16 m = map->mapname2mapid( name );
			CREATE( mf, struct mapflag_data, 1 );
			while ( i <= l && k < 50 ) {
				if ( w4[i] != ' ' && w4[i] != '	' && w4[i] != ',' && w4[i] != '\0' ) {
					temp[j++] = w4[i];
				}
				else if ( w4[i-1] != ' ' && w4[i-1] != '	' && w4[i-1] != ',' ) {
					temp[j] = '\0';
					if ( !strcmp( temp, "IT_HEALING" ) || !strcmp( temp, "0" ) )
						mf->noitemlist[k] = 0;
					else if ( !strcmp( temp, "IT_USABLE" ) || !strcmp( temp, "2" ) )
						mf->noitemlist[k] = 2;
					else if ( !strcmp( temp, "IT_WEAPON" ) || !strcmp( temp, "4" ) )
						mf->noitemlist[k] = 4;
					else if ( !strcmp( temp, "IT_ARMOR" ) || !strcmp( temp, "5" ) )
						mf->noitemlist[k] = 5;
					else if ( !strcmp( temp, "IT_CARD" ) || !strcmp( temp, "6" ) )
						mf->noitemlist[k] = 6;
					else if ( !strcmp( temp, "IT_DELAYCONSUME" ) || !strcmp( temp, "11" ) )
						mf->noitemlist[k] = 11;
					else if ( !strcmp( temp, "IT_CASH" ) || !strcmp( temp, "18" ) )
						mf->noitemlist[k] = 18;
					else if ( atoi(temp) == 0 ) {
						i_data = itemdb->search_name( temp );
						if ( i_data )
							mf->noitemlist[k] = i_data->nameid;
						else {
							ShowWarning("npc_parse_mapflag: Item name \"%s\" does not exist.\n    Mapflag noitem: At %s (file '%s', line '%d').\n", temp, name, filepath, strline(buffer,start-buffer) );
							mf->noitemlist[k] = -1;
						}
					}
					else {
						id = atoi(temp);
						if ( itemdb->exists(id) )
							mf->noitemlist[k] = id;
						else {
							ShowWarning("npc_parse_mapflag: Item ID \"%s\" does not exist.\n    Mapflag noitem: At %s (file '%s', line '%d').\n", temp, name, filepath, strline(buffer,start-buffer) );
							mf->noitemlist[k] = -1;
						}
					}
					k++;
					j = 0;
				}
				i++;
			}
			mf->noitem = k;
			addToMAPD( &map->list[m], mf, 0, true );
		}
		else
			ShowWarning("npc_parse_mapflag: no Item ID/type input.\n           Mapflag noitem: At %s (file '%s', line '%d').\n", name, filepath, strline(buffer,start-buffer));
		aFree(temp);
		hookStop();
	}
	return;
}

int pc_isequip_post( int retVal, struct map_session_data *sd, int *n ) {
	if ( retVal == 1 ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
		if ( mf && mf->noitem ) {
			struct item_data *item = sd->inventory_data[*n];
			int i = 0, slot = 0;
			ARR_FIND( 0, mf->noitem, i, item->nameid == mf->noitemlist[i] || item->type == mf->noitemlist[i] );
			if ( i < mf->noitem )
				return 0;
			if ( !itemdb_isspecial( sd->status.inventory[*n].card[0] ) ) {
				for ( slot = 0; slot < MAX_SLOTS; slot++ ) {
					if ( sd->status.inventory[*n].card[slot] ) {
						struct item_data *i_data = itemdb->exists( sd->status.inventory[*n].card[slot] );
						ARR_FIND( 0, mf->noitem, i, i_data->nameid == mf->noitemlist[i] || i_data->type == mf->noitemlist[i] );
						if ( i < mf->noitem )
							return 0;
					}
				}
			}
		}
	}
	return retVal;
}

int pc_isUseitem_post( int retVal, struct map_session_data *sd, int *n ) {
	if ( retVal == 1 ) {
		struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
		if ( mf && mf->noitem ) {
			struct item_data *item = sd->inventory_data[*n];
			int i = 0;
			ARR_FIND( 0, mf->noitem, i, mf->noitemlist[i] == sd->status.inventory[*n].nameid || item->type == mf->noitemlist[i] );
			if ( i < mf->noitem )
				return 0;
		}
	}
	return retVal;
}

int pc_checkitem_post( int retVal, struct map_session_data *sd ) {
	struct mapflag_data *mf = getFromMAPD( &map->list[sd->bl.m], 0 );
	int i, calc_flag = 0;
	if ( sd->state.vending )
		return 0;
	if ( mf && mf->noitem ) {
		for ( i = 0; i < MAX_INVENTORY; i++ ) {
			int j = 0, slot = 0;
			struct item_data *i_data = itemdb->exists( sd->status.inventory[i].nameid );
			if ( sd->status.inventory[i].nameid == 0 || !sd->status.inventory[i].equip )
				continue;
			ARR_FIND( 0, mf->noitem, j, mf->noitemlist[j] == i_data->type || mf->noitemlist[j] == sd->status.inventory[i].nameid );
			if ( j < mf->noitem ) {
				pc->unequipitem(sd, i, 2);
				calc_flag = 1;
				continue;
			}
			if ( !itemdb_isspecial( sd->status.inventory[i].card[0] ) ) {
				for ( slot = 0; slot < MAX_SLOTS; slot++ ) {
					if ( sd->status.inventory[i].card[slot] ) {
						struct item_data *i_datac = itemdb->exists( sd->status.inventory[i].card[slot] );
						ARR_FIND( 0, mf->noitem, j, mf->noitemlist[j] == i_datac->type || mf->noitemlist[j] == sd->status.inventory[i].card[slot] );
						if ( j < mf->noitem ) {
							pc->unequipitem(sd, i, 2);
							calc_flag = 1;
							break;
						}
					}
				}
			}
		}
		if ( calc_flag && sd->state.active ) {
			pc->checkallowskill(sd);
			status_calc_pc( sd,SCO_NONE );
		}
	}
	return retVal;
}

HPExport void plugin_init (void) {
	addHookPre( "map->flags_init", map_flags_init_pre );
	addHookPre( "npc->parse_unknown_mapflag", npc_parse_unknown_mapflag_pre );
	addHookPost( "pc->isequip", pc_isequip_post );
	addHookPost( "pc->isUseitem", pc_isUseitem_post );
	addHookPost( "pc->checkitem", pc_checkitem_post );
} 

 

 

 

partyscript.c

 

 

// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Mhalicot PartyScript Hercules Plugin
// Special Thanks for Mr. [Hercules/Ind]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */
#include "common/HPMi.h"
#include "common/cbasetypes.h"
#include "common/strlib.h"
#include "common/utils.h"
#include "common/malloc.h"
#include "common/mmo.h"
#include "common/db.h"
#include "map/atcommand.h"
#include "map/script.h"
#include "map/party.h"
#include "map/intif.h"
#include "map/status.h"
#include "map/clif.h"
#include "map/map.h"
#include "map/mapreg.h"
#include "map/pc.h"
#include "map/instance.h"
#include "plugins/HPMHooking.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) */

#define party_add_member(party_id,sd) party_reply_invite_mine(sd,party_id,1)
#define safestrncpy(dst,src,n)       (strlib->safestrncpy((dst),(src),(n)))
#define idb_remove(db,k)    ( (db)->remove((db),DB->i2key(k),NULL) )
/*
1.0 Initial HPM Release [Mhalicot]
1.1 Rewrite party_delmember, removemember2 dropped.
1.2 Update Compatibility to latest Revision 137**
2.0 Update codes, Drop some useless codes.
2.1 Fixed Map crash when using designate in Party Window
2.2 Resolved crashing issue when leaving party from instance. [Mumbles / Haru]
3.0 Added @leaveparty Command [Mhalicot]
3.1 Fixed Various Compile Warnings and some logic [Dastgir]
---------------------------------------
Documentation
---------------------------------------

*party_create("<party name>"{,<character id>{,<item share>,<item share type>}});

Organizes a party with the attached or specified character as leader. If
successful, the command returns 1 and sets the global temporary variable
"$@party_create_id" to the ID of the party created.

Additionally, item sharing options can be provided:
 - Item Share: 0-Each Take (default), 1-Party Share
 - Item Share Type: 0-Each Take (default), 1-Even Share

These values are returned upon failure:
 0: Unknown error.
-1: Player not found.
-2: Player already has a party.
-3: Party name exists.

---------------------------------------

*party_destroy(<party id>);

Disbands a party. The command returns 1 upon success and 0 upon failure.

---------------------------------------

*party_addmember(<party id>,<character id>);

Adds a player to an existing party.

The command returns 1 upon success, and these values upon failure:
 0: Unknown error.
-1: Player not found.
-2: Player already has a party.
-3: Party not found.
-4: Party is full.

---------------------------------------

*party_delmember({<character id>}); 
 
Removes a player from his/her party. If no player is specified, the command 
will run for the invoking player. If that player is the only party member 
remaining, the party will be disbanded. 
 
The command returns 1 upon success, and these values upon failure: 
 0: Unknown error. 
-1: Player not found. 
-2: Player is not in the party. 

---------------------------------------

*party_changeleader(<party id>,<character id>);

Transfers leadership of a party to the specified character. The original
party leader doesn't need be online.

The command returns 1 upon success, and these values upon failure:
 0: Unknown error.
-1: Party not found.
-2: Player not found.
-3: Player is not in the party.
-4: Player is already party leader

---------------------------------------

*party_changeoption(<party id>,<option>,<flag>);

Changes a party option.

Valid options are:
 0 - Exp Share (flags: 0-Each Take, 1-Even Share)
 1 - Item Share (flags: 0-Each Take, 1-Party Share)
 2 - Item Share Type (flags: 0-Each Take, 1-Even Share)

The command returns 1 upon success, and these values upon failure:
 0: Invalid option.
-1: Party not found.
*/
HPExport struct hplugin_info pinfo = {
        "partyscript",		// Plugin name
        SERVER_TYPE_MAP,	// Which server types this plugin works with?
        "2.2",				// Plugin version
        HPM_VERSION,		// HPM Version (don't change, macro is automatically updated)
};

int create_byscript;
int party_change_leader_val = 0;
struct party_data *party_change_leader_p = NULL;

int party_create_mine(struct map_session_data *sd,char *name,int item,int item2) {
	struct party_member leader;
	char tname[NAME_LENGTH];

	safestrncpy(tname, name, NAME_LENGTH);
	trim(tname);

	if( !tname[0] ) {// empty name
		return 0;
	}

	if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating ) {// already associated with a party
		clif->party_created(sd,2);
		return -2;
	}

	sd->party_creating = true;

	party->fill_member(&leader, sd, 1);

	intif->create_party(&leader,name,item,item2);
	return 1;
}

void party_created_mine(int account_id,int char_id,int fail,int party_id,char *name) {
	struct map_session_data *sd;
	sd=map->id2sd(account_id);

	if (!sd || sd->status.char_id != char_id || !sd->party_creating ) {
		//Character logged off before creation ack?
		if (!fail) //break up party since player could not be added to it.
			intif->party_leave(party_id,account_id,char_id);
		return;
	}

	sd->party_creating = false;

	if( !fail ) {
		sd->status.party_id = party_id;
		clif->party_created(sd,0); //Success message
		//We don't do any further work here because the char-server sends a party info packet right after creating the party 
		if(create_byscript) {     //returns party id in $@party_create_id if party is created by script 
		  mapreg->setreg(script->add_str("$@party_create_id"),party_id); 
		  create_byscript = 0; 
		}
	} else 
		clif->party_created(sd,1); // "party name already exists"
}

int party_reply_invite_mine(struct map_session_data *sd,int party_id,int flag) {
	struct map_session_data* tsd;
	struct party_member member;

	if( sd->party_invite != party_id ) {// forged
		sd->party_invite = 0;
		sd->party_invite_account = 0;
		return 0;
	}
	tsd = map->id2sd(sd->party_invite_account);

	if( flag == 1 && !sd->party_creating && !sd->party_joining ) {// accepted and allowed
		sd->party_joining = true;
		party->fill_member(&member, sd, 0);
		intif->party_addmember(sd->party_invite, &member);
		return 1;
	} else {// rejected or failure
		sd->party_invite = 0;
		sd->party_invite_account = 0;
		if( tsd != NULL )
			clif->party_inviteack(tsd,sd->status.name,1);
		return 0;
	}
	return 0;
}

void party_reply_invite_overload(struct map_session_data *sd,int party_id,int flag) {
	party_reply_invite_mine(sd,party_id,flag);
}

//options: 0-exp, 1-item share, 2-pickup distribution
int party_setoption(struct party_data *pdata, int option, int flag) {
	int i;
	ARR_FIND(0,MAX_PARTY,i,pdata->party.member[i].leader);
	if(i >= MAX_PARTY)
		return 0;
	switch(option) {
		case 0:
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,flag,pdata->party.item);
			break;
		case 1:
			if(flag) flag = pdata->party.item|1;
			else flag = pdata->party.item&~1;
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,pdata->party.exp,flag);
			break;
		case 2:
			if(flag) flag = pdata->party.item|2;
			else flag = pdata->party.item&~2;
			intif->party_changeoption(pdata->party.party_id,pdata->party.member[i].account_id,pdata->party.exp,flag);
			break;
		default:
			return 0;
			break;
	}
	return 1;
}

bool party_changeleader_mine(struct map_session_data *sd, struct map_session_data *tsd) {
	int mi, tmi;
	struct party_data *p = party_change_leader_p;

	party_change_leader_p = NULL;

	if ( !p ) {
		if (!sd || !sd->status.party_id) {
			party_change_leader_val = -1;
			return false;
		}

		if (!tsd || tsd->status.party_id != sd->status.party_id) {
			clif->message(sd->fd, "Target character must be online and in your current party.");
			party_change_leader_val = -3;
			return false;
		}

		if ( map->list[sd->bl.m].flag.partylock ) {
			clif->message(sd->fd, "You cannot change party leaders on this map.");
			party_change_leader_val = 0;
			return false;
		}

		if ((p = party->search(sd->status.party_id)) == NULL ) {
			party_change_leader_val = -1;
			return false;
		}

		ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
		if (mi == MAX_PARTY) {
			party_change_leader_val = 0; //Shouldn't happen
			return false;
		}

		if (!p->party.member[mi].leader) {
			clif->message(sd->fd, "You need to be a party leader to use this command.");
			party_change_leader_val = 0;
			return false;
		}

		ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
		if (tmi == MAX_PARTY) {
			party_change_leader_val = 0; //Shouldn't happen
			return false;
		}
	} else {
		ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader);
		ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd ==  tsd);
	}

	if (!p->party.member[mi].leader) {
		clif->message(sd->fd, "You need to be a party leader to use this command.");
		party_change_leader_val = 0;
		return false;
	}

	ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
	if (tmi == MAX_PARTY) {
		party_change_leader_val = 0; //Shouldn't happen
		return false;
	}

	//Change leadership.
	p->party.member[mi].leader = 0;
	if (p->data[mi].sd && p->data[mi].sd->fd)
		clif->message(p->data[mi].sd->fd, "Leadership transferred.");

	p->party.member[tmi].leader = 1;
	if (p->data[tmi].sd && p->data[tmi].sd->fd)
		clif->message(p->data[tmi].sd->fd, "You've become the party leader.");

	//Update info.
	intif->party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
	clif->party_info(p,NULL);
	party_change_leader_val = 1;
	return true;
}

/*==========================================
 * party_create "<party name>"{,<char id>{,<item share: 0-no. 1-yes>{,<item share type: 0-favorite. 1-shared>}}};
 * Return values:
 *      -3      - party name is exist
 *      -2      - player is in party already
 *      -1      - player is not found
 *      0       - unknown error
 *      1       - success, will return party id $@party_create_id
 *------------------------------------------*/
BUILDIN(party_create) {
	char party_name[NAME_LENGTH];
	int item1 = 0, item2 = 0;
	TBL_PC *sd = NULL;

	if( (!script_hasdata(st,3) && !(sd = script->rid2sd(st))) || (script_hasdata(st,3) && !(sd = map->charid2sd(script_getnum(st,3)))) ) {
		script_pushint(st,-1);
		return false;
	}

	if( sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	safestrncpy(party_name,script_getstr(st,2),NAME_LENGTH);
	trim(party_name);
	if( party->searchname(party_name) ) {
		script_pushint(st,-3);
		return false;
	}

	if( script_getnum(st,4) )
		item1 = 1;

	if( script_getnum(st,5) )
		item2 = 1;

	create_byscript = 1;
	script_pushint(st,party_create_mine(sd,party_name,item1,item2));
	return true;
}

/*==========================================
 * party_addmember <party id>,<char id>;
 * Adds player to specified party
 * Return values:
 *      -4      - party is full
 *      -3      - party is not found
 *      -2      - player is in party already
 *      -1      - player is not found
 *      0       - unknown error
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_addmember) {
	int party_id = script_getnum(st,2);
	TBL_PC *sd;
	struct party_data *pty;

	if( !(sd = map->charid2sd(script_getnum(st,3))) ) {
		script_pushint(st,-1);
		return false;
	}

	if( sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	if( !(pty = party->search(party_id)) ) {
		script_pushint(st,-3);
		return false;
	}

	if( pty->party.count >= MAX_PARTY ) {
		script_pushint(st,-4);
		return false;
	}

	sd->party_invite = party_id;
	script_pushint(st,party_add_member(party_id,sd));
	return true;
}

/*==========================================
 * party_delmember {<char id>}; 
 * Removes player from his/her party 
 * Return values: 
 *      -2      - player is not in party 
 *      -1      - player is not found 
 *      0       - unknown error 
 *      1       - success 
 *------------------------------------------*/
BUILDIN(party_delmember) {
	TBL_PC *sd = NULL;

	if( (!script_hasdata(st,2) && !(sd = script->rid2sd(st))) || 
		(script_hasdata(st,2) && !(sd = map->charid2sd(script_getnum(st,2))))
	  ){
		script_pushint(st,-1);
		return false;
	}

	if( !sd->status.party_id ) {
		script_pushint(st,-2);
		return false;
	}

	script_pushint(st,party->leave(sd));
	return true;
}

/*==========================================
 * party_changeleader <party id>,<char id>;
 * Can change party leader even the leader is not online
 * Return values:
 *      -4      - player is party leader already 
 *      -3      - player is not in this party
 *      -2      - player is not found
 *      -1      - party is not found
 *      0       - unknown error
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_changeleader) {
	int i, party_id = script_getnum(st,2);
	TBL_PC *sd = NULL;
	TBL_PC *tsd = NULL;
	struct party_data *pty = NULL;

	if( !(pty = party->search(party_id)) ) {
		script_pushint(st,-1);
		return false;
	}

	if( !(tsd = map->charid2sd(script_getnum(st,3))) ) {
		script_pushint(st,-2);
		return false;
	}

	if( tsd->status.party_id != party_id ) {
		script_pushint(st,-3);
		return false;
	}

	ARR_FIND(0,MAX_PARTY,i,pty->party.member[i].leader);
	if( i >= MAX_PARTY ) {  //this is should impossible!
		script_pushint(st,0);
		return false;
	}

	if( pty->data[i].sd == tsd ) {
		script_pushint(st,-4);
		return false;
	}

	party_change_leader_p = pty;
	party_changeleader_mine(sd,tsd);

	script_pushint(st,party_change_leader_val);
	return true;
}

/*==========================================
 * party_changeoption <party id>,<option>,<flag>;
 * Return values:
 *      -1      - party is not found
 *      0       - invalid option
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_changeoption) {
	struct party_data *pty;

	if( !(pty = party->search(script_getnum(st,2))) ) {
		script_pushint(st,-1);
		return true;
	}

	script_pushint(st,party_setoption(pty,script_getnum(st,3),script_getnum(st,4)));
	return true;
}

/*==========================================
 * party_destroy <party id>;
 * Destroys party with party id. 
 * Return values:
 *      0       - failed
 *      1       - success
 *------------------------------------------*/
BUILDIN(party_destroy) {
	int i;
	struct party_data *pty;

	if( !(pty = party->search(script_getnum(st,2))) ) {
		script_pushint(st,0);
	}

	ARR_FIND(0,MAX_PARTY,i,pty->party.member[i].leader);
	if( i >= MAX_PARTY || !pty->data[i].sd ) { //leader not online
		int j;
		for( j = 0; j < MAX_PARTY; j++ ) {
			TBL_PC *sd = pty->data[j].sd;
			if(sd)
				party->member_withdraw(pty->party.party_id,sd->status.account_id,sd->status.char_id);
			else if( pty->party.member[j].char_id )
			intif->party_leave(pty->party.party_id,pty->party.member[j].account_id,pty->party.member[j].char_id);
		}
		//party_broken_mine(pty->party.party_id);
		party->broken(pty->party.party_id);
		script_pushint(st,1);
	}
	else    //leader leave = party broken
		script_pushint(st,party->leave(pty->data[i].sd));
	return true;
}

/*==========================================
 *
 *------------------------------------------*/
ACMD(party) {
	char party_name[NAME_LENGTH];

	memset(party_name, '\0', sizeof(party_name));

	if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
		clif->message(fd, "Please enter a party name (usage: @party <party_name>).");
		return false;
	}

	party_create_mine(sd, party_name, 0, 0);
	return true;
}

ACMD(leaveparty) {

	if( !sd->status.party_id ) {
		clif->message(fd, "You must have a party to use this command");
		return false;
	}

	party->leave(sd);
	return true;
}
ACMD(partyoption) {
	struct party_data *p;
	int mi, option;
	char w1[16], w2[16];

	if (sd->status.party_id == 0 || (p = party->search(sd->status.party_id)) == NULL) {
		clif->message(fd, "You need to be a party leader to use this command.");
		return false;
	}

	ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
	if (mi == MAX_PARTY)
		return false; //Shouldn't happen

	if (!p->party.member[mi].leader) {
		clif->message(fd, "You need to be a party leader to use this command.");
		return false;
	}

	if(!message || !*message || sscanf(message, "%15s %15s", w1, w2) < 2) {
		clif->message(fd, "Usage: @partyoption <pickup share: yes/no> <item distribution: yes/no>");
		return false;
	}

	option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0);

	//Change item share type.
	if (option != p->party.item)
		party->changeoption(sd, p->party.exp, option);
	else
		clif->message(fd, "There's been no change in the setting.");

	return true;
}

/* Server Startup */
HPExport void plugin_init (void) {

	//Commands
	addAtcommand("partyoption",partyoption);
	addAtcommand("leaveparty",leaveparty);
	addAtcommand("party",party);
	
	//Scripts
	addScriptCommand("party_changeoption","iii",party_changeoption);
	addScriptCommand("party_changeleader","ii",party_changeleader);
	addScriptCommand("party_addmember","ii",party_addmember);
	addScriptCommand("party_delmember","?",party_delmember);
	addScriptCommand("party_create","s???",party_create);
	addScriptCommand("party_destroy","i",party_destroy);

	party->changeleader = &party_changeleader_mine;
	party->reply_invite = &party_reply_invite_overload;
	party->created = &party_created_mine;
	party->create = &party_create_mine;
};
 

 

 

 

I removed from partyscript.c

#include "common/malloc.h"

Error change to

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2039	'safestrncpy': is not a member of 'strlib_interface'	partyscript	Hercules\src\plugins\partyscript.c	343	
Error	C2039	'safestrncpy': is not a member of 'strlib_interface'	partyscript	Hercules\src\plugins\partyscript.c	138	

 

 

vending_extended.c

 

 

/**
 * Extended Vending System
 * Please Check conf/ExtendedVending.conf, db/item_vending.txt, db/item_db2.conf
 * By Dastgir/Hercules
 */

/*
Add Following Items to ClientSide:

idnum2itemdisplaynametable.txt
    30000#Zeny#
    30001#Cash#

idnum2itemresnametable.txt
    30000#±ÝÈ#
    30001#¹Ì½º¸±È­#
*/

#include "common/hercules.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "common/HPMi.h"
#include "common/utils.h"
#include "common/mmo.h"
#include "common/socket.h"
#include "common/memmgr.h"
#include "common/timer.h"
#include "common/ers.h"
#include "common/nullpo.h"
#include "common/strlib.h"
#include "common/sql.h"

#include "map/battle.h"
#include "map/clif.h"
#include "map/pc.h"
#include "map/map.h"
#include "map/mob.h"
#include "map/skill.h"
#include "map/atcommand.h"
#include "map/itemdb.h"
#include "map/vending.h"
#include "map/intif.h"
#include "map/chrif.h"
#include "map/path.h"
#include "map/pet.h"
#include "map/homunculus.h"
#include "map/status.h"
#include "map/searchstore.h"

#include "plugins/HPMHooking.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 =
{
    "Extended Vending System",	// Plugin name
    SERVER_TYPE_MAP,// Which server types this plugin works with?
    "1.0",			// Plugin version
    HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

#define VEND_COLOR 0x00FFFF // Cyan

struct s_ext_vend{
	int itemid;
};
struct s_ext_vend ext_vend[MAX_INVENTORY];

struct player_data {
    int vend_loot;
	int vend_lvl;
};

struct autotrade_data {
	int vend_loot;
};

//Clif Edits
void clif_vend_message(struct map_session_data *sd, const char* msg, uint32 color);
void clif_vend_message(struct map_session_data *sd, const char* msg, uint32 color)
{
	int fd;
	unsigned short len = strlen(msg) + 1;
	
	nullpo_retv(sd);
	
	color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR
	
	fd = sd->fd;
	WFIFOHEAD(fd, len+12);
	WFIFOW(fd,0) = 0x2C1;
	WFIFOW(fd,2) = len+12;
	WFIFOL(fd,4) = 0;
	WFIFOL(fd,8) = color;
	memcpy(WFIFOP(fd,12), msg, len);
	WFIFOSET(fd, WFIFOW(fd,2));
}

//Skill_Vending
int skill_vending_ev( struct map_session_data *sd, int nameid);
int skill_vending_ev( struct map_session_data *sd, int nameid) {
	struct item_data *item;
	struct player_data *ssd;
	char output[1024];
	
	nullpo_ret(sd);


	if ( nameid <= 0) {
		clif->skill_fail(sd,MC_VENDING,USESKILL_FAIL_LEVEL,0);
		return 0;
	}
	
	if ( nameid > MAX_ITEMDB ){
		return 0;
	}
    if ( !( ssd = getFromMSD(sd,0) ) ) {
		CREATE( ssd, struct player_data, 1 );
		ssd->vend_loot = 0;
		ssd->vend_lvl = 0;
		addToMSD( sd, ssd, 0, true );
    }
	ssd->vend_loot = nameid;
	item = itemdb->exists(nameid);
	
	sprintf(output,"You have selected: %s",item->jname);
	clif_vend_message(sd,output,VEND_COLOR);

	if ( !pc_can_give_items(sd) ){
		clif->skill_fail(sd,MC_VENDING,USESKILL_FAIL_LEVEL,0);
	}
	else {
		sd->state.prevend = 1;
		clif->openvendingreq(sd,2+ssd->vend_lvl);
	}
	
	return 0;
}


//Had to duplicate
void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title) {
	if (file == NULL)
		file = "??";
	
	if (func == NULL || *func == '\0')
		func = "unknown";
	
	ShowError("--- %s --------------------------------------------\n", title);
	ShowError("%s:%d: '%s' in function `%s'\n", file, line, targetname, func);
	ShowError("--- end %s ----------------------------------------\n", title);
}

int bc_extended_vending;
int bc_show_item_vending;
int bc_ex_vending_info;
int bc_item_zeny;
int bc_item_cash;
void ev_bc(const char *key, const char *val) {
	if (strcmpi(key,"battle_configuration/extended_vending") == 0) {
		bc_extended_vending = config_switch(val);
		if (bc_extended_vending > 1 || bc_extended_vending < 0){
			ShowDebug("Wrong Value for extended_vending: %d\n",config_switch(val));
			bc_extended_vending = 0;
		}
	} else if (strcmpi(key,"battle_configuration/show_item_vending") == 0) {
		bc_show_item_vending = config_switch(val);
		if (bc_show_item_vending > 1 || bc_show_item_vending < 0){
			ShowDebug("Wrong Value for show_item_vending: %d\n",config_switch(val));
			bc_extended_vending = 0;
		}
	} else if (strcmpi(key,"battle_configuration/ex_vending_info") == 0) {
		bc_ex_vending_info = config_switch(val);
		if (bc_ex_vending_info>1 || bc_ex_vending_info<0){
			ShowDebug("Wrong Value for ex_vending_info: %d\n",config_switch(val));
			bc_extended_vending = 0;
		}
	} else if (strcmpi(key,"battle_configuration/item_zeny") == 0) {
		bc_item_zeny = config_switch(val);
		if (bc_item_zeny != 0 && bc_item_zeny > MAX_ITEMDB ){
			ShowDebug("Wrong Value for item_zeny: %d\n",config_switch(val));
			bc_extended_vending = 0;
		}
	} else if (strcmpi(key,"battle_configuration/item_cash") == 0) {
		bc_item_cash = config_switch(val);
		if (bc_item_cash != 0 && bc_item_cash > MAX_ITEMDB ){
			ShowDebug("Wrong Value for item_cash: %d\n",config_switch(val));
			bc_extended_vending = 0;
		}
	}
	return;
}

int ev_return_bc(const char *key)
{
	if (strcmpi(key,"battle_configuration/extended_vending") == 0) {
		return bc_extended_vending;
	} else if (strcmpi(key,"battle_configuration/show_item_vending") == 0) {
		return bc_show_item_vending;
	} else if (strcmpi(key,"battle_configuration/ex_vending_info") == 0) {
		return bc_ex_vending_info;
	} else if (strcmpi(key,"battle_configuration/item_zeny") == 0) {
		return bc_item_zeny;
	} else if (strcmpi(key,"battle_configuration/item_cash") == 0) {
		return bc_item_cash;
	}
	return 0;
}

//Clif Edits
void clif_parse_SelectArrow_pre(int *fd,struct map_session_data **sd)
{
	if (pc_istrading(*sd)) {
	//Make it fail to avoid shop exploits where you sell something different than you see.
		clif->skill_fail(*sd,(*sd)->ud.skill_id,USESKILL_FAIL_LEVEL,0);
		clif_menuskill_clear(*sd);
		return;
	}
	switch( (*sd)->menuskill_id ) {
		case MC_VENDING: // Extended Vending system 
			skill_vending_ev(*sd, RFIFOW(*fd,2));
			clif_menuskill_clear(*sd);
			hookStop();
			break;
	}
	return;
}

void clif_parse_OpenVending_pre(int *fd, struct map_session_data **sd_) {
	int fd2 = *fd;
	short len = (short)RFIFOW(fd2,2) - 85;
	const char* mes_orig = (const char*)RFIFOP(fd2,4);
	bool flag = (bool)RFIFOB(fd2,84);
	const uint8* data = (const uint8*)RFIFOP(fd2,85);
	char message[1024];
	struct player_data* ssd;
	struct item_data *item;
	struct map_session_data *sd = *sd_;
	
	if (!( ssd = getFromMSD(sd,0))) {
		CREATE( ssd, struct player_data, 1 );
		ssd->vend_loot = 0;
		ssd->vend_lvl = 0;
		addToMSD( sd, ssd, 0, true );
    }
	item = itemdb->exists(ssd->vend_loot);

	if ((bc_extended_vending == 1) && (bc_show_item_vending==1) && ssd->vend_loot){
		memset(message, '\0', sizeof(message));
		strcat(strcat(strcat(strcat(message,"["),item->jname),"] "),mes_orig);
	}

	
	if ( !flag )
		sd->state.prevend = sd->state.workinprogress = 0;

	if ( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM )
		return;
	if ( map->list[sd->bl.m].flag.novending ) {
		clif->message (sd->fd, msg_txt(276)); // "You can't open a shop on this map"
		return;
	}
	if ( map->getcell(sd->bl.m,&sd->bl,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING) ) {
		clif->message (sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
		return;
	}

	if ( message[0] == '\0' ) // invalid input
		return;
	if ((bc_extended_vending == 1) && (bc_show_item_vending == 1) && ssd->vend_loot){
		vending->open(sd, message, data, len/8);
	}else{
		vending->open(sd, mes_orig, data, len/8);
	}

}

int clif_vend(struct map_session_data *sd, int skill_lv) {
	struct item_data *item;
	int c, i, d = 0;
	int fd;
	nullpo_ret(sd);
	fd = sd->fd;
	WFIFOHEAD(fd, 8 * 8 + 8);
	WFIFOW(fd,0) = 0x1ad;
	if (bc_item_zeny){
		WFIFOW(fd, d * 2 + 4) = bc_item_zeny;
		d++;
	}
	if (bc_item_cash){
		WFIFOW(fd, d * 2 + 4) = bc_item_cash;
		d++;
	}
	for( c = d, i = 0; i < ARRAYLENGTH(ext_vend); i ++ ) {
		if ((item = itemdb->exists(ext_vend[i].itemid)) != NULL && 
			(int)item->nameid != bc_item_zeny && (int)item->nameid != bc_item_cash){
		WFIFOW(fd, c * 2 + 4) = (int)item->nameid;
			c++;
		}
	}
	if ( c > 0 ) {
		sd->menuskill_id = MC_VENDING;
		sd->menuskill_val = skill_lv;
		WFIFOW(fd,2) = c * 2 + 4;
		WFIFOSET(fd, WFIFOW(fd, 2));
	} else {
		clif->skill_fail(sd,MC_VENDING,USESKILL_FAIL_LEVEL,0);
		return 0;
	}

	return 1;
}

/**
 * Extended Vending system 
 **/
static bool itemdb_read_vendingdb(char* fields[], int columns, int current)
{
	struct item_data* id;
	int nameid;
 
	nameid = atoi(fields[0]);
 
	if ( ( id = itemdb->exists(nameid) ) == NULL )
	{
		ShowWarning("itemdb_read_vending: Invalid item id %d.\n", nameid);
		return false;
	}

	if ( id->type == IT_ARMOR || id->type == IT_WEAPON )
	{
		ShowWarning("itemdb_read_vending: item id %d cannot be equipment or weapon.\n", nameid);
		return false;
	}

	ext_vend[current].itemid = nameid;

	return true;
}

//ItemDB.c
void itemdb_read_post(bool minimal) {
	if (minimal) return;
	sv->readdb(map->db_path, "item_vending.txt", ',', 1, 1, ARRAYLENGTH(ext_vend), itemdb_read_vendingdb);
	return;
}
//Skill.c
int skill_castend_nodamage_id_pre(struct block_list **src_, struct block_list **bl_, uint16 *skill_id2, uint16 *skill_lv2, int64 *tick2, int *flag2){
	uint16 skill_id = *skill_id2;
	uint16 skill_lv = *skill_lv2;
	struct map_session_data *sd;
	struct player_data* ssd;
	struct block_list *src = *src_, *bl = *bl_;
	if (skill_id > 0 && !skill_lv)
		return 0;	// celest


	nullpo_retr(1, src);
	nullpo_retr(1, bl);


	if (src->m != bl->m)
		return 1;


	sd = BL_CAST(BL_PC, src);
	if (sd == NULL)
		return 1;
	if ( !( ssd = getFromMSD(sd,0) ) ) {
		CREATE( ssd, struct player_data, 1 );
		ssd->vend_loot = 0;
		ssd->vend_lvl = 0;
		addToMSD( sd, ssd, 0, true );
    }

	//dstsd deleted
	if (bl->prev == NULL)
		return 1;
	if (status->isdead(src))
		return 1;
	switch(skill_id){
		case MC_VENDING:
			if (sd){
				if ( !pc_can_give_items(sd) ) //Prevent vending of GMs with unnecessary Level to trade/drop. [Skotlex]
					clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
				else { // Extended Vending system 
					if (bc_extended_vending == 1){
						struct item_data *item;
						char output[1024];

						int c = 0, i, d = 0;
					

						ssd->vend_lvl = (int)skill_lv;
						if (bc_item_zeny)
							d++;
						if (bc_item_cash)
							d++;
						for ( c = d, i = 0; i < ARRAYLENGTH(ext_vend); i ++ ) {
							if ( (item = itemdb->exists(ext_vend[i].itemid)) != NULL && 
								item->nameid != bc_item_zeny && item->nameid != bc_item_cash)
								c++;
						}
					
						if ( c > 1 ){
							clif_vend(sd,ssd->vend_lvl);
						} else {
							sd->state.prevend = 1;
							if ( c ) {
								item = itemdb->exists(bc_item_zeny?bc_item_zeny:bc_item_cash?bc_item_cash:ext_vend[0].itemid);
								ssd->vend_loot = item->nameid;
								sprintf(output,"Current Currency: %s",itemdb_jname(ssd->vend_loot));
								clif->messagecolor_self(sd->fd,COLOR_WHITE,output);
								clif->openvendingreq(sd,2+ssd->vend_lvl);
							} else {
								ssd->vend_loot = 0;
								clif->openvendingreq(sd,2+ssd->vend_lvl);
							}
						}
						hookStop();
					} else {
						ssd->vend_loot = 0;
						sd->state.prevend = sd->state.workinprogress = 3;
						clif->openvendingreq(sd,2+skill_lv);
					}
				}
			}
			break;
	}
	return 1;
}

void vending_list_pre(struct map_session_data **sd, unsigned int *id2) {
	unsigned int id = *id2;
	struct map_session_data *vsd;
	struct player_data *ssd;
	char output[1024];
	int vend_loot = 0;
	nullpo_retv(*sd);

	if ((vsd = map->id2sd(id)) == NULL)
		return;
	if (!vsd->state.vending)
		return; // not vending
	ssd = getFromMSD(vsd, 0);
	if (ssd) {
		vend_loot = ssd->vend_loot;
	}
    
	if ( !pc_can_give_items(*sd) || !pc_can_give_items(vsd) ) { //check if both GMs are allowed to trade
		// GM is not allowed to trade
		if ((*sd)->lang_id >= atcommand->max_message_table)
			clif->message((*sd)->fd, atcommand->msg_table[0][246]);
		else
			clif->message((*sd)->fd, atcommand->msg_table[(*sd)->lang_id][246]);
		return;
	} 

	if ( bc_extended_vending == 1 && vend_loot ) {
		sprintf(output,"You've opened %s's shop. Sale is carried out: %s",vsd->status.name, itemdb_jname(vend_loot));
		clif->messagecolor_self((*sd)->fd,COLOR_WHITE,output);
	}
}

void vending_purchasereq_mod(struct map_session_data **sd_, int *aid2, unsigned int *uid2, const uint8 **data_, int *count2) {
	int aid = *aid2;
	unsigned int uid = *uid2;
	int count = *count2;
	int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING];
	double z;
	struct s_vending vend[MAX_VENDING]; // against duplicate packets
	struct map_session_data* vsd = map->id2sd(aid);
	struct player_data* ssd;
	struct map_session_data *sd = *sd_;
	int vend_loot = 0;
	const uint8 *data = *data_;

	nullpo_retv(sd);
	if (vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id)
		return; // invalid shop
	
	ssd = getFromMSD(vsd, 0);
	if (ssd)
		vend_loot = ssd->vend_loot;
	
	if (vend_loot)
		hookStop();
	if ( vsd->vender_id != uid ) { // shop has changed
		clif->buyvending(sd, 0, 0, 6);  // store information was incorrect
		return;
	}

	if (!searchstore->queryremote(sd, aid) &&
		(sd->bl.m != vsd->bl.m || !check_distance_bl(&sd->bl, &vsd->bl, AREA_SIZE)))
		return; // shop too far away

	searchstore->clearremote(sd);

	if ( count < 1 || count > MAX_VENDING || count > vsd->vend_num )
		return; // invalid amount of purchased items

	blank = pc->inventoryblank(sd); //number of free cells in the buyer's inventory
	// duplicate item in vending to check hacker with multiple packets
	memcpy(&vend, &vsd->vending, sizeof(vsd->vending)); // copy vending list

	// some checks
	z = 0.; // zeny counter
	w = 0;  // weight counter
	for( i = 0; i < count; i++ ) {
		short amount = *(const uint16*)(data + 4*i + 0);
		short idx    = *(const uint16*)(data + 4*i + 2);
		idx -= 2;

		if ( amount <= 0 )
			return;

		// check of item index in the cart
		if ( idx < 0 || idx >= MAX_CART )
			return;

		ARR_FIND( 0, vsd->vend_num, j, vsd->vending[j].index == idx );
		if ( j == vsd->vend_num )
			return; //picked non-existing item
		else
			vend_list[i] = j;

		z += ((double)vsd->vending[j].value * (double)amount);
		/**
		 * Extended Vending system 
		 **/
		if ( bc_extended_vending == 1 ){
			if ( vend_loot == bc_item_zeny || !vend_loot ) {
				if ( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY ) {
					//clif_buyvending(sd, idx, amount, 1); // you don't have enough zeny
					return;
				}
				if ( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle->bc->vending_over_max ) {
					clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
					return;
		
				}
			} else if (vend_loot == bc_item_cash){
				if ( z > sd->cashPoints || z < 0. || z > (double)MAX_ZENY ) {
					clif->messagecolor_self(sd->fd,COLOR_WHITE,"You do not have enough CashPoint");
					return;
				}
			} else {
				int k, loot_count = 0, vsd_w = 0;
				for (k = 0; k < MAX_INVENTORY; k++)
					if (sd->status.inventory[k].nameid == vend_loot)
						loot_count += sd->status.inventory[k].amount;
						
				if ( z > loot_count || z < 0) {
					clif->messagecolor_self(sd->fd,COLOR_WHITE,"You do not have enough items");
					return;
				}
				if ( pc->inventoryblank(vsd) <= 0 ) {
					clif->messagecolor_self(sd->fd,COLOR_WHITE,"Seller has not enough space in your inventory");
					return;
				}
				vsd_w += itemdb_weight(vend_loot) * (int)z;
				if ( vsd_w + vsd->weight > vsd->max_weight ) {
					clif->messagecolor_self(sd->fd,COLOR_WHITE,"Seller can not take all the item");
					return;
				} 
			}
		} else {
			if ( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY )
			{
				clif->buyvending(sd, idx, amount, 1); // you don't have enough zeny
				return;
			}
			if ( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle->bc->vending_over_max )
			{
				clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
				return;
			}

		}
		w += itemdb_weight(vsd->status.cart[idx].nameid) * amount;
		if ( w + sd->weight > sd->max_weight ) {
			clif->buyvending(sd, idx, amount, 2); // you can not buy, because overweight
			return;
		}
		
		//Check to see if cart/vend info is in sync.
		if ( vend[j].amount > vsd->status.cart[idx].amount )
			vend[j].amount = vsd->status.cart[idx].amount;
		
		// if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples).
		// here, we check cumulative amounts
		if ( vend[j].amount < amount ) {
			// send more quantity is not a hack (an other player can have buy items just before)
			clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity
			return;
		}
		
		vend[j].amount -= amount;

		switch( pc->checkadditem(sd, vsd->status.cart[idx].nameid, amount) ) {
			case ADDITEM_EXIST:
				break;	//We'd add this item to the existing one (in buyers inventory)
			case ADDITEM_NEW:
				new_++;
				if (new_ > blank)
					return; //Buyer has no space in his inventory
				break;
			case ADDITEM_OVERAMOUNT:
				return; //too many items
		}
	}
/**
 * Extended Vending system 
 **/
	if (bc_extended_vending == 1) {
		if ( vend_loot == bc_item_zeny || !vend_loot ) {
		
			//Logs (V)ending Zeny [Lupus]
		
			pc->payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
			if ( battle->bc->vending_tax )
				z -= z * (battle->bc->vending_tax/10000.);
			pc->getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);

		} else if ( vend_loot == bc_item_cash ) {
			pc->paycash(sd,(int)z,0);
			pc->getcash(vsd,(int)z,0);
		} else {
			for( i = 0; i < MAX_INVENTORY; i++)
				if ( sd->status.inventory[i].nameid == vend_loot ) {
					struct item *item;
					item = &sd->status.inventory[i];
					pc->additem(vsd,item,(int)z, LOG_TYPE_VENDING);
				}
			pc->delitem(sd,pc->search_inventory(sd, vend_loot),(int)z,0,6, LOG_TYPE_VENDING);
			
		}
	} else {
		//Logs (V)ending Zeny [Lupus]
			pc->payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
		if ( battle->bc->vending_tax )
			z -= z * (battle->bc->vending_tax/10000.);
		pc->getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
	}


	for (i = 0; i < count; i++) {
		short amount = *(const uint16*)(data + 4*i + 0);
		short idx    = *(const uint16*)(data + 4*i + 2);
		const char *item_name = itemdb_jname(vsd->status.cart[idx].nameid);
		double rev = 0.;
		idx -= 2;

		if ( bc_ex_vending_info ) // Extended Vending system 
			rev = ((double)vsd->vending[vend_list[i]].value * (double)amount);
		
		// vending item
		pc->additem(sd, &vsd->status.cart[idx], amount, LOG_TYPE_VENDING);
		vsd->vending[vend_list[i]].amount -= amount;
		pc->cart_delitem(vsd, idx, amount, 0, LOG_TYPE_VENDING);
		clif->vendingreport(vsd, idx, amount, sd->status.char_id, (int)z);

		//print buyer's name
		if ( battle->bc->buyer_name ) {
			char temp[256];
			if ( bc_ex_vending_info ) { // Extended Vending system 
				
				sprintf(temp, "%s has bought '%s' in the amount of %d. Revenue: %d %s", sd->status.name, item_name, amount, (int)(rev -= rev * (battle->bc->vending_tax/10000.)), vend_loot?itemdb_jname(vend_loot):"Zeny");
			} else {
				if (sd->lang_id >= atcommand->max_message_table)
					sprintf(temp, atcommand->msg_table[0][265], sd->status.name);
				else
					sprintf(temp, atcommand->msg_table[sd->lang_id][265], sd->status.name);
			}
			clif_disp_onlyself(vsd, temp);
		}
	}

	if ( bc_ex_vending_info ) { // Extended Vending system 
		char temp[256];
		sprintf(temp, "Full revenue from %s is %d %s", sd->status.name, (int)z, vend_loot?itemdb_jname(vend_loot):"Zeny");
		clif_disp_onlyself(vsd, temp);
	}

	// compact the vending list
	for( i = 0, cursor = 0; i < vsd->vend_num; i++ ) {
		if ( vsd->vending[i].amount == 0 )
			continue;
		
		if ( cursor != i ) { // speedup
			vsd->vending[cursor].index = vsd->vending[i].index;
			vsd->vending[cursor].amount = vsd->vending[i].amount;
			vsd->vending[cursor].value = vsd->vending[i].value;
		}

		cursor++;
	}
	vsd->vend_num = cursor;

	//Always save BOTH: buyer and customer
	if ( map->save_settings&2 ) {
		chrif->save(sd,0);
		chrif->save(vsd,0);
	}

	//check for @AUTOTRADE users [durf]
	if ( vsd->state.autotrade ) {
		//see if there is anything left in the shop
		ARR_FIND( 0, vsd->vend_num, i, vsd->vending[i].amount > 0 );
		if ( i == vsd->vend_num ) {
			//Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex]
			vending->close(vsd);
			map->quit(vsd); //They have no reason to stay around anymore, do they?
		}
	}
	if (bc_extended_vending){
		hookStop();
	}
}

void pc_autotrade_prepare_pre(struct map_session_data **sd) {
	struct player_data *ssd;
	ssd = getFromMSD(*sd, 0);
	if (ssd){
		if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `evs_info` (`vend_loot`,`vend_lvl`,`char_id`) VALUES ('%d','%d','%d')ON DUPLICATE KEY UPDATE `vend_lvl`='%d', `vend_loot`='%d'",
										ssd->vend_loot,
										ssd->vend_lvl,
										(*sd)->status.char_id,
										ssd->vend_lvl,
										ssd->vend_loot
										))
			Sql_ShowDebug(map->mysql_handle);
	}
}

void pc_autotrade_populate_pre(struct map_session_data **sd) {
	struct player_data *ssd;
	char *mdata = NULL;
	
	if (!( ssd = getFromMSD(*sd,0))) {
		CREATE(ssd, struct player_data, 1);
		ssd->vend_loot = 0;
		ssd->vend_lvl = 0;
		addToMSD(*sd, ssd, 0, true);
	}
	if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `vend_loot`,`vend_lvl` FROM `evs_info` WHERE `char_id` = '%d'", (*sd)->status.char_id))
		Sql_ShowDebug(map->mysql_handle);

	while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
		SQL->GetData(map->mysql_handle, 0, &mdata, NULL); ssd->vend_loot = atoi(mdata);
		SQL->GetData(map->mysql_handle, 1, &mdata, NULL); ssd->vend_lvl = atoi(mdata);
		break;
	}
	return;
}

HPExport void plugin_init (void){
	
	addHookPre(clif, pSelectArrow, clif_parse_SelectArrow_pre);
	addHookPre(clif, pOpenVending, clif_parse_OpenVending_pre);
	addHookPre(skill, castend_nodamage_id, skill_castend_nodamage_id_pre);
	addHookPre(vending, list, vending_list_pre);
	addHookPre(vending, purchase, vending_purchasereq_mod);
	addHookPre(pc, autotrade_prepare, pc_autotrade_prepare_pre);
	addHookPre(pc, autotrade_populate, pc_autotrade_populate_pre);
	addHookPost(itemdb, read, itemdb_read_post);
	if (SQL_ERROR == SQL->Query(map->mysql_handle, "CREATE TABLE IF NOT EXISTS `evs_info` (`char_id` int(10) NOT NULL,`vend_loot` int(6) NOT NULL,`vend_lvl` int(5) NOT NULL, PRIMARY KEY(`char_id`))")){
		Sql_ShowDebug(map->mysql_handle);
	}
}

HPExport void server_preinit (void) {
	addBattleConf("battle_configuration/extended_vending",ev_bc, ev_return_bc, false);
	addBattleConf("battle_configuration/show_item_vending",ev_bc, ev_return_bc, false);
	addBattleConf("battle_configuration/ex_vending_info",ev_bc, ev_return_bc, false);
	addBattleConf("battle_configuration/item_zeny",ev_bc, ev_return_bc, false);
	addBattleConf("battle_configuration/item_cash",ev_bc, ev_return_bc, false);
}

HPExport void server_online (void) {
	ShowInfo ("'%s' Plugin by Dastgir/Hercules. Version '%s'\n",pinfo.name,pinfo.version);
}
 

 

 

 

storageadditem.c

 

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */
#include "common/HPMi.h"
#include "map/intif.h"
#include "map/pc.h"
#include "map/storage.h"
#include "plugins/HPMHooking.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 = {
	"storageadditem", // Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"0.1",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};


/*==========================================
 * storageadditem <item id>,<amount>{,<account id>}
 * Adds items from the target/attached player.
 *==========================================*/
BUILDIN(storageadditem) {
	TBL_PC *sd;
	struct item it;

	if (script_hasdata(st,4)) {
		int account_id = script_getnum(st,4);
		sd = map->id2sd(account_id); // <account id>
		if (sd == NULL) {
			ShowError("script:storageadditem: player not found (AID=%d).\n", account_id);
			st->state = END;
			return false;
		}
	} else {
		sd = script->rid2sd(st);// attached player
		if (sd == NULL)
			return true;
	}

	memset(&it, 0, sizeof(it));
	if (script_isstringtype(st, 2)) {
		const char* item_name = script_getstr(st, 2);
		struct item_data* id = itemdb->search_name(item_name);
		if (id == NULL) {
			ShowError("script:storageadditem: unknown item \"%s\".\n", item_name);
			st->state = END;
			return false;
		}
		it.nameid = id->nameid;// "<item name>"
	} else {
		it.nameid = script_getnum(st, 2);// <item id>
		if (!itemdb->exists(it.nameid)) {
			ShowError("script:storageadditem: unknown item \"%d\".\n", it.nameid);
			st->state = END;
			return false;
		}
	}

	it.amount=script_getnum(st,3);

	if( it.amount <= 0 ) {
		return true;// nothing to do
	}
	if( sd->status.storage.storage_amount > MAX_STORAGE ) {
		return 0; // storage full
	}
	it.identify=1;
	storage->open(sd);
	storage->additem(sd,&it,it.amount);
	storage->close(sd);
}

/* Server Startup */
HPExport void plugin_init (void) {
	addScriptCommand( "storageadditem", "vi?", storageadditem);
} 

 

 

 

@edit 

I forgot to say that I added ALL the plugins

#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */

Is correct?

Edited by Like it~*

Share this post


Link to post
Share on other sites
  • 0

remove this 

#define safestrncpy(dst,src,n)       (strlib->safestrncpy((dst),(src),(n)))

from 

partyscript.c

 

 

 

remove this 

#define safestrncpy(dst,src,n)       (strlib->safestrncpy((dst),(src),(n)))

from 

partyscript.c

 

Thanks you very much.

Amazingly, now there are only two plugins

 

Severity	Code	Description	Project	File	Line	Suppression State
Warning	C4003	not enough actual parameters for macro 'addHookPre'	noitem	Hercules\src\plugins\noitem.c	191	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	191	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	191	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	191	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	192	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	193	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	193	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	194	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	194	
Warning	C4003	not enough actual parameters for macro 'addHookPost'	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2065	'HPMHOOK_post_': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2143	syntax error: missing ')' before 'string'	noitem	Hercules\src\plugins\noitem.c	195	
Error	C2059	syntax error: ')'	noitem	Hercules\src\plugins\noitem.c	195	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2143	syntax error: missing ')' before 'string'	maintenance	Hercules\src\plugins\maintenance.c	551	
Error	C2059	syntax error: ')'	maintenance	Hercules\src\plugins\maintenance.c	551	
Warning	C4003	not enough actual parameters for macro 'addHookPre'	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2065	'HPMHOOK_pre_': undeclared identifier	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2143	syntax error: missing ')' before 'string'	maintenance	Hercules\src\plugins\maintenance.c	552	
Error	C2059	syntax error: ')'	maintenance	Hercules\src\plugins\maintenance.c	552

Share this post


Link to post
Share on other sites
  • 0

For noitem.c, look for this line:

HPExport void plugin_init (void) {
	addHookPre( "map->flags_init", map_flags_init_pre );
	addHookPre( "npc->parse_unknown_mapflag", npc_parse_unknown_mapflag_pre );
	addHookPost( "pc->isequip", pc_isequip_post );
	addHookPost( "pc->isUseitem", pc_isUseitem_post );
	addHookPost( "pc->checkitem", pc_checkitem_post );
}

and replace it with:

HPExport void plugin_init (void) {
	addHookPre( map, flags_init, map_flags_init_pre );
	addHookPre( npc, parse_unknown_mapflag, npc_parse_unknown_mapflag_pre );
	addHookPost( pc, isequip, pc_isequip_post );
	addHookPost( pc, isUseitem, pc_isUseitem_post );
	addHookPost( pc, checkitem, pc_checkitem_post );
}

 

 

For maintenance.c, look for this line:

	addHookPre( "pc->authok", pc_authok_pre );
	addHookPre( "clif->pLoadEndAck", clif_parse_LoadEndAck_pre );

replace it with:

	addHookPre( pc, authok, pc_authok_pre );
	addHookPre( clif, pLoadEndAck, clif_parse_LoadEndAck_pre );

;)

Share this post


Link to post
Share on other sites
  • 0

For noitem.c, look for this line:

HPExport void plugin_init (void) {
	addHookPre( "map->flags_init", map_flags_init_pre );
	addHookPre( "npc->parse_unknown_mapflag", npc_parse_unknown_mapflag_pre );
	addHookPost( "pc->isequip", pc_isequip_post );
	addHookPost( "pc->isUseitem", pc_isUseitem_post );
	addHookPost( "pc->checkitem", pc_checkitem_post );
}

and replace it with:

HPExport void plugin_init (void) {
	addHookPre( map, flags_init, map_flags_init_pre );
	addHookPre( npc, parse_unknown_mapflag, npc_parse_unknown_mapflag_pre );
	addHookPost( pc, isequip, pc_isequip_post );
	addHookPost( pc, isUseitem, pc_isUseitem_post );
	addHookPost( pc, checkitem, pc_checkitem_post );
}

 

 

For maintenance.c, look for this line:

	addHookPre( "pc->authok", pc_authok_pre );
	addHookPre( "clif->pLoadEndAck", clif_parse_LoadEndAck_pre );

replace it with:

	addHookPre( pc, authok, pc_authok_pre );
	addHookPre( clif, pLoadEndAck, clif_parse_LoadEndAck_pre );

;)

 

Thank you very much.

But, there is still an error.

 

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2065	'HPMHOOK_pre_npc_parse_unknown_mapflag': undeclared identifier	noitem	Hercules\src\plugins\noitem.c	192	
Error	C2143	syntax error: missing ')' before 'constant'	noitem	Hercules\src\plugins\noitem.c	192	
Warning	C4028	formal parameter 3 different from declaration	noitem	Hercules\src\plugins\noitem.c	193
Warning	C4028	formal parameter 3 different from declaration	noitem	Hercules\src\plugins\noitem.c	194

Share this post


Link to post
Share on other sites
  • 0

Sorry for the necro, but this plugins are too useful and now they are out of date with the new changes of Plugin System ;(

Can help us? 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.