• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

TalkAction Private message system.

Joined
Apr 17, 2008
Messages
1,922
Solutions
1
Reaction score
188
Location
Venezuela
Releasing my brand new script, a private message system.

How this works?

22:00 Player X: /message Hello man, i miss u :(; Darkhaos
22:00 Message successfully sended to Darkhaos.
Only if Darkhaos is online --
22:00 You have received a new private message.
--
22:15 Darkhaos: /read
22:15 Reading 1 message(s).
22:15 Message from Player X at 01/10/11 22:00:05 > Hello man, i miss u :(

22:16 Darkhaos: /delete
22:16 You have deleted 1 message(s).

23:00 Player X: /message Hello man, i neet you; Darkhaos
23:00 Player X: /message i need you*, sorry my bad writting; Darkhaos

23:10 Darkhaos: /read
23:10 Reading 2 message(s).
23:10 Message from Player X at 01/10/11 23:00:17 > Hello man, i neet you
23:10 Message from Player X at 01/10/11 23:00:20 > i need you*, sorry my bad writting

23:11 Darkhaos: /delete
23:11 You have deleted 2 message(s).

23:10 Darkhaos: /read
23:10 Reading 3 message(s).
23:10 Message from Player X at 01/10/11 19:10:17 > Hello man, i neet you
23:10 Message from Player X at 01/10/11 19:10:20 > i need you*, sorry my bad writting
23:10 Message from Player X at 01/10/11 19:10:22 > PD: I love you
23:11 Darkhaos: /delete 2
23:11 You have deleted 2 message(s).
23:11 Darkhaos: /read
23:11 Reading 1 message(s).
23:11 Message from Player X at 01/10/11 19:10:22 > PD: I love you


First of all, execute this on phpMyAdmin:
SQL:
alter table players add messages varchar(10000) not null default '';

Now paste this on a lib file
LUA:
messageSep = "<msgSep>" --used on database
senderSep = "<sendSep>" --used on database

function getPlayerMessages(name)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	local messages = {}
	local x
	if query:getID() ~= -1 then
		x = query:getDataString("messages")
		x = string.explode(x, messageSep)
		for i = 1, table.maxn(x) do
			table.insert(messages, x[i])
		end
	end
	return messages
end

function doPlayerAddMessage(name, message, sender)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	if query:getID() ~= -1 then
		local m = query:getDataString("messages")
		m = m .. (m ~= "" and messageSep or "") .. message .. senderSep .. getCreatureName(sender) .. senderSep .. os.date()
		local newquery = db.executeQuery("update players set messages = " .. db.escapeString(m) .. " where name = " .. db.escapeString(name) .. ";")
		if not newquery then
			return false
		end
	else
		return false
	end
	return true
end

function doPlayerRemoveMessages(name, limit)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	local messages = {}
	local x, y
	local t, tt = "", ""
	if query:getID() ~= -1 then
		x, y = query:getDataString("messages"), query:getDataString("messages")
		x = string.explode(x, messageSep)
		for i = 1, limit do
			t = t .. x[i]
		end

		tt = string.sub(y, string.len(t) + (string.len(messageSep) * limit) + 1, string.len(y))
		local newquery = db.executeQuery("update players set messages = " .. db.escapeString(tt) .. " where name = " .. db.escapeString(name) .. ";")
		if not newquery then
			return false
		end
	end
	return true
end

function getPlayerMessagesLenght(name)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	if query:getID() ~= -1 then
		return string.len(query:getDataString("messages"))
	end
	return -1
end

Now, create a file on data/talkactions/scripts called message.lua and paste this:
LUA:
local maxMessageLenght = 1500
local deleteMessageAsRead = false

function onSay(cid, words, param, channel)

	local msg = getPlayerMessages(getCreatureName(cid))
	if words == "/message" then
		param = string.explode(param, ";")
		if table.maxn(param) < 2 then
			return doPlayerSendCancel(cid, "No player specified.")
		end
		if param[2]:lower() == getCreatureName(cid):lower() then
			return doPlayerSendCancel(cid, "You cannot send messages to yourself.")
		end
		if string.len(param[1]) > maxMessageLenght then
			return doPlayerSendCancel(cid, "Message is too long, only " .. maxMessageLenght .. " characters are admitted.")
		end
		if playerExists(param[2]) and getPlayerMessagesLenght(param[2]) >= 10000 then
			return doPlayerSendCancel(cid, "You cannot send more messages to " .. param[2] .. " until he/she clean his/her inbox.")
		end
		if doPlayerAddMessage(param[2], param[1], cid) then
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Message successfully sended to " .. param[2] .. ".")
			if getPlayerByNameWildcard(param[2]) then
				doPlayerSendTextMessage(getPlayerByNameWildcard(param[2]), MESSAGE_INFO_DESCR, "You have received a new private message.")
			end
		else
			doPlayerSendCancel(cid, "Player with that name does not exists.")
		end
	elseif words == "/read" then
		doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Reading " .. table.maxn(msg) .. " message(s)" .. (not deleteMessageAsRead and getPlayerMessagesLenght(getCreatureName(cid)) >= 10000 and ", your inbox is full, you should delete messages or you won't receive more messages" or "") .. ".")
		if table.maxn(msg) > 0 then
			for i = 1, table.maxn(msg) do
				local t = string.explode(msg[i], senderSep)
				doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Message from " .. t[2] .. " at " .. (t[3] or "No Date") .. " > " .. t[1])
			end
		end
		if deleteMessageAsRead and table.maxn(msg) > 0 then
			if doPlayerRemoveMessages(getCreatureName(cid)) then
				doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "The following message(s) have been deleted.")
			end
		end
	elseif words == "/delete" then
		local limit = (tonumber(param) and tonumber(param) > 0 and tonumber(param) <= table.maxn(msg) and tonumber(param) or table.maxn(msg))
		if doPlayerRemoveMessages(getCreatureName(cid), limit) then
			doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have deleted " .. limit .. " message(s).")
		end
	end
	return true
end

And paste this on data/talkactions/talkactions.xml
XML:
	<talkaction words="/message;/read;/delete" event="script" value="messages.lua"/>

If you want to notify players at login if they have messages, add this to your login.lua:
LUA:
	local msg = getPlayerMessages(getCreatureName(cid))
	if table.maxn(msg) > 0 then
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have " .. table.maxn(msg) .. " new message(s).")
	end

Enjoy (:
 
Last edited:
http://simonwillison.net/2002/Aug/1/mysqlTextLimits/ said:
MySQL text limits
Today’s scary discovery: MySQL TEXT fields have a limit of 65,000 bytes. If you insert anything larger than that in to a normal TEXT field mySQL will silently truncate your data without telling you (meaning software checks are probably a good idea).
'only 65KB' and player can read it by command /read?!
Players can also use separator in their messages :(
Fixed version of script:
* Limit of message text lenght
* Limit of read messages
* Replace separator in message with 'HAXOR'
--------
MOD:
PHP:
<?xml version="1.0" encoding="UTF-8"?>
<mod name="Messages to offline players" version="1.0" author="darkhaos" contact="http://otland.net/forum.php" enabled="yes">
	<config name="messages_config"><![CDATA[
	messageSep = "<msgSep>" --used on database
	messageSenderSep = "<sendSep>" --used on database
	messageMaxLenght = 200
	messageMaxPerRead = 10
	function getPlayerMessages(name)
		local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
		local messages = {}
		local x
		if query:getID() ~= -1 then
			x = query:getDataString("messages")
			x = string.explode(x, messageSep)
			for i = 1, math.min(table.maxn(x), messageMaxPerRead) do
				table.insert(messages, x[i])
			end
		end
		return messages
	end
	 
	function doPlayerAddMessage(name, message, sender)
		local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
		if query:getID() ~= -1 then
			local m = query:getDataString("messages")
			m = m .. (m ~= "" and messageSep or "") .. message .. messageSenderSep .. getCreatureName(sender) .. messageSenderSep .. os.date()
			local newquery = db.executeQuery("update players set messages = " .. db.escapeString(m) .. " where name = " .. db.escapeString(name) .. ";")
			if not newquery then
				return false
			end
		else
			return false
		end
		return true
	end
	 
	function doPlayerRemoveMessages(name)
		local query = db.executeQuery("update players set messages = '' where name = " .. db.escapeString(name) .. ";")
		if not query then
			return false
		end
		return true
	end
	]]></config>
	<talkaction words="/message; /read; /delete" event="buffer"><![CDATA[
	domodlib('messages_config')
	if words == "/message" then
		param = string.explode(param, ";")
		if table.maxn(param) < 2 then
			return doPlayerSendCancel(cid, "No player specified.")
		end
		local message = string.gsub(string.gsub(param[1], messageSenderSep, 'HAXOR'), messageSep, 'HAXOR')
		if string.len(message) <= messageMaxLenght then
			if playerExists(param[2]) and doPlayerAddMessage(param[2], message, cid) then
				doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Message successfully sended to " .. param[2] .. ".")
				if getPlayerByNameWildcard(param[2]) then
					doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have received a new private message.")
				end
			else
				doPlayerSendCancel(cid, "Player with that name does not exists.")
			end
		else
			doPlayerSendCancel(cid, "Too long message, max. lenght: " .. messageMaxLenght)
		end
	elseif words == "/read" then
		local msg = getPlayerMessages(getCreatureName(cid))
		doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Reading " .. table.maxn(msg) .. " message(s).")
		if table.maxn(msg) > 0 then
			for i = 1, table.maxn(msg) do
				local t = string.explode(msg[i], messageSenderSep)
				doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Message from " .. t[2] .. " at " .. t[3] .. " > " .. t[1])
			end
		end
	elseif words == "/delete" then
		local msg = getPlayerMessages(getCreatureName(cid))
		if doPlayerRemoveMessages(getCreatureName(cid)) then
			doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have deleted " .. table.maxn(msg) .. " message(s).")
		end
	end
	return true
	]]></talkaction>
</mod>
 
Even though I'm almost capable of doing anything LUA related, I can't tell you how advanced this looks while being drunk xDDD
 
i used:
iam: /message hello ; test

and it says in the console:
16:28 Message successfully sended to Test.
16:28 You have received a new private message.

But i asked to "Test" and he didnt receive anything u.u
 
i used:
iam: /message hello ; test

and it says in the console:
16:28 Message successfully sended to Test.
16:28 You have received a new private message.

But i asked to "Test" and he didnt receive anything u.u

I tested script again and didn't get that.

PD: Script updated and a new function added, some optimizations and features added.
 
i got this :<

[11/01/2011 20:11:10] [Error - TalkAction Interface]
[11/01/2011 20:11:10] data/talkactions/scripts/messages.lua:onSay
[11/01/2011 20:11:10] Description:
[11/01/2011 20:11:10] data/talkactions/scripts/messages.lua:18: attempt to call global 'getPlayerMessagesLenght' (a nil value)
[11/01/2011 20:11:10] stack traceback:
[11/01/2011 20:11:10] data/talkactions/scripts/messages.lua:18: in function <data/talkactions/scripts/messages.lua:4>
 
i got this :<

you needs add this function in data/lib/050-function

LUA:
messageSep = "<msgSep>" --used on database
senderSep = "<sendSep>" --used on database
 
function getPlayerMessages(name)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	local messages = {}
	local x
	if query:getID() ~= -1 then
		x = query:getDataString("messages")
		x = string.explode(x, messageSep)
		for i = 1, table.maxn(x) do
			table.insert(messages, x[i])
		end
	end
	return messages
end
 
function doPlayerAddMessage(name, message, sender)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	if query:getID() ~= -1 then
		local m = query:getDataString("messages")
		m = m .. (m ~= "" and messageSep or "") .. message .. senderSep .. getCreatureName(sender) .. senderSep .. os.date()
		local newquery = db.executeQuery("update players set messages = " .. db.escapeString(m) .. " where name = " .. db.escapeString(name) .. ";")
		if not newquery then
			return false
		end
	else
		return false
	end
	return true
end
 
function doPlayerRemoveMessages(name)
	local query = db.executeQuery("update players set messages = '' where name = " .. db.escapeString(name) .. ";")
	if not query then
		return false
	end
	return true
end
 
function getPlayerMessagesLenght(name)
	local query = db.getResult("select messages from players where name = " .. db.escapeString(name) .. ";")
	if query:getID() ~= -1 then
		return string.len(query:getDataString("messages"))
	end
	return -1
end

;)
 
Back
Top