• 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!

TalkAction Changename in-game

LucasFerraz

Systems Analyst
Joined
Jun 10, 2010
Messages
2,858
Reaction score
96
Location
Brazil
Changename in-game v2.0

Talkaction: "words" newName
Description: Changes the name of a character in-game.
Recommended version: 4.0
Made by: Ratser (REP+)

Installation
data/talkactions/talkactions.xml:
XML:
	<talkaction log="yes" words="!changename;/changename;!namechange;/namechange" access="0" event="script" value="changename.lua"/>
data/talkactions/changename.lua:
v4.0:
Code:
Changelog (v4.0):

Optimized the code.
Removed the "force" parameter for the namelock check and replaced it with a config value (left the string.explode for future features such as changing the name of other players).
Now the script supports multiworld.
Used a workaround to fix the LIMIT bug in sqlite.
New config values:
- kick: Kicks the player after the name change.
-- enabled: To enable or disable the player kick.
-- delay: The delay value for the player kick event. Now it can be freely configured.
- forceLogout: Kick players without restrictions. It isn't needed in most cases but added a config value anyways (this is why it's not enabled by default).
- namelockCheck: To check if the new name is namelocked.
- vowelsCheck: To check if there are vowels in the new name.
- minWordLenght: The minimum lenght for each word of the new name.
- maxWordLenght: The maximum lenght for each word of the new name.
- maxWords: The maximum amount of words that the new name can have.
New checks:
- The script now detects if the server is running on "mysql" or "sqlite" and adapts the queries depending on the result.
- If the words are not in an appropiated format they are automatically fixed (e.g. rAtSeR -> Ratser).
-- The first letter of the first word will always be uppercase. In the rest of words, the first letter won't be changed.
-- The other letters of each word will be lowercase.

Lua:
local config = {
	item = {Id = 1111, count = 0},
	paramBlacklist = {"account manager", "god", "tutor", "tester"},
	kick = {enabled = true, delay = 2 * 1000},
	forceLogout = false,
	namelockCheck = true,
	vowelsCheck = true,
	maxTextLenght = 29,
	minWordLenght = 2,
	maxWordLenght = 14,
	maxWords = 3
}
 
config.kick.enabled = getBooleanFromString(config.kick.enabled)
config.forceLogout = getBooleanFromString(config.forceLogout)
config.namelockCheck = getBooleanFromString(config.namelockCheck)
config.vowelsCheck = getBooleanFromString(config.vowelsCheck)
 
function onSay(cid, words, param, channel)
	local t = string.explode(param, ",")
	local len, firstWord, wordCount, textCancel, limit = string.len(tostring(t[1])), true, 0, '', ";"
	if(getConfigValue('sqlType') == 'mysql') then
		limit = db.updateLimiter()
	end
 
	if(param == '') then
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Command param required.")
	elseif(getPlayerGUIDByName(t[1], true) ~= nil) then
		textCancel = "That name is already in use."
	elseif(getPlayerItemCount(cid, config.item.Id) < config.item.count) then
		textCancel = "You do not fulfill the requirements."
	elseif(not getTilePzInfo(getCreaturePosition(cid))) then
		textCancel = "You must be inside a protection zone to use this command."
	elseif(len > config.maxTextLenght) then
		textCancel = "A name must have at least " .. config.minWordLenght .. " but no more than " .. config.maxTextLenght .. " letters!"
	elseif(config.namelockCheck and db.getResult("SELECT * FROM `player_namelocks` WHERE `name` = " .. db.escapeString(t[1]) .. "" .. limit .. ""):getID() ~= 1) then
		textCancel = "That name is namelocked."
	elseif(string.find(t[1]:lower(), "[^%l%s]") ~= nil) then
		textCancel = "This name contains invalid letters. Please use only A-Z, a-z and space!"
	else
		paramTemp = ''
		for word in string.gmatch(t[1], "%a+") do
			len, wordCount = string.len(word), wordCount + 1
			if(isInArray(config.paramBlacklist, paramTemp:lower())) then
				textCancel = "Invalid name entry."
				break
			elseif(len < config.minWordLenght) then
				textCancel = "This name contains a word with only " .. len .. " letter" .. (len > 1 and "s" or '') .. ". Please use more than " .. len .. " letter" .. (len > 2 and "s" or '') .. " for each word!"
				break
			elseif(len > config.maxWordLenght) then
				textCancel = "This name contains a word that is too long. Please use no more than " .. config.maxWordLenght .. " letters for each word!"
				break
			elseif(wordCount > config.maxWords) then
				textCancel = "This name contains more than 3 words. Please choose another name!"
				break
			elseif(config.vowelsCheck and string.find(word:lower(), "[aeiouy]") == nil) then
				textCancel = "This name contains a word without vowels. Please choose another name!"
				break
			else
				wordTemp = ''
				for i = 1, len do
					letter = string.sub(word, i, i)
					if(i == 1) then
						if(getBooleanFromString(firstWord) and string.find(letter, "%l")) then
							letter = string.upper(letter)
						end
					else
						if(string.find(letter, "%u")) then
							letter = string.lower(letter)
						end
					end
 
					firstWord = false
					wordTemp = "" .. wordTemp .. "" .. letter .. ""
				end
			end
 
			paramTemp = "" .. paramTemp .. "" .. (paramTemp ~= '' and " " or '') .. "" .. wordTemp .. ""
		end
	end
 
	if(textCancel ~= '') then
		doPlayerSendCancel(cid, textCancel)
		return true
	end
 
	local oldName, guid = getCreatureName(cid), getPlayerGUID(cid)
	t[1] = paramTemp
	doPlayerRemoveItem(cid, config.item.Id, config.item.count)
	if(pcall(doPlayerChangeName, guid, oldName, t[1]) ~= true) then
		db.executeQuery("INSERT INTO `player_namelocks` (`player_id`, `name`, `new_name`, `date`) VALUES (" .. guid .. ", " .. db.escapeString(oldName) .. ", " .. db.escapeString(t[1]) .. ", " .. os.time() .. ");")
		db.executeQuery("UPDATE `players` SET `name` = " .. db.escapeString(t[1]) .. " WHERE `id` = " .. guid .. "" .. limit .. "")
	end
 
	doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your name has been changed successfully." .. (config.kick.enabled and " You will be kicked in " .. config.kick.delay / 1000 .. " seconds." or " Re-enter the game to see the changes.") .. "")
	if(config.kick.enabled) then
		addEvent(function(cid, forceLogout)
			if(isPlayer(cid)) then
				doRemoveCreature(cid, forceLogout)
			end
		end, config.kick.delay, cid, config.forceLogout)
	end
 
	return true
end

v3.0:
Code:
Changelog (v3.0):
Added a second param: force. (/changename name[, force]). It will force the change of the name even if the new name is namelocked (e.g. /changename Player, true).
Removed some useless config values.
Now the script checkes wether TFS has the doPlayerChangeName function using pcall. If it doesn't (0.3.6 or lower) it will use the classic database method.
Added a missing namelock query.
Added a missing limit to a query.
Lua:
local config = {
	item = {
		Id = 1111,
		count = 0,
	},
	maxTextLenght = 15,
	blacklistParam = {"account manager", "god", "cm", "gm", "tutor", "tester"},
	minWordLenght = 3,
	delay = 2
}

function onSay(cid, words, param, channel)
	local textCancel, t = config.text, string.explode(param, ",")
	if(param == '') then
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Command param required.")
	elseif((getPlayerGUIDByName(t[1]) ~= nil) and (not getBooleanFromString(t[2]))) then
		textCancel = "That name is already in use."
	elseif(getPlayerItemCount(cid, config.item.Id) < config.item.count) then
		textCancel = "You do not fulfill the requirements."
	elseif(not getTilePzInfo(getCreaturePosition(cid))) then
		textCancel = "You must be inside a protection zone to use this command."
	elseif(string.len(tostring(t[1])) >= config.maxTextLenght) then
		textCancel = "You can only use a maximum of " .. config.maxTextLenght .. " characters."
	elseif(string.find(t[1]:lower(), "[^%l%s]") ~= nil) then
		textCancel = "You cannot use symbols."
	else
		for blacklist = 1, table.maxn(config.blacklistParam) do
			if(string.find(t[1]:lower(), config.blacklistParam[blacklist]) ~= nil) then
				textCancel = "Invalid name entry."
				break
			end
		end
	end

	if(config.text ~= textCancel) then
		doPlayerSendCancel(cid, textCancel)
		return true
	end

	local paramTemp, space, oldName = '', '', getCreatureName(cid)
	for word in string.gmatch(t[1], "%a+") do
		if(string.len(word) < config.minWordLenght) then
			doPlayerSendCancel(cid, "Each word must have a minimum of " .. config.minWordLenght .. " characters.")
			return true
		end

		paramTemp = "" .. paramTemp .. "" .. space .. "" .. word .. ""
		if(space == '') then
			space = " "
		end
	end

	local guid = getPlayerGUID(cid)
	t[1] = paramTemp
	doPlayerRemoveItem(cid, config.item.Id, config.item.count)
	if(pcall(doPlayerChangeName, guid, oldName, t[1]) == false) then
		db.executeQuery("INSERT INTO `player_namelocks` (`player_id`, `name`, `new_name`, `date`) VALUES (" .. guid .. ", " .. db.escapeString(oldName) .. ", " .. db.escapeString(t[1]) .. ", " .. os.time() .. ");")
		db.executeQuery("UPDATE `players` SET `name` = " .. db.escapeString(t[1]) .. " WHERE `id` = " .. guid .. " LIMIT 1;")
	end

	doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your name has been changed successfully. You will be kicked in " .. config.delay .. " seconds.")
	addEvent(function(cid, forceLogout)
		if(isPlayer(cid)) then
			doRemoveCreature(cid, forceLogout)
		end
	end, config.delay * 1000, cid, false)

	return true
end
v2.0:
Code:
Notes:

If "newMethod" = TRUE then it'll use the new 0.3.7+ function doPlayerChangeName else it'll just use the common db update.
Lua:
local config = {
	text = "Your name has been changed successfully.",
	item = {
		Id = 1111,
		count = 1
	},
	maxTextLenght = 15,
	blacklistParam = {"account manager", "god", "cm", "gm", "tutor", "tester"},
	minWordLenght = 3,
	newMethod = false,
	delay = 2
}

function onSay(cid, words, param, channel)
	local textCancel = config.text
	if(param == '') then
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Command param required.")
	elseif(getPlayerGUIDByName(param) ~= nil) then
		textCancel = "That name is already in use."
	elseif(getPlayerItemCount(cid, config.item.Id) < config.item.count) then
		textCancel = "You do not have enough premium points."
	elseif(not getTilePzInfo(getCreaturePosition(cid))) then
		textCancel = "You must be inside a protection zone to use this command."
	elseif(string.len(tostring(param)) >= config.maxTextLenght) then
		textCancel = "You can only use a maximum of " .. config.maxTextLenght .. " characters."
	elseif(string.find(param:lower(), "[^%l%s]") ~= nil) then
		textCancel = "You cannot use symbols."
	else
		for blacklist = 1, table.maxn(config.blacklistParam) do
			if(string.find(param:lower(), config.blacklistParam[blacklist]) ~= nil) then
				textCancel = "Invalid name entry."
				break
			end
		end
	end

	if(config.text ~= textCancel) then
		doPlayerSendCancel(cid, textCancel)
		return true
	end

	local paramTemp, space, oldName = '', '', getCreatureName(cid)
	for word in string.gmatch(param, "%a+") do
		if(string.len(word) < config.minWordLenght) then
			doPlayerSendCancel(cid, "Each word must have a minimum of " .. config.minWordLenght .. " characters.")
			return true
		end
 
		paramTemp = "" .. paramTemp .. "" .. space .. "" .. word .. ""
		if(space == '') then
			space = " "
		end
	end

	local guid = getPlayerGUID(cid)
	param = paramTemp
	doPlayerRemoveItem(cid, config.item.Id, config.item.count)
	if(config.newMethod == true) then
		doPlayerChangeName(guid, oldName, param)
	else
		db.executeQuery("UPDATE `players` SET `name` = " .. db.escapeString(param) .. " WHERE `id` = " .. guid .. ";")
	end

	doPlayerSendTextMessage(cid, 25, "" .. config.text .. " You will be kicked in " .. config.delay .. " seconds.")
	addEvent(function(cid, forceLogout)
		if(isPlayer(cid)) then
			doRemoveCreature(cid, forceLogout)
		end
	end, config.delay * 1000, cid, false)

	return true
end
 
Last edited:
Lua:
addEvent(function(cid, forceLogout)
	if(isPlayer(cid)) then
		doRemoveCreature(cid, forceLogout)
	end
end, 2 * 1000, cid, true)
or
Before onSay (function "valid" by Mock):
Lua:
function valid(f)
	return function(p,...)
		if isCreature(p) then
			return f(p,...)
		end
	end
end
Lua:
addEvent(valid(doRemoveCreature), 2 * 1000, cid, true)
Else it will print error if the player logs out.
 
Last edited:
A "small" fix...
Lua:
local itemId, count, maxTextLenght, delay = 1111, 1, 15, 2 * 1000
local blacklistParam = {"!", "@", "*", "/", "?",
",", ".", ";", "<", ">", ":", "~", "^", "°", "´",
"`", "[", "{", "ª", "]", "}", "º", "=", "+", "§",
"_", "-", ")", "(", "&", "¨", "¬", "%", "¢", "£",
"$", "#", "¹", "²", "³", "'", "god", "cm", "gm",
"tutor", "tester", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9"}

function onSay(cid, words, param, channel)
	local text, continue = "You will be kicked in 2 seconds.", true
	if(db.getResult("SELECT `name` FROM `players` WHERE `name` = " .. db.escapeString(param) .. ";"):getID() ~= -1) then
		text, continue = "That name is already in use.", false
	elseif(getPlayerItemCount(cid, itemId) < count) then
		text, continue = "You do not have enough premium points.", false
	elseif(not getTilePzInfo(getCreaturePosition(cid))) then
		text, continue = "You must be inside a protection zone to use this command.", false
	elseif(not tostring(param)) then
		text, continue = "Invalid parameter.", false
	elseif(string.len(tostring(param)) > maxTextLenght) then
		text, continue = "You can use a maximum of " .. maxTextLenght .. " characters.", false
	else
		for blacklist = 1, table.maxn(blacklistParam) do
			if(string.find(param:lower(), blacklistParam[blacklist]) ~= nil) then
				text, continue = "You can not use symbols.", false
				break
			end
		end
	end

	if(continue == false) then
		doPlayerSendCancel(cid, text)
		return true
	end

	db.executeQuery("UPDATE `players` SET `name` = " .. db.escapeString(param) .. " WHERE `id` = " .. getPlayerGUID(cid) .. ";")
	doPlayerRemoveItem(cid, itemId, count)
	doPlayerSendTextMessage(cid, 25, text)
	addEvent(function(cid, forceLogout)
		if(isPlayer(cid)) then
			doRemoveCreature(cid, forceLogout)
		end
	end, delay, cid, false)
	return true
end
 
Last edited:
Try removing "god", "cm", "gm", "tutor", "tester" from forbiddenParam and tell me what happens.
 
Just FYI, there are MUCH more symbols to censor out.
Instead of doing so, check if the string contains VALID symbols only. (using patterns)
 
^ Then we would have to put a hell ton of random names in the table :p
 
^ Then we would have to put a hell ton of random names in the table :p

Patterns are a bit like regular expressions, where you can make sure a character is like: [A-Z][a-z]%s // %u%l%s (uppercase, lowercase, space characters).
 
Still we would have to make a forbidden table so that players won't be able to use "god", "gm"... preffix. But well...seems easier like that.
 
Back
Top