npcChat [Non Retail]

daiiawn
Posts: 20
Joined: Tue Mar 12, 2013 7:56 am

npcChat [Non Retail]

Post by daiiawn » Sat Mar 30, 2013 2:27 pm

Attached is a non retail function, that allows mobs/npcs to send you /tells via lua scripts.

Example usage:
In CHOCOBO.LUA (NPC)

Code: Select all

function onTrigger(player,npc)
	message = "Galka's ate my mum";
	SendMobMessage(npc:getID(),player:getID(),message);
end;
In WILD_RABBIT.LUA (MOB)

Code: Select all

function onMobDeath(mob,killer)	
	message = "Yeah, thanks for that! :(";
	SendMobMessage(mob:getID(),killer:getID(),message);	
end;	
Attachments
npcChat.patch
(5.65 KiB) Downloaded 424 times

altalus
Posts: 136
Joined: Wed Nov 14, 2012 8:31 pm
Location: Montreal Qc, CAN

Re: npcChat [Non Retail]

Post by altalus » Sat Mar 30, 2013 4:55 pm

I love you for this... seriously... this is kick ass...

User avatar
TeoTwawki
Developer
Posts: 527
Joined: Mon Jul 15, 2013 9:50 pm

Re: npcChat [Non Retail]

Post by TeoTwawki » Sun Jun 15, 2014 11:32 pm

I made a few modifications to this for enabling other chat types besides tell.

The following instructions assume you don't have the older version already, if you do, just replace what you have from the patch.

Add this in chat_message.cpp :

Code: Select all

CNPCMessagePacket::CNPCMessagePacket(int8* name, CHAT_MESSAGE_TYPE MessageType, uint8 zone, int8* dat, uint8 size) 
{
	this->type = 0x17;
	this->size = 32 + strlen(dat) + strlen(dat)%2;
	WBUFB(data,(0x04)-4) = MessageType;
    WBUFB(data,(0x06)-4) = zone;
	memcpy(data+(0x08)-4, name,size);
	memcpy(data+(0x18)-4, dat, strlen(dat));
}
Add this in chat_message.h right above the #endif line:

Code: Select all

class CNPCMessagePacket : public CBasicPacket
{
public:
	CNPCMessagePacket(int8* name, CHAT_MESSAGE_TYPE MessageType, uint8 zone, int8* dat,uint8 size);
};
In luautils.cpp find:

Code: Select all

Lunar<CLuaAbility>::Register(LuaHandle);
and make these new lines above it

Code: Select all

	lua_register(LuaHandle,"SpoofSay",luautils::SpoofSay);
	lua_register(LuaHandle,"SpoofTell",luautils::SpoofTell);
Also in luautils.cpp find:

Code: Select all

/************************************************************************
*                                                                       *
*  Загружаем значение переменной TextID указанной зоны                  *
*                                                                       *
************************************************************************/

int32 GetTextIDVariable(uint16 ZoneID, const char* variable)
And place this code above it:

Code: Select all

/************************************************************************
*																		*
*	Send a fake "say" message from an NPC or MOB.						*
*																		*
************************************************************************/

int32 SpoofSay(lua_State* L)
{
	uint32 mobid = (uint32)lua_tointeger(L,1);
	uint32 CharID = (uint32)lua_tointeger(L,2);
	CBaseEntity* PNPC = (CBaseEntity*)zoneutils::GetEntity(mobid, TYPE_MOB | TYPE_NPC);
	if (PNPC != NULL)
	{
		const int8* Query = "SELECT targid, pos_zone FROM chars INNER JOIN accounts_sessions USING(charid) WHERE charid = %u LIMIT 1";
		int32 ret = Sql_Query(SqlHandle, Query, CharID);
		if (ret != SQL_ERROR &&
		Sql_NumRows(SqlHandle) != 0 &&
		Sql_NextRow(SqlHandle) == SQL_SUCCESS)
		{
			uint16 TargID = (uint16)Sql_GetUIntData(SqlHandle,0);
			uint8  ZoneID = (uint8) Sql_GetUIntData(SqlHandle,1);
			CCharEntity* PTellRecipient = (CCharEntity*)zoneutils::GetZone(ZoneID)->GetEntity(TargID, TYPE_PC);
			int8* data = (int8*)lua_tolstring(L,3,NULL);
			int8* name = (int8*)PNPC->GetObjectName();
			uint8 size = (uint8)PNPC->name.size();
			PTellRecipient->pushPacket(new CNPCMessagePacket(name,MESSAGE_SAY,ZoneID,data,size));
		}
	}
	return 1;
}

/************************************************************************
*																		*
*	Send a fake "tell" message from an NPC or MOB.						*
*																		*
************************************************************************/

int32 SpoofTell(lua_State* L)
{
	uint32 mobid = (uint32)lua_tointeger(L,1);
	uint32 CharID = (uint32)lua_tointeger(L,2);
	CBaseEntity* PNPC = (CBaseEntity*)zoneutils::GetEntity(mobid, TYPE_MOB | TYPE_NPC);
	if (PNPC != NULL)
	{
		const int8* Query = "SELECT targid, pos_zone FROM chars INNER JOIN accounts_sessions USING(charid) WHERE charid = %u LIMIT 1";
		int32 ret = Sql_Query(SqlHandle, Query, CharID);
		if (ret != SQL_ERROR &&
		Sql_NumRows(SqlHandle) != 0 &&
		Sql_NextRow(SqlHandle) == SQL_SUCCESS)
		{
			uint16 TargID = (uint16)Sql_GetUIntData(SqlHandle,0);
			uint8  ZoneID = (uint8) Sql_GetUIntData(SqlHandle,1);
			CCharEntity* PTellRecipient = (CCharEntity*)zoneutils::GetZone(ZoneID)->GetEntity(TargID, TYPE_PC);
			int8* data = (int8*)lua_tolstring(L,3,NULL);
			int8* name = (int8*)PNPC->GetObjectName();
			uint8 size = (uint8)PNPC->name.size();
			PTellRecipient->pushPacket(new CNPCMessagePacket(name,MESSAGE_TELL,ZoneID,data,size));
		}
	}
	return 1;
}
In luautils.h find:

Code: Select all

	int32 UpdateNMSpawnPoint(lua_State* L);                                     // Update the spawn point of an NM
and place these newlines below it:

Code: Select all

	int32 SpoofSay(lua_State* L);												// Send faked say messages from NPCs or MOBs.
	int32 SpoofTell(lua_State* L);												// Send faked tell messages from NPCs or MOBs.
If you compare with the patch you'll see I didn't change much. All really did I did was add the chat type instead of a static 0x03 and renamed the command(s).

Thank you daiiawn for posting the original version of this!


Edit: missed a piece of code in baseentity.cpp right after

Code: Select all

const int8* CBaseEntity::GetName()
{
	return name.c_str();
}
I have this (which I think is almost identical to the original patch, don't remember changing it *shrug*):

Code: Select all

const int8* CBaseEntity::GetObjectName()
{
	// Strip out the _ in names
	ObjectName = name;
	size_t start_pos = ObjectName.find("_");
	if (start_pos < name.size())
	{
		ObjectName.replace(start_pos,1," ");
	}
	return ObjectName.c_str();
}
In baseentitity.h find:

Code: Select all

	virtual const int8*		GetName();			// The entity name
and add:

Code: Select all

	virtual const int8*		GetObjectName();	// The entity name
Last edited by TeoTwawki on Thu Oct 23, 2014 10:19 pm, edited 4 times in total.
Hi, I run The Demiurge server.


Image
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. - Martin Golding
PLS USE [ code ] CODE TAGS [ /code ] WHEN POSTING CODE
DO NOT PRIVATE MESSAGE ME ABOUT BUGS

nasomi
Posts: 141
Joined: Wed Feb 13, 2013 8:51 am

Re: npcChat [Non Retail]

Post by nasomi » Sun Aug 03, 2014 9:22 pm

I'm liking this, but I wanted to make sure of something.

chat_message.h has this:

Code: Select all

class CChatMessagePacket : public CBasicPacket
{
public:

	CChatMessagePacket(CCharEntity* PChar, CHAT_MESSAGE_TYPE MessageType, int8* buff);
};
And you want to add this below that?

Code: Select all

class CNPCMessagePacket : public CBasicPacket
{
public:
	CNPCMessagePacket(int8* name, CHAT_MESSAGE_TYPE MessageType, uint8 zone, int8* dat, uint8 size);
};

Also this:

Code: Select all

CNPCMessagePacket::CNPCMessagePacket(int8* name, CHAT_MESSAGE_TYPE MessageType, uint8 zone, int8* dat, uint8 size)
{
	this->type = 0x17;
	this->size = 32 + strlen(dat) + strlen(dat) % 2;
	WBUFB(data, (0x04) - 4) = MessageType;
	WBUFB(data, (0x06) - 4) = zone;
	memcpy(data + (0x08) - 4, name, size);
	memcpy(data + (0x18) - 4, dat, strlen(dat));
}
Goes after this:

Code: Select all

CChatMessagePacket::CChatMessagePacket(CCharEntity* PChar, CHAT_MESSAGE_TYPE MessageType, int8* buff)
{
    this->type = 0x17;
    this->size = 32 + strlen(buff) + strlen(buff) % 2;

    if (PChar->nameflags.flags & FLAG_GM)
    {
        WBUFB(data, (0x05) - 4) = 0x01;
    }
    WBUFB(data, (0x04) - 4) = MessageType;
    WBUFW(data, (0x06) - 4) = PChar->getZone();

    memcpy(data + (0x08) - 4, PChar->GetName(), PChar->name.size());
    memcpy(data + (0x18) - 4, buff, strlen(buff));
Does that sound right?

User avatar
TeoTwawki
Developer
Posts: 527
Joined: Mon Jul 15, 2013 9:50 pm

Re: npcChat [Non Retail]

Post by TeoTwawki » Sun Aug 03, 2014 11:11 pm

Yep
Hi, I run The Demiurge server.


Image
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. - Martin Golding
PLS USE [ code ] CODE TAGS [ /code ] WHEN POSTING CODE
DO NOT PRIVATE MESSAGE ME ABOUT BUGS

nasomi
Posts: 141
Joined: Wed Feb 13, 2013 8:51 am

Re: npcChat [Non Retail]

Post by nasomi » Mon Aug 04, 2014 12:53 pm

That's throwing more than a few errors.

GetSayName is not a member of cbaseentity, there were no modifications to baseentity.h that i saw.

syntax error: identifier 'cnpc messagepacket
message_say : unidentified identifier
ccharentity::pushpacket functin does not take 5 arguments

Am I missing something? It produced 16 errors.

User avatar
TeoTwawki
Developer
Posts: 527
Joined: Mon Jul 15, 2013 9:50 pm

Re: npcChat [Non Retail]

Post by TeoTwawki » Mon Aug 04, 2014 3:02 pm

You're right I missed something else that got altered from the original patch. Editing the other post.

Changed it GetObjectName. The original Patch had GetTellName, and before I merged our work and shared I had been using a GetSayName for spoofs. Just changed the name because we aren't using it just for tell. Add the snippet I added to the other post and change existing instances of GetSayName and it should compile now.
Hi, I run The Demiurge server.


Image
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. - Martin Golding
PLS USE [ code ] CODE TAGS [ /code ] WHEN POSTING CODE
DO NOT PRIVATE MESSAGE ME ABOUT BUGS

User avatar
Aale
Posts: 22
Joined: Thu Aug 07, 2014 1:08 pm

Re: npcChat [Non Retail]

Post by Aale » Tue Jun 30, 2015 1:52 pm

Sorry for the necro bump, did the instructional post after the OP ever get edited? Just compiled this and getting the same 16 errors nasomi had.

Edit - only getting 15 errors, and 1 warning as follows:

warning C4005: 'FD_SETSIZE' : macro redefinition d:\ffxi server\darkstar\src\common\socket.h 12 1 DSGame-server

error C2061: syntax error : identifier 'CNPCMessagePacket' d:\ffxi server\darkstar\src\map\lua\luautils.cpp 991 1 DSGame-server
error C2065: 'MESSAGE_SAY' : undeclared identifier d:\ffxi server\darkstar\src\map\lua\luautils.cpp 991 1 DSGame-server
error C2660: 'CCharEntity::pushPacket' : function does not take 5 arguments d:\ffxi server\darkstar\src\map\lua\luautils.cpp 991 1 DSGame-server
error C2143: syntax error : missing ';' before ')' d:\ffxi server\darkstar\src\map\lua\luautils.cpp 991 1 DSGame-server
error C2061: syntax error : identifier 'CNPCMessagePacket' d:\ffxi server\darkstar\src\map\lua\luautils.cpp 1022 1 DSGame-server
error C2065: 'MESSAGE_TELL' : undeclared identifier d:\ffxi server\darkstar\src\map\lua\luautils.cpp 1022 1 DSGame-server
error C2660: 'CCharEntity::pushPacket' : function does not take 5 arguments d:\ffxi server\darkstar\src\map\lua\luautils.cpp 1022 1 DSGame-server
error C2143: syntax error : missing ';' before ')' d:\ffxi server\darkstar\src\map\lua\luautils.cpp 1022 1 DSGame-server
error C2065: 'ObjectName' : undeclared identifier d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 66 1 DSGame-server
error C2065: 'ObjectName' : undeclared identifier d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 67 1 DSGame-server
error C2228: left of '.find' must have class/struct/union d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 67 1 DSGame-server
error C2065: 'ObjectName' : undeclared identifier d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 70 1 DSGame-server
error C2228: left of '.replace' must have class/struct/union d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 70 1 DSGame-server
error C2065: 'ObjectName' : undeclared identifier d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 72 1 DSGame-server
error C2228: left of '.c_str' must have class/struct/union d:\ffxi server\darkstar\src\map\entities\baseentity.cpp 72 1 DSGame-server

User avatar
TeoTwawki
Developer
Posts: 527
Joined: Mon Jul 15, 2013 9:50 pm

Re: npcChat [Non Retail]

Post by TeoTwawki » Tue Jun 30, 2015 4:15 pm

The packet this uses got changed a bit. My own post on this is way old/outdated now. I have a sort of working version right now but I have a few bugs to work out. I dunno if daiiawn is still around anymore, but I'll see if I can make time to post an updated version. Among other changes I've made since then: argument to function to specify chat type (say tell shout etc), rather than multiple near duplicate functions.
Hi, I run The Demiurge server.


Image
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. - Martin Golding
PLS USE [ code ] CODE TAGS [ /code ] WHEN POSTING CODE
DO NOT PRIVATE MESSAGE ME ABOUT BUGS

User avatar
Aale
Posts: 22
Joined: Thu Aug 07, 2014 1:08 pm

Re: npcChat [Non Retail]

Post by Aale » Tue Jun 30, 2015 4:17 pm

Awesome, looking forward to it ^^

Post Reply