• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua Function onWriteToChannel(cid, channelId, text) [+ extra doPlayerOpenChannel(cid, channelId)]

Colandus

Advanced OT User
Senator
Joined
Jun 6, 2007
Messages
2,434
Solutions
19
Reaction score
219
Location
Sweden
Hello. This can be used for several things... E.g. you could rewrite guild system to be in Lua or make anti-bot system in a channel without using a command in front of each word (that means if you'd be using talkactions). onWriteToChannel does not react on keywords, as fast as you write to a channel it will call this function!



So, open up creatureevent.h, and under:
Code:
	CREATURE_EVENT_CHANNEL_LEAVE,

Add:
Code:
	CREATURE_EVENT_CHANNEL_WRITE,

And under:
Code:
uint32_t executeChannelLeave(Player* player, uint16_t channelId, UsersMap usersMap);

Add:
Code:
uint32_t executeChannelWrite(Player* player, uint16_t channelId, std::string text);

Now, open creatureevent.cpp.

Under:
Code:
	else if(tmpStr == "joinchannel")
		m_type = CREATURE_EVENT_CHANNEL_JOIN;

Add:
Code:
	else if(tmpStr == "writetochannel")
		m_type = CREATURE_EVENT_CHANNEL_WRITE;

Under:
Code:
		case CREATURE_EVENT_CHANNEL_LEAVE:
			return "onLeaveChannel";

Add:
Code:
		case CREATURE_EVENT_CHANNEL_WRITE:
			return "onWriteToChannel";

Under:
Code:
		case CREATURE_EVENT_CHANNEL_LEAVE:
			return "cid, channel, users";

Add:
Code:
		case CREATURE_EVENT_CHANNEL_WRITE:
			return "cid, channel, text";

Under function:
Code:
uint32_t CreatureEvent::executeChannelLeave(Player* player, uint16_t channelId, UsersMap usersMap)

Add:
Code:
uint32_t CreatureEvent::executeChannelWrite(Player* player, uint16_t channelId, std::string text)
{
	//onWriteToChannel(cid, channel, text)
	if(m_scriptInterface->reserveScriptEnv())
	{
		ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
		if(m_scripted == EVENT_SCRIPT_BUFFER)
		{
			env->setRealPos(player->getPosition());
			std::stringstream scriptstream;
			scriptstream << "local cid = " << env->addThing(player) << std::endl;

			scriptstream << "local channel = " << channelId << std::endl;
			scriptstream << "local text = " << text << std::endl;

			scriptstream << m_scriptData;
			bool result = true;
			if(m_scriptInterface->loadBuffer(scriptstream.str()) != -1)
			{
				lua_State* L = m_scriptInterface->getLuaState();
				result = m_scriptInterface->getGlobalBool(L, "_result", true);
			}

			m_scriptInterface->releaseScriptEnv();
			return result;
		}
		else
		{
			#ifdef __DEBUG_LUASCRIPTS__
			char desc[35];
			sprintf(desc, "%s", player->getName().c_str());
			env->setEventDesc(desc);
			#endif

			env->setScriptId(m_scriptId, m_scriptInterface);
			env->setRealPos(player->getPosition());

			lua_State* L = m_scriptInterface->getLuaState();
			m_scriptInterface->pushFunction(m_scriptId);

			lua_pushnumber(L, env->addThing(player));
			lua_pushnumber(L, channelId);
			lua_pushstring(L, text.c_str());

			bool result = m_scriptInterface->callFunction(3);
			m_scriptInterface->releaseScriptEnv();
			return result;
		}
	}
	else
	{
		std::cout << "[Error - CreatureEvent::executeChannelWrite] Call stack overflow." << std::endl;
		return 0;
	}
}

Now finally open up chat.cpp, find function Chat::talkToChannel, above:
Code:
	if(channelId != CHANNEL_GUILD || !g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT)
		|| (text[0] != '!' && text[0] != '/'))

Add:
Code:
	CreatureEventList writeEvents = player->getCreatureEvents(CREATURE_EVENT_CHANNEL_WRITE);
	for(CreatureEventList::iterator it = writeEvents.begin(); it != writeEvents.end(); ++it)
		if(!(*it)->executeChannelWrite(player, channelId, text))
			return true;


Now, in creaturescripts.xml you write:
Code:
	<event type="writetochannel" name="PlayerWriteToChannel" event="script" value="playerWrite.lua"/>

And script (example):
Lua:
function onWriteToChannel(cid, channelId, text)
    if(text:lower() == 'fuck') then
        doPlayerSendChannelMessage(cid, "", "Swearings are not allowed here!", TALKTYPE_CHANNEL_RN, channelId)
        return false -- this will make his text dont appear!
    end
    return true
end

Then we're done! :) Enjoy! :D


Now, if you want function doPlayerOpenChannel, keep reading!

In luascript.h, find:
Code:
		static int32_t luaGetChannelUsers(lua_State* L);

Under it add:
Code:
static int32_t luaDoPlayerOpenChannel(lua_State* L);

Now go to luascript.cpp and find:
Code:
	//getChannelUsers(channelId)
	lua_register(m_luaState, "getChannelUsers", LuaScriptInterface::luaGetChannelUsers);

Under it add:
Code:
	//doPlayerOpenChannel(cid, channelId)
	lua_register(m_luaState, "doPlayerOpenChannel", LuaScriptInterface::luaDoPlayerOpenChannel);

Now find function:
Code:
int32_t LuaScriptInterface::luaGetChannelUsers(lua_State* L)

Under it add:
Code:
int32_t LuaScriptInterface::luaDoPlayerOpenChannel(lua_State* L)
{
	//doPlayerOpenChannel(cid, channelId)
	uint32_t channelId = popNumber(L);
	uint32_t cid = popNumber(L);
	
	ScriptEnviroment* env = getScriptEnv();
	Player* player = env->getPlayerByUID(cid);
	if(player)
		lua_pushnumber(L, g_game.playerOpenChannel(cid, channelId) ? true : false);
	else
	{
		reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
		lua_pushnumber(L, false);
	}
	return 1;
}
 
Last edited:
Please HELP me ;)
helpmey.jpg
 
You have not added the functions in creatureevent.cpp/h ! Please check the main post again and go through each step properly.
 
Well... I'll add today more channel related functions to TFS (onChannelMessage, which you have made, but you don't pass users map what's imho bad) and like openchannel, etc. Thanks for suggestion :p
 
Yes, I was thinking if I should pass users map or not, but I couldn't think of any case you'd need it so... And if you'd really need it you'd simply use getChannelUsers function :p
 
LoL you think you're only one who can figure that ? :) I had that code in my server for 3+ months now :p
 
Is right but ...

i no did because I do not know
but I guarantee you do not take ideas from other

and not give credits for those who had the idea :mad:
 
Whatever translator you are using, this idea was not yours. I'm using it for my server theotserver.com, and I've had it on my old one too, now for over 4 months!

This has been requested by lots of people, that's why I released it. I never even saw your thread :p
 
Last edited:
No one cares about idea, the most important is coder ;]
 
Under:
uint32_t executeChannelLeave(Player* player, uint16_t channelId, UsersMap usersMap);

add this ?:
uint32_t executeChannelWrite(Player* player, uint16_t channelId, std::string text);

I added, an error when compiling:
Code:
 E:\TFS\creatureevent.cpp In member function `uint32_t CreatureEvent::executeChannelWrite(Player*, uint16_t, std::string)': 
575 E:\TFS\creatureevent.cpp no matching function for call to `LuaScriptInterface::getGlobalBool(lua_State*&, const char[8], bool)' 
 note E:\TFS\luascript.h:329 candidates are: static bool LuaScriptInterface::getGlobalBool(lua_State*, const std::string&, const std::string&)
 
Did you add in creatureevent.cpp too ?

Edit: ohh now I noticed I missed that part :p Added now :)
 
result = m_scriptInterface->getGlobalBool(L, "_result", true);


replace it:
result = m_scriptInterface->getFieldBool(L, "_result");


for me it works. :p


this is right?

if(text:lower()) == 'fuck') then

...'fuck') :confused:

small patch: :p

Lua:
  function onWriteToChannel(cid, channelId, text)
    if((text:lower()) == 'fuck') then
        doPlayerSendChannelMessage(cid, "", "Swearings are not allowed here!", TALKTYPE_CHANNEL_W, channelId)

		return false -- this will make his text dont appear!
    end
    return true
end


//and operates only on channels, not working on default: (
 
Back
Top