Jump to content
  • 0
cumbe11

@partybuff / @spb

Question

Here is this change?
 
 
 
@partybuff (@spb) can display party member's special buffs in party list (Alt+Z)
Buffs are:
Quote

B - Blessing
A - Agility Up
F - Full Chemical Protection
S - Soul Link
+ - Devotion

Look like
[BAFS+]Player name

Share this post


Link to post
Share on other sites

30 answers to this question

Recommended Posts

  • 0

even if this is possible, there is a client restriction which disallow to display player name longer than 23 characters ...
and the color has to be client reverse engineer ...
 
means, no, this also has to do client side modification
 
but if not display in the Alt+Z, but with a message command
then this can even done with scripting alone, with getstatus script command

 

 

-    script    jsfkjsdf    FAKE_NPC,{OnInit:    bindatcmd "psc", strnpcinfo(0)+"::Onaaa";    end;Onaaa:    .@pid = getcharid(1);    if ( !.@pid ) {        dispbottom "you don't have a party to use this command";        end;    }    getpartymember .@pid, 1;    getpartymember .@pid, 2;    .@origin = getcharid(3);    for ( .@i = 0; .@i < $@partymembercount; ++.@i ) {        if ( isloggedin( $@partymemberaid[.@i] , $@partymembercid[.@i] ) ) {            attachrid $@partymemberaid[.@i];            .@buff$ = "";            if ( getstatus(SC_BLESSING) ) .@buff$ += "B";            if ( getstatus(SC_INC_AGI) ) .@buff$ += "A";            if ( getstatus(SC_PROTECTWEAPON) && getstatus(SC_PROTECTSHIELD) && getstatus(SC_PROTECTARMOR) && getstatus(SC_PROTECTHELM) ) .@buff$ += "F";            if ( getstatus(SC_SOULLINK) ) .@buff$ += "S";            if ( getstatus(SC_DEVOTION) ) .@buff$ += "+";            .@display$[.@c++] = "["+ .@buff$ +"] "+ strcharinfo(0);        }    }    attachrid .@origin;    for ( .@i = 0; .@i < .@c; ++.@i )        dispbottom .@display$[.@i];    end;}

post-4102-0-87723800-1449233909_thumb.jpg

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

@@Vlync

now I'm very very interested, show meh ! :D

 

 

EDIT: even a video is fine, I can guess how they did it

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

@@Vlync

now I'm very very interested, show meh ! :D

 

 

EDIT: even a video is fine, I can guess how they did it

Name can be modified via clif.c, hooking appropriate functions..

(And trimming names if they reach > 23 char, thats what they do)

Share this post


Link to post
Share on other sites
  • 0

ok, let's analyze the packet

 

clif_party_member_info

/// Adds new member to a party.

/// 0104 <account id>.L <role>.L <x>.W <y>.W <state>.B <party name>.24B <char name>.24B <map name>.16B (ZC_ADD_MEMBER_TO_GROUP)

23 characters for name, 23 characters for map name

hmm ... if we replace the map name with buff ... hehe ... sounds fun

 

clif_party_info

/// Sends party information (ZC_GROUP_LIST).

/// 00fb <packet len>.W <party name>.24B { <account id>.L <nick>.24B <map name>.16B <role>.B <state>.B }*

/// role:

/// 0 = leader

/// 1 = normal

/// state:

/// 0 = connected

/// 1 = disconnected

 

clif_party_xy

/// Updates the position of a party member on the minimap (ZC_NOTIFY_POSITION_TO_GROUPM).

/// 0107 <account id>.L <x>.W <y>.W

 

clif_party_hp

/// Updates HP bar of a party member.

/// 0106 <account id>.L <hp>.W <max hp>.W (ZC_NOTIFY_HP_TO_GROUPM)

 

 

so ... there is no packet to update the party member's status in Alt+Z bar

 

 

clif_parse_LeaveParty

/// Request to leave party (CZ_REQ_LEAVE_GROUP).

 

clif_parse_RemovePartyMember

/// Request to expel a party member (CZ_REQ_EXPEL_GROUP_MEMBER).

 

 

the one trick that I can think off, is sending a packet to leave player's party and invite back with a fake name

but I wonder doing this will have message on the chat log ?

... hmm ... ask a client translation team, maybe they know where is the english file at

Share this post


Link to post
Share on other sites
  • 0

void clif_party_info -> memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH); 

Just modify m->name before using memcpy.. and that will show change in party window. :)

 

Edit: In chat log, they will have normal name, just party window will be edited.

Share this post


Link to post
Share on other sites
  • 0

Hmm. But that will also need additional calls to this if status will get changed. Because iirc by default party info changes when player either logs off/on or changes map. Also, may change character name limit to 17 to avoid name cutting (most nicknames are under 12~15 characters anyway).

Edited by Garr

Share this post


Link to post
Share on other sites
  • 0

#include "common/hercules.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include "map/pc.h"#include "map/clif.h"#include "map/party.h"#include "common/nullpo.h"#include "common/socket.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 = {	"test123",		// 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 ) {		ShowDebug( "PC" );		if ( *type == SC_BLESSING )			ShowDebug( "Yes" );	}	return retVal;}	void clif_party_info_pre(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;	char aaa[NAME_LENGTH];	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;		safesnprintf( aaa, NAME_LENGTH, "[ASDF]%s",  m->name );		memcpy(WBUFP(buf,28+c*46+4), aaa, 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);	hookStop();	return;}	HPExport void plugin_init (void) {	addHookPre( "clif->party_info", clif_party_info_pre );	addHookPost( "status->change_start", status_change_start_post );}
@@cumbe11

is it normal to show [ASDF]<name> in the chat log like this ?

post-4102-0-79798400-1449258192_thumb.jpg

 

 

EDIT:

@@Garr

I thought about that,

but Dastgir said just have to put clif_party_info function in status_change_start and status_change_end,

and it will update itself

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

yup, currently look like this now

#include "common/hercules.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.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 "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 = {
    "test123",    // 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, 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 0;
}
int map_quit_post( int retVal, struct map_session_data *sd ) {
    struct player_data *ssd = getFromMSD( sd, 0 );
    removeFromMSD( sd, 0 );
    return retVal;
}

HPExport void plugin_init (void) {    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 );
}

there is a bug, when the player JUST login for the 1st time in that party ( party just loaded )
your name will appear twice in the party window
post-4102-0-78309900-1449272214_thumb.jpg
but will disappear when apply a buff ... or another party member login

and, when apply a buff, it really does show the [b____] for the party member name
post-4102-0-74101400-1449272411_thumb.jpg

I guess, have to do something like @showbuff atcommand, to make this bug disappear
it also has the advantage to show it or not to show it
... and this is harder to do than I thought
try continue tomorrow, I have to sleep now =.=

Edited by Dastgir
Edited the plugin with newline

Share this post


Link to post
Share on other sites
  • 0

@@Dastgir can you adapt this too on ur hercules plugin collection please? and check the bugs that annies talking about.

 

 

Edit: In chat log, they will have normal name, just party window will be edited.

 

and this :D

Edited by vBrenth

Share this post


Link to post
Share on other sites
  • 0

there is a bug, when the player JUST login for the 1st time in that party ( party just loaded )

your name will appear twice in the party window

Also we can see this bug, when someone enters to the party.
 
It is caused by sending of 0x1E9 packet, which adds one specific party member to the list on the client side.
 
To fix bug of this plugin, we can disable sending of this packet.
 
Because in any case server always sends full list of party members in 0xFB packet.

 

before:

 

HPExport void plugin_init (void) {

add:

 

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

 

after:

HPExport void plugin_init (void) {

add:

clif->party_member_info = &clif_party_member_info_overload;
Edited by Functor

Share this post


Link to post
Share on other sites
  • 0

http://upaste.me/aa5e49917485b4900

I need some people to comment on my script
I just bam bam and google here and there and it works on VS2015, but not sure if it is work on others though

1. need help how to really optimize this code
2.not really sure about using this kind of function

char *showing_buff( struct map_session_data *sd ) {

@meko

@4144

 


http://upaste.me/75d049918e2088402

no idea how I get this error message, only pop up once

[Error]: --- nullpo info --------------------------------------------
[Error]: ..\src\plugins\showbuff.c:115: 'p' in function `unknown'
[Error]: --- end nullpo info ----------------------------------------

@xVec

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

in ACMD(showbuff) in line 275 you show error message and p is NULL, and after call clif->party_info(p), this call your overloaded function clif_party_info_overload, and here it validate parameter for NULL and show error message.

Share this post


Link to post
Share on other sites
  • 0
On 6/5/2018 at 3:53 PM, AnnieRuru said:

0.4 http://upaste.me/75d049918e2088402
wow ~ thanks ... having an extra eye is different ...

about turning the [BASF+] into player configured buff ...
that will be done in another day ...

 

I have an error when i make the plugins:

        CC      showbuff.c
showbuff.c: In function ‘status_change_start_post’:
showbuff.c:50: warning: suggest parentheses around assignment used as truth value
showbuff.c: In function ‘clif_party_info_overload’:
showbuff.c:114: error: dereferencing pointer to incomplete type
showbuff.c:114: error: invalid application of ‘sizeof’ to incomplete type ‘struct PACKET_ZC_GROUP_LIST_SUB’
showbuff.c:119: error: dereferencing pointer to incomplete type
showbuff.c:119: error: ‘partyinfo’ undeclared (first use in this function)
showbuff.c:119: error: (Each undeclared identifier is reported only once
showbuff.c:119: error: for each function it appears in.)
showbuff.c:120: error: dereferencing pointer to incomplete type
showbuff.c:125: error: dereferencing pointer to incomplete type
showbuff.c:129: error: dereferencing pointer to incomplete type
showbuff.c:130: error: dereferencing pointer to incomplete type
showbuff.c:131: error: dereferencing pointer to incomplete type
showbuff.c:132: error: dereferencing pointer to incomplete type
showbuff.c:139: error: dereferencing pointer to incomplete type
showbuff.c:139: error: dereferencing pointer to incomplete type
showbuff.c:139: error: invalid application of ‘sizeof’ to incomplete type ‘struct PACKET_ZC_GROUP_LIST_SUB’
showbuff.c:148: error: dereferencing pointer to incomplete type
showbuff.c:152: error: dereferencing pointer to incomplete type
showbuff.c:172: error: dereferencing pointer to incomplete type
showbuff.c:182: error: dereferencing pointer to incomplete type
showbuff.c:186: error: dereferencing pointer to incomplete type
showbuff.c:114: warning: unused variable ‘buf’
make[1]: *** [../../plugins/showbuff.so] Error 1
make[1]: Leaving directory `/home/hercules1234/Hercules/src/plugins'
make: *** [plugins] Error 2

Any ideas'? Thx in advance

Share this post


Link to post
Share on other sites
  • 0
8 hours ago, xVec said:

 

I have an error when i make the plugins:


        CC      showbuff.c
showbuff.c: In function ‘status_change_start_post’:
showbuff.c:50: warning: suggest parentheses around assignment used as truth value
showbuff.c: In function ‘clif_party_info_overload’:
showbuff.c:114: error: dereferencing pointer to incomplete type
showbuff.c:114: error: invalid application of ‘sizeof’ to incomplete type ‘struct PACKET_ZC_GROUP_LIST_SUB’
showbuff.c:119: error: dereferencing pointer to incomplete type
showbuff.c:119: error: ‘partyinfo’ undeclared (first use in this function)
showbuff.c:119: error: (Each undeclared identifier is reported only once
showbuff.c:119: error: for each function it appears in.)
showbuff.c:120: error: dereferencing pointer to incomplete type
showbuff.c:125: error: dereferencing pointer to incomplete type
showbuff.c:129: error: dereferencing pointer to incomplete type
showbuff.c:130: error: dereferencing pointer to incomplete type
showbuff.c:131: error: dereferencing pointer to incomplete type
showbuff.c:132: error: dereferencing pointer to incomplete type
showbuff.c:139: error: dereferencing pointer to incomplete type
showbuff.c:139: error: dereferencing pointer to incomplete type
showbuff.c:139: error: invalid application of ‘sizeof’ to incomplete type ‘struct PACKET_ZC_GROUP_LIST_SUB’
showbuff.c:148: error: dereferencing pointer to incomplete type
showbuff.c:152: error: dereferencing pointer to incomplete type
showbuff.c:172: error: dereferencing pointer to incomplete type
showbuff.c:182: error: dereferencing pointer to incomplete type
showbuff.c:186: error: dereferencing pointer to incomplete type
showbuff.c:114: warning: unused variable ‘buf’
make[1]: *** [../../plugins/showbuff.so] Error 1
make[1]: Leaving directory `/home/hercules1234/Hercules/src/plugins'
make: *** [plugins] Error 2

Any ideas'? Thx in advance

Your hercules should be atleast updated till 2018.01.14

Share this post


Link to post
Share on other sites
  • 0
11 hours ago, xVec said:

I see.. I have a very very dummy question.

What if i don't want update my production herc and i just want add the PACKET_ZC_GROUP_LIST_SUB support?

If I modify this files it should work? https://github.com/HerculesWS/Hercules/search?q=ZC_PROGRESS_ACTOR&unscoped_q=ZC_PROGRESS_ACTOR

Wouldn't recommend that, but you need these changes: https://github.com/HerculesWS/Hercules/commit/499745c3eb6d79573e627433bd77881bd26afb7c

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.