Отлов определенных слов в чате

valerikov

Участник
Сообщения
4
Реакции
2
Всем привет!

Нашел тут один пример кода который отлавливает слово в чате и автоматом на него отвечает

PHP:
#include <sourcemod>

public OnPluginStart()
{
       AddCommandListener(Command_Say, "say");
       AddCommandListener(Command_Say, "say_team");
}

public Action:Command_Say(client, const String:command[], args)
{
        if (!client)
        {
        return Plugin_Continue;
        }

        decl String:text[192];
        GetCmdArgString(text, 192);

        new startidx = 0;
        if (text[strlen(text)-1] == '"')
        {
        text[strlen(text)-1] = '\0';
        startidx = 1;
        }

        if(StrEqual(text[startidx], "привет")
        || StrEqual(text[startidx], "Привет")
        || StrEqual(text[startidx], "ку")
        || StrEqual(text[startidx], "хай"))
        {
        CreateTimer(0.1, response, client,TIMER_FLAG_NO_MAPCHANGE);
        }
        return Plugin_Continue;
}

public Action:response(Handle:timer, any:client)
{
        if (!client)
        {
        return;
        }
        PrintToChat(client, "\x04[\x01InTeam\x04] Здравствуй дружище)");
}
в принципе он работает, но есть одно но!? если написать в чате "Привет" то он определит это слово, а если написать "Всем привет" то он не поймает это слово.. т.е. получается так что он ловит только одно слово.

Отсюда вопрос. Как сделать чтобы этот скрипт находил нужное нам слово среди других слов?
К примеру "Всем привет ребята!" как бы определяем нужное слово несмотря на другие слова.
..Если конечно такое возможно.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #2
valerikov, http://docs.sourcemod.net/api/index.php?fastload=show&id=615&

Вместо
PHP:
if(StrEqual(text[startidx], "привет") 
        || StrEqual(text[startidx], "Привет") 
        || StrEqual(text[startidx], "ку") 
        || StrEqual(text[startidx], "хай"))

Так:
PHP:
if(StrContains(text[startidx], "привет") != -1
        || StrContains(text[startidx], "Привет") != -1
        || StrContains(text[startidx], "ку") != -1
        || StrContains(text[startidx], "хай") != -1)
 

The Night Fury

Участник
Сообщения
1,300
Реакции
1,395
Где-то осуществлялось через explode, если не ошибаюсь, а где-то по аргументам подбирали. Плагина название, увы, уже не помню. Можно попробовать StrContains.
 

valerikov

Участник
Сообщения
4
Реакции
2
R1KO при таком раскладе он на любой текст реагирует)) только что проверил, даже на цифры. Может чего не хватает к этой функции?

Добавлено через 1 минуту
стоп, вру, я сам не изменил как надо)) ща проверю ещё раз.

Добавлено через 7 минут
В принципе работает, но опять это но... если ввести не просто "привет" а "приветы" он реагирует :lol: если написать не "ку" а тупо "курица" он так же реагирует.. Может есть ещё какие функции?

Добавлено через 26 минут
А может как-то через сравнение строк попробовать? или это тупо?))
 
Последнее редактирование:

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
Где-то осуществлялось через explode, если не ошибаюсь, а где-то по аргументам подбирали. Плагина название, увы, уже не помню. Можно попробовать StrContains.

Explode не оптимальный вариант, причем неизвестно сколько будут пробелов (или другие знаки препинания). Думаю лучше с помощью StrContains получить индекс массива начала слова и затем скопировать содержимое следующих индексов до тех пор, пока не найдет пробел, точку или другие знаки препинания
 

Monroe

Участник
Сообщения
25
Реакции
35
PHP:
new const String:Hello[][] = {"привет", "Привет", "ку", "хай"};

public Action:Command_Say(client, const String:command[], args)
{
	if(!client) return Plugin_Continue;

	decl String:text[192]; GetCmdArgString(text, 192);

	new startidx = 0;
	if(text[strlen(text) - 1] == '"')
	{
		text[strlen(text) - 1] = '\0';
		startidx = 1;
	}

	for(new i = 0; i < sizeof(Hello); i++)
	{
		if(!strcmp(text[startidx], Hello[i]))
		{
			PrintToChat(client, "Здравствуй дружище");
			break;
		}
	}
	
	return Plugin_Continue;
}

Можно так попробовать
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #7
Minus, это почти то же самое, что и его 1-й вариант, только более оптимизированый. Проблему это не решает.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #8
Minus, да, но не решает эту:

Отсюда вопрос. Как сделать чтобы этот скрипт находил нужное нам слово среди других слов?
К примеру "Всем привет ребята!" как бы определяем нужное слово несмотря на другие слова.
..Если конечно такое возможно.
 

semjef

semjef.ru
Сообщения
993
Реакции
444
В таком случае используйте идею FrozDark,
только желательно будет если индекс начального символа у нас не 0, то проверять предыдущую букву.
 

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
Решает эту проблему

Реагирует только на значения в массиве

так его код под спойлером в первом посте и есть то, что ты сделал

накидал код того, что имел ввиду
PHP:
new const String:Hello[][] = {"привет", "Привет", "ку", "хай"}; 

public Action:Command_Say(client, const String:command[], args) 
{ 
    if(!client) return Plugin_Continue; 

    decl String:text[192]; GetCmdArgString(text, 192); 

	new index = -1;
	decl String:word[32];
    for(new i = 0; i < sizeof(Hello); i++) 
    { 
		if ((index = StrContains(text, Hello[i], false)) == -1) continue;
		
		new c = 0;
		while (text[index] != '\0' && text[index] != '\'' && text[index] != '"' && text[index] != '[' && text[index] != '{' && text[index] != ']' && text[index] != '}' && text[index] != '\\' && text[index] != '/' && text[index] != '|' && text[index] != ' ' && text[index] != '.' && text[index] != '?' && text[index] != '!' && text[index] != '(' && text[index] != ')' && text[index] != '_' && text[index] != '-' && text[index] != '+' && !IsCharNumeric(text[index]))
		{
			word[c++] = text[index++];
		}
		word[c] = '\0';
		
        if(!strcmp(word, Hello[i], false)) 
        { 
            PrintToChat(client, "Здравствуй дружище"); 
            break; 
        } 
    } 
     
    return Plugin_Continue; 
}
 
Последнее редактирование:

semjef

semjef.ru
Сообщения
993
Реакции
444
FrozDark, предыдущий символ ещё проверяй, если не index больше 0, иначе среагирует на любое слово оканчивающееся на "ку"
 

Monroe

Участник
Сообщения
25
Реакции
35
PHP:
#include <sourcemod>
#include <regex>

new const String:Hello[][] = {"привет", "Привет", "ку", "хай"};
new const String:Exclude[] = "[^А-Яа-яA-Za-z0-9]";

public OnPluginStart()
{
   AddCommandListener(Command_Say, "say");
   AddCommandListener(Command_Say, "say_team");
}

public Action:Command_Say(client, const String:command[], args)
{
	if(!client) return Plugin_Continue;

	decl String:text[192]; GetCmdArgString(text, 192);

	new startidx = 0;
	if(text[strlen(text) - 1] == '"')
	{
		text[strlen(text) - 1] = '\0';
		startidx = 1;
	}
	
	decl String:pattern[128];
	for(new i = 0; i < sizeof(Hello); i++)
	{
		FormatEx(pattern, sizeof(pattern), "(%s|^)%s((%s)|$)", Exclude, Hello[i], Exclude);
		
		if(SimpleRegexMatch(text[startidx], pattern) > 0)
		{					
			PrintToChat(client, "Здравствуй дружище");
			break;
		}
	}	
	
	return Plugin_Continue;
}

Так попробуйте

Добавлено через 4 часа 38 минут
PHP:
#include <sourcemod>
#include <regex>

new const String:Hello[][] = {"привет", "Привет", "ку", "хай"};
new const String:Exclude[] = "[^А-Яа-яA-Za-z0-9]";

public OnPluginStart() HookEvent("player_say", OnPlayerSay);

public OnPlayerSay(Handle:event, const String:name[], bool:dontBroadcast)
{
	decl String:text[192], String:pattern[128]; GetEventString(event, "text", text, sizeof(text));
	for(new i = 0; i < sizeof(Hello); i++)
	{
		FormatEx(pattern, sizeof(pattern), "(%s|^)%s(%s|$)", Exclude, Hello[i], Exclude);
		if(SimpleRegexMatch(text, pattern) > 0)
		{
			PrintToChat(GetClientOfUserId(GetEventInt(event, "userid")), "Здравствуй дружище");
			break;
		}
	}
}
Я бы еще сделал так
 
Последнее редактирование:

valerikov

Участник
Сообщения
4
Реакции
2
накидал код того, что имел ввиду
Я проверил и ваш пример не реагирует.. вообще тишина.

PHP:
#include <sourcemod>
#include <regex>

new const String:Hello[][] = {"привет", "Привет", "ку", "хай"};
new const String:Exclude[] = "[^А-Яа-яA-Za-z0-9]";

public OnPluginStart()
{
   AddCommandListener(Command_Say, "say");
   AddCommandListener(Command_Say, "say_team");
}

public Action:Command_Say(client, const String:command[], args)
{
	if(!client) return Plugin_Continue;

	decl String:text[192]; GetCmdArgString(text, 192);

	new startidx = 0;
	if(text[strlen(text) - 1] == '"')
	{
		text[strlen(text) - 1] = '\0';
		startidx = 1;
	}
	
	decl String:pattern[128];
	for(new i = 0; i < sizeof(Hello); i++)
	{
		FormatEx(pattern, sizeof(pattern), "(%s|^)%s((%s)|$)", Exclude, Hello[i], Exclude);
		
		if(SimpleRegexMatch(text[startidx], pattern) > 0)
		{					
			PrintToChat(client, "Здравствуй дружище");
			break;
		}
	}	
	
	return Plugin_Continue;
}

Так попробуйте

Добавлено через 4 часа 38 минут
PHP:
#include <sourcemod>
#include <regex>

new const String:Hello[][] = {"привет", "Привет", "ку", "хай"};
new const String:Exclude[] = "[^А-Яа-яA-Za-z0-9]";

public OnPluginStart() HookEvent("player_say", OnPlayerSay);

public OnPlayerSay(Handle:event, const String:name[], bool:dontBroadcast)
{
	decl String:text[192], String:pattern[128]; GetEventString(event, "text", text, sizeof(text));
	for(new i = 0; i < sizeof(Hello); i++)
	{
		FormatEx(pattern, sizeof(pattern), "(%s|^)%s(%s|$)", Exclude, Hello[i], Exclude);
		if(SimpleRegexMatch(text, pattern) > 0)
		{
			PrintToChat(GetClientOfUserId(GetEventInt(event, "userid")), "Здравствуй дружище");
			break;
		}
	}
}
Я бы еще сделал так

А вот эти два примера работают как надо)) второй даже компактней.
Спасибо всем!
 

Konstantin

Участник
Сообщения
1,775
Реакции
759
А как добавить разные ответы на разные сообщения? Например: на "Привет" отвечает "Здравствуй, дружище", а на ":D" или ": )" — "Что смешного?"
 

DanZa

Участник
Сообщения
82
Реакции
11
@R1KO а возможно сделать что-бы при определённом тексте, от игрока выполнялась команда, например когда игрок пишет в чат like, у него в консоли выполнялась команда sm_like?
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
@R1KO а возможно сделать что-бы при определённом тексте, от игрока выполнялась команда, например когда игрок пишет в чат like, у него в консоли выполнялась команда sm_like?
Причем тут Рико?

И да можно так сделать
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Просто решил обратиться к нему
C-подобный:
HookEvent("player_say", PlayerSay);

public Action PlayerSay(Event hEvent, const char[] sEvent, bool bdb)
{
    int client = GetClientOfUserId(hEvent.GetInt("userid"));
    char text[256];
    hEvent.GetString("text", text, sizeof(text));
 
    if(0 < client <= MaxClients && IsClientInGame(client))
        if(strcmp(text, "like", true) == 0)
            ClientCommand(client, "sm_like");
    return Plugin_Continue;
}
 
Последнее редактирование:

DanZa

Участник
Сообщения
82
Реакции
11
C-подобный:
HookEvent("player_say", PlayerSay);

public Action PlayerSay(Event hEvent, const char[] sEvent, bool bdb)
{
    int client = GetClientOfUserId(hEvent.GetInt("userid"));
    char text[256];
    hEvent.GetString("text", text, sizeof(text));
 
    if(0 < client <= MaxClients && IsClientInGame(client) && bCanSend)
        if(strcmp(text, "like", true) == 0)
            ClientCommand(client, "sm_like");
    return Plugin_Continue;
}
Спасибо, но)))
ошибка:
//SourceMod Batch Compiler
// by the SourceMod Dev Team


//// sayrank.sp
//
// C:\Users\kvolo\Desktop\scripting\sayrank.sp(2) : error 021: symbol already defined: "HookEvent"
// C:\Users\kvolo\Desktop\scripting\sayrank.sp(10) : error 017: undefined symbol "bCanSend"
//
// 2 Errors.
//
// Compilation Time: 0,14 sec
// ----------------------------------------

Press enter to exit ...
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Спасибо, но)))
ошибка:
//SourceMod Batch Compiler
// by the SourceMod Dev Team


//// sayrank.sp
//
// C:\Users\kvolo\Desktop\scripting\sayrank.sp(2) : error 021: symbol already defined: "HookEvent"
// C:\Users\kvolo\Desktop\scripting\sayrank.sp(10) : error 017: undefined symbol "bCanSend"
//
// 2 Errors.
//
// Compilation Time: 0,14 sec
// ----------------------------------------

Press enter to exit ...
C-подобный:
public void OnPluginStart()
{
    HookEvent("player_say", PlayerSay);
}

public Action PlayerSay(Event hEvent, const char[] sEvent, bool bdb)
{
    int client = GetClientOfUserId(hEvent.GetInt("userid"));
    char text[256];
    hEvent.GetString("text", text, sizeof(text));
 
    if(0 < client <= MaxClients && IsClientInGame(client))
        if(strcmp(text, "like", true) == 0)
            ClientCommand(client, "sm_like");
    return Plugin_Continue;
}
 
Сверху Снизу