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

TFS 1.X+ [TFS 1.3] Block messages like (.biz, .servegame, .no-ip, .sytes.net ....)

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,188
Solutions
34
Reaction score
200
As the title explains, how do I block players from speaking a certain kind of message?
I always see people advertising servers within other servers.
 
Solution
C++:
    std::string lower_text = text;
    std::transform(lower_text.begin(), lower_text.end(), lower_text.begin(), [](unsigned char c){ return std::tolower(c); });
    lower_text.erase(std::remove_if(lower_text.begin(), lower_text.end(), isspace), lower_text.end());

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (lower_text.find(str) != std::string::npos) {
            return;
        }
    }
Try this out, replace the entire Chat::talkToChannel function with this. You can add new blocked messages to the blocked_messages vector as well.
C++:
bool Chat::talkToChannel(const Player& player, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    ChatChannel* channel = getChannel(player, channelId);
    if (!channel) {
        return false;
    }

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (text.find(str) != std::string::npos) {
            return false;
        }
    }

    if (channelId == CHANNEL_GUILD) {
        const GuildRank* rank = player.getGuildRank();
        if (rank && rank->level > 1) {
            type = TALKTYPE_CHANNEL_O;
        } else if (type != TALKTYPE_CHANNEL_Y) {
            type = TALKTYPE_CHANNEL_Y;
        }
    } else if (type != TALKTYPE_CHANNEL_Y && (channelId == CHANNEL_PRIVATE || channelId == CHANNEL_PARTY)) {
        type = TALKTYPE_CHANNEL_Y;
    }

    if (!channel->executeOnSpeakEvent(player, type, text)) {
        return false;
    }

    return channel->talk(player, type, text);
}
 
Try this out, replace the entire Chat::talkToChannel function with this. You can add new blocked messages to the blocked_messages vector as well.
C++:
bool Chat::talkToChannel(const Player& player, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    ChatChannel* channel = getChannel(player, channelId);
    if (!channel) {
        return false;
    }

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (text.find(str) != std::string::npos) {
            return false;
        }
    }

    if (channelId == CHANNEL_GUILD) {
        const GuildRank* rank = player.getGuildRank();
        if (rank && rank->level > 1) {
            type = TALKTYPE_CHANNEL_O;
        } else if (type != TALKTYPE_CHANNEL_Y) {
            type = TALKTYPE_CHANNEL_Y;
        }
    } else if (type != TALKTYPE_CHANNEL_Y && (channelId == CHANNEL_PRIVATE || channelId == CHANNEL_PARTY)) {
        type = TALKTYPE_CHANNEL_Y;
    }

    if (!channel->executeOnSpeakEvent(player, type, text)) {
        return false;
    }

    return channel->talk(player, type, text);
}
Could't be better add this callback(onSay Callback) and do this through Lua? To when needed add new msgs and don't need to recompile?
-I don't tested this callback, just readed about-
 
Could't be better add this callback(onSay Callback) and do this through Lua? To when needed add new msgs and don't need to recompile?
-I don't tested this callback, just readed about-
I don't think you can register a chatchannel script to default channel.

tested but it didn't work, I can still speak the words on the list
View attachment 38294
Try using Game::playerSay instead, remove the changes from the chat function.
C++:
void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type,
                     const std::string& receiver, const std::string& text)
{
    Player* player = getPlayerByID(playerId);
    if (!player) {
        return;
    }

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (text.find(str) != std::string::npos) {
            return;
        }
    }

    player->resetIdleTime();

    if (playerSaySpell(player, type, text)) {
        return;
    }

    uint32_t muteTime = player->isMuted();
    if (muteTime > 0) {
        std::ostringstream ss;
        ss << "You are still muted for " << muteTime << " seconds.";
        player->sendTextMessage(MESSAGE_STATUS_SMALL, ss.str());
        return;
    }

    if (!text.empty() && text.front() == '/' && player->isAccessPlayer()) {
        return;
    }

    if (type != TALKTYPE_PRIVATE_PN) {
        player->removeMessageBuffer();
    }

    switch (type) {
        case TALKTYPE_SAY:
            internalCreatureSay(player, TALKTYPE_SAY, text, false);
            break;

        case TALKTYPE_WHISPER:
            playerWhisper(player, text);
            break;

        case TALKTYPE_YELL:
            playerYell(player, text);
            break;

        case TALKTYPE_PRIVATE_TO:
        case TALKTYPE_PRIVATE_RED_TO:
            playerSpeakTo(player, type, receiver, text);
            break;

        case TALKTYPE_CHANNEL_O:
        case TALKTYPE_CHANNEL_Y:
        case TALKTYPE_CHANNEL_R1:
            g_chat->talkToChannel(*player, type, text, channelId);
            break;

        case TALKTYPE_PRIVATE_PN:
            playerSpeakToNpc(player, text);
            break;

        case TALKTYPE_BROADCAST:
            playerBroadcastMessage(player, text);
            break;

        default:
            break;
    }
}
 
I don't think you can register a chatchannel script to default channel.
worked, but have a "bug"
If the player speaks capital letters, or puts space, he can send a message.
only blocks if it says exactly ".servegame", "www.servegame" and etc
1565805425397.png

edit: this script work, but dont for 1.3, if it could be something like him
 
Last edited:
This will solve it. if (std::tolower(text).find(str) != std::string::npos) {
You can add more things to block yourself, add links without periods, with spaces, etc.
 
This will solve it. if (std::tolower(text).find(str) != std::string::npos) {
You can add more things to block yourself, add links without periods, with spaces, etc.
give this error:
1565806996243.png
would have to add for example:
{. servegame,. servegame,. servegame, ...}?
with one, two, three, .... spaces
 
C++:
    std::string lower_text = text;
    std::transform(lower_text.begin(), lower_text.end(), [](unsigned char c){ return std::tolower(c); });
    lower_text.erase(std::remove_if(lower_text.begin(), lower_text.end(), isspace), lower_text.end());

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (lower_text.find(str) != std::string::npos) {
            return false;
        }
    }

would have to add for example:
{. servegame,. servegame,. servegame, ...}?
with one, two, three, .... spaces
With this, spaces shouldn't matter (they will be removed from the text for the comparisons).
Add #include <cctype> and #include <algorithm> to the top of the file as well, next to the other includes.
 
Last edited:
C++:
    std::string lower_text = text;
    std::transform(lower_text.begin(), lower_text.end(), [](unsigned char c){ return std::tolower(c); });
    lower_text.erase(remove_if(lower_text.begin(), lower_text.end(), isspace), lower_text.end());

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (lower_text.find(str) != std::string::npos) {
            return false;
        }
    }


With this, spaces shouldn't matter (they will be removed from the text for the comparisons).
Add #include <cctype> and #include <algorithm> to the top of the file as well, next to the other includes.
tried but get this error during compilation
1565810498357.png
 
C++:
    std::string lower_text = text;
    std::transform(lower_text.begin(), lower_text.end(), lower_text.begin(), [](unsigned char c){ return std::tolower(c); });
    lower_text.erase(std::remove_if(lower_text.begin(), lower_text.end(), isspace), lower_text.end());

    std::vector<std::string> blocked_messages = {".biz", ".servegame", ".no-ip"};
    for (const std::string& str : blocked_messages) {
        if (lower_text.find(str) != std::string::npos) {
            return;
        }
    }
 
Solution
Back
Top