• 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 Help Script channel

Fortera Global

Intermediate OT User
Joined
Nov 20, 2015
Messages
1,180
Solutions
2
Reaction score
117
Hello, I'm trying to make an script to appear [Staff] before the nick if the player are Account tutor, could someone help?

tfs 1.2

Script:
Lua:
local CHANNEL_HELP = 7

local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT)
muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_HELP)
muted:setParameter(CONDITION_PARAM_TICKS, 3600000)

local exhausted = createConditionObject(CONDITION_CHANNELMUTEDTICKS)
setConditionParam(exhausted, CONDITION_PARAM_SUBID, CHANNEL_HELP)
setConditionParam(exhausted, CONDITION_PARAM_TICKS, 120000)

function onSpeak(player, type, message)
    local playerAccountType = player:getAccountType()
    if player:getLevel() <= 100 and playerAccountType == ACCOUNT_TYPE_NORMAL then
        player:sendCancelMessage("You may not speak into channels if you are level less than 100.")
        return false
    end

     if(getCreatureCondition(player, CONDITION_CHANNELMUTEDTICKS, CHANNEL_HELP)) and playerAccountType == ACCOUNT_TYPE_NORMAL then
         player:sendCancelMessage("You may only ask a question once every 2 minutes.")
            return false
        end
 
    if getPlayerGroupId(player) <= 1 then
        doAddCondition(player, exhausted)
    end
  
    if player:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
        player:sendCancelMessage("You are muted from the Help channel for using it inappropriately.")
        return false
    end

    if playerAccountType >= ACCOUNT_TYPE_TUTOR then
        if string.sub(message, 1, 6) == "!mute " then
            local targetName = string.sub(message, 7)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if not target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                        target:addCondition(muted)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been muted by " .. player:getName() .. " for using Help Channel inappropriately.")
                    else
                        player:sendCancelMessage("That player is already muted.")
                    end
                else
                    player:sendCancelMessage("You are not authorized to mute that player.")
                end
            else
                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        elseif string.sub(message, 1, 8) == "!unmute " then
            local targetName = string.sub(message, 9)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                        target:removeCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been unmuted by " .. player:getName() .. ".")
                    else
                        player:sendCancelMessage("That player is not muted.")
                    end
                else
                    player:sendCancelMessage("You are not authorized to unmute that player.")
                end
            else
                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        end
    -- HERE 
        local info = "Staff"
        sendChannelMessage(10, type, player:getName() .. " [" .. info .. "]: " .. message)
    end

    if type == TALKTYPE_CHANNEL_Y then

        if playerAccountType == ACCOUNT_TYPE_TUTOR then
            type = TALKTYPE_CHANNEL_O

            elseif playerAccountType >= ACCOUNT_TYPE_SENIORTUTOR then

            type = TALKTYPE_CHANNEL_O
        end
    elseif type == TALKTYPE_CHANNEL_O then
 
        if playerAccountType < ACCOUNT_TYPE_TUTOR and not getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
            type = TALKTYPE_CHANNEL_Y

        end
    elseif type == TALKTYPE_CHANNEL_O then

        if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not getPlayerFlagValue(player, PlayerFlag_CanTalkRedChannel) then

            if playerAccountType >= ACCOUNT_TYPE_TUTOR or getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then

                type = TALKTYPE_CHANNEL_O
            else

                type = TALKTYPE_CHANNEL_Y
            end
        end
    end
    return type
end
 
Last edited by a moderator:
I tried to modify a constant value, lol, I'm newbie sorry:

Just try this:
C++:
void sendChannelMessage(const std::string& author, const std::string& text, SpeakClasses type, uint16_t channel) {
    if (client) {
        if (this->getAccountType() == ACCOUNT_TYPE_GOD) {
            const std::string& newAuthor = "[God] " + author;
            client->sendChannelMessage(newAuthor, text, type, channel);
        } else if (this->getAccountType() == ACCOUNT_TYPE_GOD) {
            const std::string& newAuthor = "[Tutor] " + author;
            client->sendChannelMessage(newAuthor, text, type, channel);
        } else {
            client->sendChannelMessage(author, text, type, channel);
        }
    }
}

Thanks again. You are not noob, I'm noob.... this compiled now but dont appear on channels, look (I tested with tutor and God):
SOIi0tj.png
 
Try this

Code:
local CHANNEL_HELP = 7

local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT)
muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_HELP)
muted:setParameter(CONDITION_PARAM_TICKS, 3600000)

local exhausted = createConditionObject(CONDITION_CHANNELMUTEDTICKS)
setConditionParam(exhausted, CONDITION_PARAM_SUBID, CHANNEL_HELP)
setConditionParam(exhausted, CONDITION_PARAM_TICKS, 30000)

function onSpeak(player, type, message)
    local playerAccountType = player:getAccountType()
    if player:getLevel() <= 3 and playerAccountType == ACCOUNT_TYPE_NORMAL then
        player:sendCancelMessage("You may not speak into channels as long as you are on level 3.")
        return false
    end
    local tutor = "Tutor"
    local Adm = ""
    type = TALKTYPE_CHANNEL_O


    if player:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
        player:sendCancelMessage("You are muted from the Help channel for using it inappropriately.")
        return false
    end

    if(getCreatureCondition(player, CONDITION_CHANNELMUTEDTICKS, CHANNEL_HELP)) and playerAccountType == ACCOUNT_TYPE_NORMAL then
        player:sendCancelMessage("You may only ask a question once every 30 seconds.")
        return false
    end

    if player:getGroup():getId() <= 1 then
        player:addCondition(exhausted)
    end

    if playerAccountType >= ACCOUNT_TYPE_TUTOR then
       
        if string.match(message, "!mute") then
           
            local targetName = string.sub(message, 7)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if not target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                      
                        target:addCondition(muted)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been muted by " .. player:getName() .. " for using Help Channel inappropriately.")
                    else
                        player:sendCancelMessage("That player is already muted.")
                    end
                else
                   
                    player:sendCancelMessage("You are not authorized to mute that player.")
                end
            else

                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        elseif string.sub(message, 1, 8) == "!unmute " then
            local targetName = string.sub(message, 9)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                        target:removeCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been unmuted by " .. player:getName() .. ".")
                    else
                        player:sendCancelMessage("That player is not muted.")
                    end
                else
                    player:sendCancelMessage("You are not authorized to unmute that player.")
                end
            else
                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        end
    end

    if type == TALKTYPE_CHANNEL_Y then
        if playerAccountType >= ACCOUNT_TYPE_TUTOR or getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
            type = TALKTYPE_CHANNEL_O
            if playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then
                type = TALKTYPE_CHANNEL_R1
            end
        end
    elseif type == TALKTYPE_CHANNEL_O then
        if playerAccountType < ACCOUNT_TYPE_TUTOR and not getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
            type = TALKTYPE_CHANNEL_Y
        end
    elseif type == TALKTYPE_CHANNEL_R1 then
        if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not getPlayerFlagValue(player, PlayerFlag_CanTalkRedChannel) then
            if playerAccountType >= ACCOUNT_TYPE_TUTOR or getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
                type = TALKTYPE_CHANNEL_O
            else
                type = TALKTYPE_CHANNEL_Y
            end
        end
    end

    if playerAccountType == ACCOUNT_TYPE_TUTOR then
        sendChannelMessage(CHANNEL_HELP, type, "[" .. tutor .. "] " .. player:getName() .. " [" .. player:getLevel() .."] : " .. message)
        return false
    elseif playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then
        type = TALKTYPE_CHANNEL_R1
        sendChannelMessage(CHANNEL_HELP, type, "" .. Adm .. "" .. player:getName() .. ": ".. message)
        return false
    else
        type = TALKTYPE_CHANNEL_Y
        sendChannelMessage(CHANNEL_HELP, type, player:getName() .. " [" .. player:getLevel() .."] : " .. message)
        return false
    end

    return true
end

Credits Xeraphus
 
Thanks again. You are not noob, I'm noob.... this compiled now but dont appear on channels, look (I tested with tutor and God):
Look at:
forgottenserver/protocolgame.cpp at 0cf1f267bf1a0f83a9d3ed91b466472f4fd4629d · otland/forgottenserver · GitHub

Change to:
C++:
void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (!creature) {
        msg.add<uint32_t>(0x00);
    } else if (type == TALKTYPE_CHANNEL_R2) {
        msg.add<uint32_t>(0x00);
        type = TALKTYPE_CHANNEL_R1;
    } else {
        const Player* speaker = creature->getPlayer();
        if (speaker) {
            std::string playerName = speaker->getName();
            if (speaker->accountType == ACCOUNT_TYPE_GOD) {
                playerName = "[God] " + speaker->getName();
            } else if (speaker->accountType == ACCOUNT_TYPE_TUTOR) {
                playerName = "[Tutor] " + speaker->getName();
            }

            msg.addString(playerName);
            msg.add<uint16_t>(speaker->getLevel());
        } else {
            msg.addString(creature->getName());
            msg.add<uint16_t>(0x00);
        }
    }

    msg.addByte(type);
    msg.add<uint16_t>(channelId);
    msg.addString(text);
    writeToOutputBuffer(msg);
}

And ignore previous changes.
 
Try this

Code:
local CHANNEL_HELP = 7

local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT)
muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_HELP)
muted:setParameter(CONDITION_PARAM_TICKS, 3600000)

local exhausted = createConditionObject(CONDITION_CHANNELMUTEDTICKS)
setConditionParam(exhausted, CONDITION_PARAM_SUBID, CHANNEL_HELP)
setConditionParam(exhausted, CONDITION_PARAM_TICKS, 30000)

function onSpeak(player, type, message)
    local playerAccountType = player:getAccountType()
    if player:getLevel() <= 3 and playerAccountType == ACCOUNT_TYPE_NORMAL then
        player:sendCancelMessage("You may not speak into channels as long as you are on level 3.")
        return false
    end
    local tutor = "Tutor"
    local Adm = ""
    type = TALKTYPE_CHANNEL_O


    if player:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
        player:sendCancelMessage("You are muted from the Help channel for using it inappropriately.")
        return false
    end

    if(getCreatureCondition(player, CONDITION_CHANNELMUTEDTICKS, CHANNEL_HELP)) and playerAccountType == ACCOUNT_TYPE_NORMAL then
        player:sendCancelMessage("You may only ask a question once every 30 seconds.")
        return false
    end

    if player:getGroup():getId() <= 1 then
        player:addCondition(exhausted)
    end

    if playerAccountType >= ACCOUNT_TYPE_TUTOR then
     
        if string.match(message, "!mute") then
         
            local targetName = string.sub(message, 7)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if not target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                    
                        target:addCondition(muted)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been muted by " .. player:getName() .. " for using Help Channel inappropriately.")
                    else
                        player:sendCancelMessage("That player is already muted.")
                    end
                else
                 
                    player:sendCancelMessage("You are not authorized to mute that player.")
                end
            else

                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        elseif string.sub(message, 1, 8) == "!unmute " then
            local targetName = string.sub(message, 9)
            local target = Player(targetName)
            if target ~= nil then
                if playerAccountType > target:getAccountType() then
                    if target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then
                        target:removeCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP)
                        sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been unmuted by " .. player:getName() .. ".")
                    else
                        player:sendCancelMessage("That player is not muted.")
                    end
                else
                    player:sendCancelMessage("You are not authorized to unmute that player.")
                end
            else
                player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
            end
            return false
        end
    end

    if type == TALKTYPE_CHANNEL_Y then
        if playerAccountType >= ACCOUNT_TYPE_TUTOR or getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
            type = TALKTYPE_CHANNEL_O
            if playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then
                type = TALKTYPE_CHANNEL_R1
            end
        end
    elseif type == TALKTYPE_CHANNEL_O then
        if playerAccountType < ACCOUNT_TYPE_TUTOR and not getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
            type = TALKTYPE_CHANNEL_Y
        end
    elseif type == TALKTYPE_CHANNEL_R1 then
        if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not getPlayerFlagValue(player, PlayerFlag_CanTalkRedChannel) then
            if playerAccountType >= ACCOUNT_TYPE_TUTOR or getPlayerFlagValue(player, PlayerFlag_TalkOrangeHelpChannel) then
                type = TALKTYPE_CHANNEL_O
            else
                type = TALKTYPE_CHANNEL_Y
            end
        end
    end

    if playerAccountType == ACCOUNT_TYPE_TUTOR then
        sendChannelMessage(CHANNEL_HELP, type, "[" .. tutor .. "] " .. player:getName() .. " [" .. player:getLevel() .."] : " .. message)
        return false
    elseif playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then
        type = TALKTYPE_CHANNEL_R1
        sendChannelMessage(CHANNEL_HELP, type, "" .. Adm .. "" .. player:getName() .. ": ".. message)
        return false
    else
        type = TALKTYPE_CHANNEL_Y
        sendChannelMessage(CHANNEL_HELP, type, player:getName() .. " [" .. player:getLevel() .."] : " .. message)
        return false
    end

    return true
end

Credits Xeraphus


Hello, thanks, this worked but we can't click to Copy name, add to vip or other options, this show only 2 options, look:

K0swPLK.png


the correct is (Here does not show add vip, ignore,etc.. why I even sent this msg):
BCawR6P.png


thanks
 
Look at:
forgottenserver/protocolgame.cpp at 0cf1f267bf1a0f83a9d3ed91b466472f4fd4629d · otland/forgottenserver · GitHub

Change to:
C++:
void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (!creature) {
        msg.add<uint32_t>(0x00);
    } else if (type == TALKTYPE_CHANNEL_R2) {
        msg.add<uint32_t>(0x00);
        type = TALKTYPE_CHANNEL_R1;
    } else {
        const Player* speaker = creature->getPlayer();
        if (speaker) {
            std::string playerName = speaker->getName();
            if (speaker->accountType == ACCOUNT_TYPE_GOD) {
                playerName = "[God] " + speaker->getName();
            } else if (speaker->accountType == ACCOUNT_TYPE_TUTOR) {
                playerName = "[Tutor] " + speaker->getName();
            }

            msg.addString(playerName);
            msg.add<uint16_t>(speaker->getLevel());
        } else {
            msg.addString(creature->getName());
            msg.add<uint16_t>(0x00);
        }
    }

    msg.addByte(type);
    msg.add<uint16_t>(channelId);
    msg.addString(text);
    writeToOutputBuffer(msg);
}

And ignore previous changes.
thanks I'll test :p
 
Humm, I understand, have solution for this? The options disappear from normal players too
if the author name is changed and the new name doesn't correlate to an actual player, the options wont show up
there's probably a way to change this somewhere in sources to trim string and look for a valid player name at the beginning, but i'd have no idea where to look
 
Back
Top