Jump to content
  • 0
brunosc

Plugin @partybuff

Question

im using AnnieRuru plugin . version 0.4 Link -> https://upaste.me/75d049918e2088402

//===== Hercules Plugin ======================================
//= @showbuff
//===== By: ==================================================
//= AnnieRuru
//===== Current Version: =====================================
//= 0.4
//===== Compatible With: ===================================== 
//= Hercules 2018-06-05
//===== Description: =========================================
//= @showbuff on the party screen Alt + Z
//===== Topic ================================================
//= http://herc.ws/board/topic/11349-partybuff-spb/
//===== Additional Comments: =================================  
//=	testing ...
//=	join party -> OK -> clif_party_member_info_overload
//=	somebody leave party -> OK -> clif_party_withdraw_overload
//=	disband party -> not yet ... I guess no need test this one
//=	party member log in -> OK
//=	party member log out -> OK
//=	expel party -> BUG -> no choice but have to prevent them from doing so
//=	you leave party -> party_leave_pre
//============================================================

#include "common/hercules.h"
#include "map/pc.h"
#include "map/clif.h"
#include "map/party.h"
#include "common/nullpo.h"
#include "common/socket.h"
#include "common/memmgr.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"showbuff",
	SERVER_TYPE_MAP,
	"0.4",
	HPM_VERSION,
};

struct player_data {
	int buff;
	bool showbuff;
};

int status_change_start_post( int retVal, struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) {
	if ( bl->type == BL_PC && retVal > 0 ) {
		struct map_session_data *sd = BL_CAST( BL_PC, bl );
		struct party_data *p;
		if ( p = party->search(sd->status.party_id )) {
			struct player_data *ssd = getFromMSD( sd, 0 );
			int before_buff = ssd->buff;
			if ( type == SC_BLESSING )
				ssd->buff |= 0x1;
			if ( type == SC_INC_AGI )
				ssd->buff |= 0x2;
			if ( type == SC_PROTECTWEAPON || type == SC_PROTECTSHIELD || type == SC_PROTECTARMOR || type == SC_PROTECTHELM )
				if ( sd->sc.data[SC_PROTECTWEAPON] && sd->sc.data[SC_PROTECTSHIELD] && sd->sc.data[SC_PROTECTARMOR] && sd->sc.data[SC_PROTECTHELM] )
					ssd->buff |= 0x4;
			if ( type == SC_SOULLINK )
				ssd->buff |= 0x8;
			if ( type == SC_DEVOTION )
				ssd->buff |= 0x10;
			if ( before_buff != ssd->buff ) // only send the packet if update the status is newly apply, no need to resend if just renew the status
				clif->party_info( p, NULL );
		}
	}
	return retVal;
}

int status_change_end_post( int retVal, struct block_list *bl, enum sc_type type, int tid, const char *file, int line ) {
	if ( bl->type == BL_PC && retVal > 0 ) {
		struct map_session_data *sd = BL_CAST( BL_PC, bl );
		struct party_data *p;
		if ( sd->state.active == 1 ) { // fix map-server crash when player logout
			if (( p = party->search(sd->status.party_id ))) {
				struct player_data *ssd = getFromMSD( sd, 0 );
				int before_buff = ssd->buff;
				if ( type == SC_BLESSING )
					ssd->buff &= ~0x1;
				if ( type == SC_INC_AGI )
					ssd->buff &= ~0x2;
				if ( type == SC_PROTECTWEAPON || type == SC_PROTECTSHIELD || type == SC_PROTECTARMOR || type == SC_PROTECTHELM )
					if ( sd->sc.data[SC_PROTECTWEAPON] && sd->sc.data[SC_PROTECTSHIELD] && sd->sc.data[SC_PROTECTARMOR] && sd->sc.data[SC_PROTECTHELM] )
						ssd->buff &= ~0x4;
				if ( type == SC_SOULLINK )
					ssd->buff &= ~0x8;
				if ( type == SC_DEVOTION )
					ssd->buff &= ~0x10;
				if ( before_buff != ssd->buff ) // only send the packet if update the status is newly apply, no need to resend if just renew the status
					clif->party_info( p, NULL );
			}
		}
	}
	return retVal;
}

char *showing_buff( struct map_session_data *sd ) {
	struct player_data *ssd = getFromMSD( sd, 0 );
	char *temp = "\0";
	safesnprintf( temp, NAME_LENGTH, "[%s%s%s%s%s]%s",
		( ssd->buff & 0x1 )? "B" : "_",
		( ssd->buff & 0x2 )? "A" : "_",
		( ssd->buff & 0x4 )? "F" : "_",
		( ssd->buff & 0x8 )? "S" : "_",
		( ssd->buff & 0x10 )? "+" : "_",
		sd->status.name );
	return temp;
}

void clif_party_info_overload( struct party_data *p, struct map_session_data *sd ) {
	struct PACKET_ZC_GROUP_LIST *packet;
	int i, c;
	unsigned char buf[sizeof(*packet) + sizeof(struct PACKET_ZC_GROUP_LIST_SUB) * MAX_PARTY];
	nullpo_retv(p);

	memset( buf, 0, sizeof(buf) );
	packet = (struct PACKET_ZC_GROUP_LIST *)buf;
	packet->packetType = partyinfo;
	memcpy( packet->partyName, p->party.name, NAME_LENGTH );
	for ( i = 0, c = 0; i < MAX_PARTY; ++i ) {
		struct party_member *m = &p->party.member[i];
		if ( !m->account_id )
			continue;
		packet->members[c].AID = m->account_id;
#if PACKETVER >= 20171207
		packet->members[c].GID = m->char_id;
#endif
		memcpy( packet->members[c].playerName, m->name, NAME_LENGTH );
		mapindex->getmapname_ext(mapindex_id2name(m->map), packet->members[c].mapName);
		packet->members[c].leader = (m->leader) ? 0 : 1;
		packet->members[c].offline = (m->online) ? 0 : 1;
#if PACKETVER >= 20170502
		packet->members[c].class = m->class;
		packet->members[c].baseLevel = m->lv;
#endif
		++c;
	}
	packet->packetLen = sizeof(*packet) + c * sizeof( struct PACKET_ZC_GROUP_LIST_SUB );
	if ( sd ) {
		struct player_data *ssd = getFromMSD( sd, 0 );
		if ( ssd && ssd->showbuff ) {
			for ( i = 0, c = 0; i < MAX_PARTY; ++i ) {
				struct party_member *m = &p->party.member[i];
				if ( !m->account_id )
					continue;
				if ( m->online && p->data[i].sd != NULL )
					memcpy( packet->members[c].playerName, showing_buff( p->data[i].sd ), NAME_LENGTH );
				++c;
			}
		}
		clif->send( buf, packet->packetLen, &sd->bl, SELF );
	}
	else {
		int j;
		for ( j = 0; j < MAX_PARTY; ++j ) {
			struct party_member *m1 = &p->party.member[j];
			if ( !m1 || !m1->account_id )
				continue;
			else {
				struct map_session_data *tsd = map->id2sd( m1->account_id );
				struct player_data *ssd = NULL;
				if ( !tsd )
					continue;
				ssd = getFromMSD( tsd, 0 );
				if ( ssd && ssd->showbuff ) {
					for ( i = 0, c = 0; i < MAX_PARTY; ++i ) {
						struct party_member *m = &p->party.member[i];
						if ( !m->account_id )
							continue;
						if ( m->online && p->data[i].sd != NULL ) {
							memcpy( packet->members[c].playerName, showing_buff( p->data[i].sd ), NAME_LENGTH );
						}
						++c;
					}
				}
				else {
					for ( i = 0, c = 0; i < MAX_PARTY; ++i ) {
						struct party_member *m = &p->party.member[i];
						if ( !m->account_id )
							continue;
						memcpy( packet->members[c].playerName, m->name, NAME_LENGTH );
						++c;
					}
				}
				clif->send( buf, packet->packetLen, map->id2bl( m1->account_id ), SELF );
			}
		}
	}
}

bool pc_authok_pre( struct map_session_data **sd, int *login_id2, time_t *expiration_time, int *group_id, const struct mmo_charstatus **st, bool *changing_mapservers ) {
	struct player_data *ssd;
	CREATE( ssd, struct player_data, true );
	ssd->buff = 0;
	ssd->showbuff = 0;
	addToMSD( *sd, ssd, 0, true );
	return 0;
}

void clif_party_member_info_overload( struct party_data *p, struct map_session_data *sd ) {
	return;
}

void clif_party_withdraw_overload( struct party_data *p, struct map_session_data *sd, int account_id, const char *name, int flag ) {
	unsigned char buf[64];
	nullpo_retv(p);
	nullpo_retv(name);
	if ( !sd && !(flag & 0xf0) ) {
		int i;
		ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd != NULL );
		if ( i != MAX_PARTY )
			sd = p->data[i].sd;
	}
	if ( !sd )
		return;
	WBUFW(buf,0) = 0x105;
	WBUFL(buf,2) = account_id;
	memcpy( WBUFP(buf,6), name, NAME_LENGTH );
	WBUFB(buf,30) = flag & 0x0f;
	if ( !(flag & 0xf0) ) {
		for ( int i = 0; i < MAX_PARTY; ++i ) {
			struct party_member *m = &p->party.member[i];
			if ( !m || !m->account_id )
				continue;
			else {
				struct map_session_data *tsd = map->id2sd( m->account_id );
				struct player_data *ssd = NULL;
				if ( !tsd )
					continue;
				ssd = getFromMSD( tsd, 0 );
				if ( ssd && ssd->showbuff )
					memcpy( WBUFP(buf,6), showing_buff( sd ), NAME_LENGTH );
				else
					memcpy( WBUFP(buf,6), name, NAME_LENGTH );
				clif->send( buf, 31, map->id2bl( m->account_id ), SELF );
			}
		}
	}
	else
		clif->send( buf, 31, &sd->bl, SELF );
}

int party_removemember_pre( struct map_session_data **sd, int *account_id, const char **name ) {
	struct player_data *ssd = getFromMSD( *sd, 0 );
	if ( ssd->showbuff ) {		
		clif->message( (*sd)->fd, "You cannot expel a party member while @showbuff is turn ON." );
		hookStop();
	}
	return 0;
}

int party_leave_pre( struct map_session_data **sd ) {
	struct party_data *p;
	int i;
	nullpo_ret(*sd);
	p = party->search( (*sd)->status.party_id );
	if ( p == NULL )
		return 0;
	ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == (*sd)->status.account_id && p->party.member[i].char_id == (*sd)->status.char_id );
	if ( i == MAX_PARTY )
		return 0;
	else {
		struct player_data *ssd = getFromMSD( *sd, 0 );
		if ( ssd->showbuff )
			ssd->showbuff = 0;
	}
	return 0;
}

ACMD(showbuff) {
	struct player_data *ssd = getFromMSD( sd, 0 );
	struct party_data *p = party->search( sd->status.party_id );
	if ( !p ) {
		clif->message( sd->fd, "You don't have a Party." );
		return false;
	}
	else if ( ssd->showbuff ) {
		ssd->showbuff = 0;
		clif->message( sd->fd, "@showbuff is now turn OFF." );
	}
	else {
		ssd->showbuff = 1;
		clif->message( sd->fd, "@showbuff is now turn ON." );
	}
	clif->party_info( p, sd );
	return true;
}

HPExport void plugin_init (void) {
	addHookPost( status, change_start, status_change_start_post );
	addHookPost( status, change_end_, status_change_end_post );
	clif->party_info = &clif_party_info_overload;
	addHookPre( pc, authok, pc_authok_pre );
	clif->party_member_info = &clif_party_member_info_overload;
	clif->party_withdraw = &clif_party_withdraw_overload;
	addHookPre( party, removemember, party_removemember_pre );
	addHookPre( party, leave, party_leave_pre );
	addAtcommand( "showbuff", showbuff );
}

and i fix some problem reading topic. in line 70 change it

int status_change_end_post(int retVal, struct block_list* bl, enum sc_type type, int tid, const char* file, int line) {

for

int status_change_end_post(int retVal, struct block_list* bl, enum sc_type type, int tid)//, const char* file, int line) {
{

and in line 50

change it

  if ( p = party->search(sd->status.party_id )) {

for it

struct party_data* p = party->search(sd->status.party_id);
		if (p) {

i dont have some errors  when compile but got game crash.

 

image.thumb.png.e1c1a00e262b1d8b8f81cf7345212c7c.png

 

today im searching about it i found this :

//===== Hercules Plugin ======================================
//= Show Party Buffs
//===== By: ==================================================
//= Samuel [Hercules]
//===== Current Version: =====================================
//= 1.0
//===== Compatible With: ===================================== 
//= Hercules/RagEmu
//===== Description: =========================================
//= With this plugin, it will show certain buffs that are
//= present with you and your party members in the party
//= window.
//= B - Blessing
//= A - Agility Up
//= F - Full Chemical Protection
//= S - Soul Link
//= + - Devotion
//===== Credits: =============================================
//= AnnieRuru - originally made the plugin
//= Functor - bug fix
//============================================================

#include "common/hercules.h"
#include "common/nullpo.h"
#include "common/socket.h"
#include "common/memmgr.h"

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

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

struct player_data {
    int buff;
};

int status_change_start_post( int retVal___, struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
{
    if ( bl->type == BL_PC && retVal___ > 0 ) {
        TBL_PC *sd = BL_CAST(BL_PC, bl);
        struct party_data *p;
        if (( p = party->search(sd->status.party_id ))) {
			struct player_data *ssd = getFromMSD( sd, 0 );
			int before_buff = ssd->buff;
			if ( type == SC_BLESSING )
				ssd->buff |= 0x1;
			if ( type == SC_INC_AGI )
				ssd->buff |= 0x2;
			if ( type == SC_PROTECTWEAPON || type == SC_PROTECTSHIELD || type == SC_PROTECTARMOR || type == SC_PROTECTHELM )
				if ( sd->sc.data[SC_PROTECTWEAPON] && sd->sc.data[SC_PROTECTSHIELD] && sd->sc.data[SC_PROTECTARMOR] && sd->sc.data[SC_PROTECTHELM] )
					ssd->buff |= 0x4;
			if ( type == SC_SOULLINK )
				ssd->buff |= 0x8;
			if ( type == SC_DEVOTION )
				ssd->buff |= 0x10;
			if ( before_buff != ssd->buff ) // only send the packet if update the status is newly apply, no need to resend if just renew the status
				clif->party_info( p, NULL );
		}
	}
    return retVal___;
}

int status_change_end_post( int retVal___, struct block_list *bl, enum sc_type type, int tid, const char *file, int line )
{
    if ( bl->type == BL_PC && retVal___ > 0 ) {
        TBL_PC *sd = BL_CAST(BL_PC, bl);
        struct party_data *p;
        if ( sd->state.active == 1 ) { // fix map-server crash when player logout
        if (( p = party->search(sd->status.party_id ))) {
           struct player_data *ssd = getFromMSD( sd, 0 );
			int before_buff = ssd->buff;
			if ( type == SC_BLESSING )
				ssd->buff &= ~0x1;
			if ( type == SC_INC_AGI )
				ssd->buff &= ~0x2;
			if ( type == SC_PROTECTWEAPON || type == SC_PROTECTSHIELD || type == SC_PROTECTARMOR || type == SC_PROTECTHELM )
				if ( sd->sc.data[SC_PROTECTWEAPON] && sd->sc.data[SC_PROTECTSHIELD] && sd->sc.data[SC_PROTECTARMOR] && sd->sc.data[SC_PROTECTHELM] )
					ssd->buff &= ~0x4;
			if ( type == SC_SOULLINK )
				ssd->buff &= ~0x8;
			if ( type == SC_DEVOTION )
				ssd->buff &= ~0x10;
			if ( before_buff != ssd->buff ) // only send the packet if update the status is newly apply, no need to resend if just renew the status
				clif->party_info( p, NULL );
			}
		}
	}
    return retVal___;
}

void clif_party_info_overload( struct party_data* p, struct map_session_data *sd ) {
    unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY];
    struct map_session_data* party_sd = NULL;
    int i, c;
    nullpo_retv(p);
    WBUFW(buf,0) = 0xfb;
    memcpy( WBUFP(buf,4), p->party.name, NAME_LENGTH );
    for ( i = 0, c = 0; i < MAX_PARTY; i++ ) {
        struct party_member* m = &p->party.member[i];
        if(!m->account_id) continue;
        if(party_sd == NULL) party_sd = p->data[i].sd;
        WBUFL(buf,28+c*46) = m->account_id;
        if ( m->online && p->data[i].sd != NULL ) {
            struct player_data *ssd = getFromMSD( p->data[i].sd, 0 );
            char temp[NAME_LENGTH];
            safesnprintf( temp, NAME_LENGTH, "[%s%s%s%s%s]%s",
                                                            ( ssd->buff & 0x1 )? "B" : "_",
                                                            ( ssd->buff & 0x2 )? "A" : "_",
                                                            ( ssd->buff & 0x4 )? "F" : "_",
                                                            ( ssd->buff & 0x8 )? "S" : "_",
                                                            ( ssd->buff & 0x10 )? "+" : "_",
                                                            m->name );
            memcpy(WBUFP(buf,28+c*46+4), temp, NAME_LENGTH);
        } else
            memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH);
        mapindex->getmapname_ext(mapindex_id2name(m->map), (char*)WBUFP(buf,28+c*46+28));
        WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1;
        WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1;
        c++;
    }
    WBUFW(buf,2) = 28+c*46;
    if (sd)
        clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
    else if (party_sd)
        clif->send(buf, WBUFW(buf,2), &party_sd->bl, PARTY);
    return;
}

bool pc_authok_pre( struct map_session_data **sd, int *login_id2, time_t *expiration_time, int *group_id, const struct mmo_charstatus **st, bool *changing_mapservers ) {
    struct player_data *ssd;
    CREATE( ssd, struct player_data, true );
    ssd->buff = 0;
    addToMSD( *sd, ssd, 0, true );
    return true;
}

int map_quit_post( int retVal___, struct map_session_data *sd ) {
    //struct player_data *ssd = getFromMSD( sd, 0 );
    removeFromMSD( sd, 0 );
    return retVal___;
}

void clif_party_member_info_overload(struct party_data* p, struct map_session_data* sd)
{
	return;
}

HPExport void plugin_init (void) {
	clif->party_member_info = &clif_party_member_info_overload;
	addHookPre( pc, authok, pc_authok_pre );
    addHookPost( map, quit, map_quit_post );
	clif->party_info = &clif_party_info_overload;
    addHookPost( status, change_start, status_change_start_post );
    addHookPost( status, change_end_, status_change_end_post );
}

this work show BA..... in mae player on party window.

but sometimes got gravit error and dont have @showbuff and simbol of my job is wrong.

 

Edited by brunosc

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0
On 2/24/2021 at 8:28 PM, Caspian said:

Here is working fine.  Do you use the last revision of hercules?

yes the last version anda client 2019.

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, brunosc said:

yes the last version anda client 2019.

I think that's why it isn't working. The dev's team keep changing the code all the time and then the plugins become outdated.

I use an old revison of hercules, so that's why I am able to use all the plugins I want.

Share this post


Link to post
Share on other sites
  • 0
On 3/1/2021 at 9:12 PM, Caspian said:

I think that's why it isn't working. The dev's team keep changing the code all the time and then the plugins become outdated.

I use an old revison of hercules, so that's why I am able to use all the plugins I want.

im try to update it but not ok.

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.