Перейти к содержанию
Авторизация  
SHOROOP

Решение проблемы "команды не в той раскладке" (OnPlayerCommandText и OnPlayerText, строка как массив и пр.)

Рекомендуемые сообщения

Vlad_Miroshnicov

Доброй ночи.

 

Итак, сегодня мы рассмотрим простейшую ситуацию, которая поможет нам ответить на несколько вопросов:

- в какой коллбэк и почему уходит любое сообщение, написанное в чат;

- почему со строкой можно работать абсолютно так же, как и с массивом.

 

Разберем ситуацию на примере.

Бывают такие случаи, когда игрок по ошибке забыл переключить раскладку клавиатуры на английскую и при попытке ввода команды получает что-то вроде ".ксщт дщпшт зфыыцщкв" вместо "/rcon login password". Это, конечно, происходит исключительно по невнимательности, но - не есть хорошо.

Как можно предусмотреть такую ситуацию? Ответ прост и просится сам - первым символом ошибочного сообщения будет точка, вторым - любой другой, кроме точки. Это очевидно - точка в русской раскладке и слэш - в английской находятся на одной и той же кнопке. Само собой разумеется, что можно эту ситуацию проконтролировать. Но как?

 

Первоначально - проследим путь отправленной строки в чат.

Клиент парсит введенную строку и проверяет первый символ. Это слэш? Отлично, строка отправится в OnPlayerCommandText и будет обрабатываться уже этой функцией. Не слэш? Значит, строка командой не является и ее нужно отправить в другой коллбэк - OnPlayerText. В этом и заключается разница между строкой-командой и строкой-текстом для клиента.

 

Итак, коллбэк для отслеживания подобных опечаток мы определили, это OnPlayerText (playerid, text[]). Но как отследить, какие первые два символа в переданной строке text[]?

Конечно, можно воспользоваться функцией работы с текстом strcmp и отследить эту самую точку, подобрав нужные параметры. Но это - изобретение велосипеда с квадратными колесами.

Каждая строка (не только в Pawn, во многих других ЯП) - является массивом символов, каждый элемент этого массива хранит в себе ASCII-код нужного символа. Соответственно, если строка - массив, то и работать в ней можно абсолютно так же.

Прямо в начале тела коллбэка проверяем первые два символа - text[0] и text[1]. Значение text[0] соответствует точке, а значение text[1] - нет? Наш случай! Выводим игроку сообщение об опечатке и, дабы текст не синхронизировался с остальными игроками, вернем false как результат обработки строки.

public OnPlayerText(playerid, text[])
{
   if (text[0] == '.' && text[1] != '.') //Можно и по-другому. ASCII-код точки - 46, сравниваем напрямую: if (text[0] == 46 && text[1] != 46)
   {
      SendClientMessage (playerid, -1, "Проверьте раскладку клавиатуры.");
      return false;
   }
  //Остальной код обработки коллбэка будет уже для каждого свой.
}

Результат работы будет выглядеть примерно так.

32a4ec52df363f82c2d5a118cf74e822.png315d509c0a6b9599d1e5528234bda0a1.png

 

Пусть решение вышло в три строки кода, но оно является хорошим примером, на котором можно разобрать как разницу между командой и текстом, так и методы работы со строкой как с массивом.

 

Решение авторское, перепост разрешен только с моего согласия и указания меня как автора.

ммм... даже не чего, мне понравилось!

Изменено пользователем Vlad_Andreev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
SHOROOP

ммм... даже не чего, мне понравилось!

Дело не в "даже не чего", а в том, чтобы юзеры наконец уяснили две простые вещи - разницу между командой и строкой и то, что строка - это массив и работать с ней можно аналогично.
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Vlad_Miroshnicov

 

ммм... даже не чего, мне понравилось!

Дело не в "даже не чего", а в том, чтобы юзеры наконец уяснили две простые вещи - разницу между командой и строкой и то, что строка - это массив и работать с ней можно аналогично.

 

+ согласен с тобой полностью!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Flaymeek

Доброй ночи.

 

Итак, сегодня мы рассмотрим простейшую ситуацию, которая поможет нам ответить на несколько вопросов:

- в какой коллбэк и почему уходит любое сообщение, написанное в чат;

- почему со строкой можно работать абсолютно так же, как и с массивом.

 

Разберем ситуацию на примере.

Бывают такие случаи, когда игрок по ошибке забыл переключить раскладку клавиатуры на английскую и при попытке ввода команды получает что-то вроде ".ксщт дщпшт зфыыцщкв" вместо "/rcon login password". Это, конечно, происходит исключительно по невнимательности, но - не есть хорошо.

Как можно предусмотреть такую ситуацию? Ответ прост и просится сам - первым символом ошибочного сообщения будет точка, вторым - любой другой, кроме точки. Это очевидно - точка в русской раскладке и слэш - в английской находятся на одной и той же кнопке. Само собой разумеется, что можно эту ситуацию проконтролировать. Но как?

 

Первоначально - проследим путь отправленной строки в чат.

Клиент парсит введенную строку и проверяет первый символ. Это слэш? Отлично, строка отправится в OnPlayerCommandText и будет обрабатываться уже этой функцией. Не слэш? Значит, строка командой не является и ее нужно отправить в другой коллбэк - OnPlayerText. В этом и заключается разница между строкой-командой и строкой-текстом для клиента.

 

Итак, коллбэк для отслеживания подобных опечаток мы определили, это OnPlayerText (playerid, text[]). Но как отследить, какие первые два символа в переданной строке text[]?

Конечно, можно воспользоваться функцией работы с текстом strcmp и отследить эту самую точку, подобрав нужные параметры. Но это - изобретение велосипеда с квадратными колесами.

Каждая строка (не только в Pawn, во многих других ЯП) - является массивом символов, каждый элемент этого массива хранит в себе ASCII-код нужного символа. Соответственно, если строка - массив, то и работать в ней можно абсолютно так же.

Прямо в начале тела коллбэка проверяем первые два символа - text[0] и text[1]. Значение text[0] соответствует точке, а значение text[1] - нет? Наш случай! Выводим игроку сообщение об опечатке и, дабы текст не синхронизировался с остальными игроками, вернем false как результат обработки строки.

public OnPlayerText(playerid, text[])
{
   if (text[0] == '.' && text[1] != '.') //Можно и по-другому. ASCII-код точки - 46, сравниваем напрямую: if (text[0] == 46 && text[1] != 46)
   {
      SendClientMessage (playerid, -1, "Проверьте раскладку клавиатуры.");
      return false;
   }
  //Остальной код обработки коллбэка будет уже для каждого свой.
}

Результат работы будет выглядеть примерно так.

32a4ec52df363f82c2d5a118cf74e822.png315d509c0a6b9599d1e5528234bda0a1.png

 

Пусть решение вышло в три строки кода, но оно является хорошим примером, на котором можно разобрать как разницу между командой и текстом, так и методы работы со строкой как с массивом.

 

Решение авторское, перепост разрешен только с моего согласия и указания меня как автора.

Огромное спасибо,много раз такое было.Раньше даже не додумался...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
#GiFF

полезная тема. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Frozen Man

Полезная вещь, плюс дал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
FVCKFISH

Довольно хорошо объяснил на словах, лайк) 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Predator

Кхм...полезная штука + твой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Гость
Эта тема закрыта для публикации ответов.
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.