Русское сообщество по скриптингу

(Неактуально) Использование возможностей motd_write

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

(Неактуально) Использование возможностей motd_write

Сообщение DJ_WEST » 27 сен 2009, 23:08

Автор: DJ_WEST

Хочу рассказать Вам о моем способе использования клиентских возможностей для работы с MOTD файлом. Всего существует три команды:
  • motdfile - команда, указывающая какой MOTD файл отображается при соединении к серверу, то есть используется в основном для сервера. По умолчанию: motd.txt.
  • motd_write - команда, используемая для записи текстовой информации в MOTD файл, который указан в motdfile.
  • motd - команда, используемая для отображения содержимого MOTD файла, указанного в motdfile, в консоль клиента.

Для наших целей мы будем использовать только две первые команды, а именно motdfile и motd_write. Существует ряд ограничений при использовании данных команд:
  • Мы можем использовать файлы только в пределах папки мода, в нашем случае cstrike. Использовать вложенные каталоги в cstrike можно, а выйти на уровень выше - нет. Другими словами, мы можем использовать в качестве MOTD файлы из директории cstrike/models или cstrike/sprites, но не файлы, которые за пределами cstrike директории.
  • Мы не можем использовать для motd_write некоторые типы файлов, такие как: exe, dll, cfg, rc, com, bat (возможно и другие, я указал те, о которых мне известно).
  • Мы не можем записывать файл в директорию, которая не существует в cstrike на клиенте. Другими словами, если мы хотим записать файл в cstrike/test/test.txt и у игрока нет директории cstrike/test, то ничего не выйдет.
  • Записывая данные через motd_write в файл, который уже существует, мы удаляем его содержимое полностью, заменяя своими данными. Другими словами, дописать в файл информацию нельзя.
  • Через motd_write мы можем записать максимум 1012 байт информации.

Итак, получается, что мы можем записать через motd_write 1012 байт информации, но как записать информацию в несколько строк? Потому что новый абзац в motd_write считается концом, тем самым обрывается дальнейшая запись строки. Не беда, я расскажу, как можно записать информацию в несколько строк и что нам это даст в практическом использовании.

Прежде всего помните, что через motd_write можно нарушить целостность игры клиента: повредить bsp карту, повредить mdl модель, повредить liblist.gam или какие-то другие важные файлы игры. Поэтому используйте возможности данной команды на своем сервере на свой страх и риск. Вы должны понимать результат своих действий.

К примеру, выполняя данный код:
Код: Выделить всё
// Указываем файл, который будет использоваться (cstrike/models/amx-x.mdl)
client_cmd(id, "motdfile models/amx-x.mdl")
// Записываем текст Example в файл
client_cmd(id, "motd_write Example")
// Возвращаем значение команды motdfile по умолчанию
client_cmd(id, "motdfile motd.txt")
 

В результате у игрока в директории cstrike/models появится новый файл amx-x.mdl с содержимым Example. Ясно, что данная модель работать не будет и использовать мы ее не сможем. Потому что модели имеют сложное содержимое, которое даже свыше допустимых 1012 байт.

Сейчас попробуем разобраться, как записать в файл данные в несколько строк. Для удобства воспользуемся бесплатным текстовым редактором Notepad++. Чтобы видеть скрытые символы в тексте нужно в меню программы выбрать "Вид" - "Отображение символов" - "Все символы". Теперь открыв какой-нибудь текстовый файл мы увидем такие символы, как CR LF, которые означают новую строку.
  • LF: подача строки (ALT + 010)
  • CR: возврат каретки (ALT + 013)
Теперь если мы в файле будем считывать информацию, где содержатся символы CR LF и передавать данную информацию через client_cmd(id, motd_write ...), то запись оборвется, как будут найдены символы CR LF, то есть движок игры не разрешает выполнить то, что мы хотим. Но если мы будем вместо CR LF использовать только символ CR, то запись пройдет успешно и фактически редакторы будут понимать, что это новая строка, кроме обычного Notepad. Главное, что движок игры будет понимать, что это новая строка. Почему главное? Сейчас рассмотрим пример, как добавить опцию подключения к вашему серверу в меню игрока игры Counter-Strike 1.6!
За меню игры отвечает файл cstrike/resource/GameMenu.res.
По умолчанию он имеет такой вид (взято из Steam версии игры):
Код: Выделить всё

"GameMenu"
{
   "1"
   {
      "label" "#GameUI_GameMenu_ResumeGame"
      "command" "ResumeGame"
      "OnlyInGame" "1"
   }
   "2"
   {
      "label" "#GameUI_GameMenu_Disconnect"
      "command" "Disconnect"
      "OnlyInGame" "1"
      "notsingle" "1"
   }
   "4"
   {
      "label" "#GameUI_GameMenu_PlayerList"
      "command" "OpenPlayerListDialog"
      "OnlyInGame" "1"
      "notsingle" "1"
   }
   "8"
   {
      "label" ""
      "command" ""
      "OnlyInGame" "1"
   }
   "9"
   {
      "label" "#GameUI_GameMenu_NewGame"
      "command" "OpenCreateMultiplayerGameDialog"
   }
   "10"
   {
      "label" "#GameUI_GameMenu_FindServers"
      "command" "OpenServerBrowser"
   }
   "11"
   {
      "label" "#GameUI_GameMenu_Options"
      "command" "OpenOptionsDialog"
   }
   "12"
   {
      "label" "#GameUI_GameMenu_Quit"
      "command" "Quit"
   }
}

Если попытаться разобраться в нем, то:
  • label - это название опции, которое и будет отображаться в меню игры
  • command - команда, которая будет выполняться при нажатии данной опции меню. В данном случае эти команды понятны только движку игры, но если использовать в них engine, то это приведет к выполнению консольной команды игры, то есть тоже самое, что если игрок выполнит ее в консоли лично:
    command "engine connect 127.0.0.1:27015

    Нажатие опции с данной командой приведет к подключению клиента к серверу с адресом 127.0.0.1:27015.
  • OnlyInGame - если имеет значение 1, то означает, что опция будет видна меню, если игрок будет в игре.
  • notsingle - если значение 1, то опция видна только в multiplayer режиме, а Counter-Strike 1.6 имеет как раз такой режим.
Допустим у нас есть сервер с адресом 127.0.0.1:27015 и мы хотим, чтобы в меню игры у игроков была опция подключения к нашему серверу. Для этого мы редактируем GameMenu.res и получаем:
Код: Выделить всё

"GameMenu"
{
   "1"
   {
      "label" "Join to AMX-X.RU Server"
      "command" "engine connect 127.0.0.1:27015"
   }
   "2"
   {
      "label" ""
      "command" ""
   }
   "3"
   {
      "label" "#GameUI_GameMenu_ResumeGame"
      "command" "ResumeGame"
      "OnlyInGame" "1"
   }
   "4"
   {
      "label" "#GameUI_GameMenu_Disconnect"
      "command" "Disconnect"
      "OnlyInGame" "1"
      "notsingle" "1"
   }
   "5"
   {
      "label" "#GameUI_GameMenu_PlayerList"
      "command" "OpenPlayerListDialog"
      "OnlyInGame" "1"
      "notsingle" "1"
   }
   "6"
   {
      "label" ""
      "command" ""
      "OnlyInGame" "1"
   }
   "7"
   {
      "label" "#GameUI_GameMenu_NewGame"
      "command" "OpenCreateMultiplayerGameDialog"
   }
   "8"
   {
      "label" "#GameUI_GameMenu_FindServers"
      "command" "OpenServerBrowser"
   }
   "9"
   {
      "label" "#GameUI_GameMenu_Options"
      "command" "OpenOptionsDialog"
   }
   "10"
   {
      "label" "#GameUI_GameMenu_Quit"
      "command" "Quit"
   }
}

Теперь нам нужно, чтобы файл имеел правильное содержимое для его использовании в нашем плагине. Заменяем CR LF на CR. Чтобы вставить символ CR, зажимаем на клавиатуре ALT затем набираем 013. В конце файла оставляем CR LF, как конец. После всех изменений у меня получился файл размером 776 байт, что не превышает наш лимит (1012 байт). Сохраняем его, как gamemenu.txt, к примеру, и ложим в addons/amxmodx/configs.

[align=center]
gamemenu.jpg
[/align]

Теперь напишем плагин для чтения нашего gamemenu.txt и записи его игроку:
Код: Выделить всё
#include <amxmodx>

#define PLUGIN "Game Menu"
#define VERSION "1.0"
#define AUTHOR "DJ_WEST"

#define GAMEMENU_FILE "resource/GameMenu.res"
#define MAX_SIZE 1012

new g_Text[MAX_SIZE]

public plugin_init() 
{
    register_plugin(PLUGIN, VERSION, AUTHOR)
    
    
// Вызываем функцию Read_GameMenu для чтения нашего исправленного файла меню.
    set_task(0.1, "Read_GameMenu")
}

public Read_GameMenu()
{
    new i_File, s_File[128]
    
    
// Получаем путь к директории с конфигами AMXX в s_File.
    get_configsdir(s_File, charsmax(s_File))
    
    
// Формируем путь к gamemenu.txt файлу, используя путь к конфигам, и сохраняем в s_File.
    format(s_File, charsmax(s_File), "%s/gamemenu.txt", s_File)
    
    
// Открываем файл для чтения
    i_File = fopen(s_File, "r")
    
    
// Читаем содержимое файла в g_Text. Данная функция поддерживает чтение символов CR, LF.
    fgets(i_File, g_Text, MAX_SIZE)
    
    
// Закрываем файл
    fclose(i_File)
}

public client_putinserver(id)
{
    // Вызываем функцию Change_GameMenu
    set_task(3.0, "Change_GameMenu", id)
}

stock get_configsdir(s_Name[], i_Len)
{
    return get_localinfo("amxx_configsdir", s_Name, i_Len)
}

public Change_GameMenu(id)
{
    // Указываем путь к файлу resource/GameMenu.res
    client_cmd(id, "motdfile %s", GAMEMENU_FILE)
    
    
// Записываем в файл содержимое g_Text
    client_cmd(id, "motd_write %s", g_Text)
    
    
// Возвращаем значение команды по умолчанию
    client_cmd(id, "motdfile motd.txt")    
}
 

Изменения меню вступят в силу после перезапуска игры. Или выполнения команды _restart.
Помните, что данным способом вы стираете клиентский GameMenu.res файл, который может быть уже был изменен игроком по его предпочтениям и желанию.

[align=center]
gamemenu_after.jpg
[/align]
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2190 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Использование возможностей motd_write

Сообщение nubi1051 » 09 дек 2012, 22:52

BROWN писал(а):
nubi1051 писал(а):А в .ini файлы писать я так понял нельзя?

Можно.

Подскажите пожалуйста как?
Аватара пользователя
nubi1051
 
Сообщения: 16
Зарегистрирован: 30 сен 2012, 11:55
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6

Re: Использование возможностей motd_write

Сообщение BROWN » 10 дек 2012, 00:28

nubi1051 писал(а):
BROWN писал(а):
nubi1051 писал(а):А в .ini файлы писать я так понял нельзя?

Можно.

Подскажите пожалуйста как?

Код: Выделить всё
motdfile ololoshkin.ini;motd_write ololoshkin text
Brown_dev
Аватара пользователя
BROWN
 
Сообщения: 991
Зарегистрирован: 25 фев 2012, 23:19
Забанен
Благодарил (а): 39 раз.
Поблагодарили: 411 раз.

Re: Использование возможностей motd_write

Сообщение nubi1051 » 10 дек 2012, 00:42

И радуемся сообщению: Invalid motdfile name (ololoshkin.ini)
Аватара пользователя
nubi1051
 
Сообщения: 16
Зарегистрирован: 30 сен 2012, 11:55
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6

Re: Использование возможностей motd_write

Сообщение BROWN » 10 дек 2012, 00:50

nubi1051 писал(а):И радуемся сообщению: Invalid motdfile name (ololoshkin.ini)

Радуешься ты если у тебя такой клиент.
Brown_dev
Аватара пользователя
BROWN
 
Сообщения: 991
Зарегистрирован: 25 фев 2012, 23:19
Забанен
Благодарил (а): 39 раз.
Поблагодарили: 411 раз.

Re: Использование возможностей motd_write

Сообщение nubi1051 » 10 дек 2012, 00:56

Я пытаюсь выполнить от имени сервера даже ( т.е. через ркон), то же самое.

Клиент? Steam.
Аватара пользователя
nubi1051
 
Сообщения: 16
Зарегистрирован: 30 сен 2012, 11:55
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6

Re: Использование возможностей motd_write

Сообщение google.bsk » 26 авг 2017, 09:15

Как сделать плагин автоконнект через этот метод?
Аватара пользователя
google.bsk
 
Сообщения: 27
Зарегистрирован: 25 июл 2013, 09:44
Благодарил (а): 7 раз.
Поблагодарили: 0 раз.

Re: Использование возможностей motd_write

Сообщение Subb98 » 26 авг 2017, 10:03

Никак. Этот метод не актуален.
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5395
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1315 раз.
Поблагодарили: 2320 раз.
Опыт программирования: Больше трех лет
Языки программирования: Pawn, PHP, Ruby

Re: (Неактуально) Использование возможностей motd_write

Сообщение google.bsk » 26 авг 2017, 10:39

а есть ли актуальный метод?
Аватара пользователя
google.bsk
 
Сообщения: 27
Зарегистрирован: 25 июл 2013, 09:44
Благодарил (а): 7 раз.
Поблагодарили: 0 раз.

Re: (Неактуально) Использование возможностей motd_write

Сообщение Subb98 » 26 авг 2017, 11:16

google.bsk, если и есть, то почему вы думаете, что его кто-то будет сливать? Чтобы были конкуренты? Или чтобы сделали фикс? :crazy:
«Очень хорошо. Лучше вы, чем я» © Donald J. Trump
Аватара пользователя
Subb98
Модератор
 
Сообщения: 5395
Зарегистрирован: 24 мар 2011, 19:42
Откуда: г. Пермь
Благодарил (а): 1315 раз.
Поблагодарили: 2320 раз.
Опыт программирования: Больше трех лет
Языки программирования: Pawn, PHP, Ruby

Пред.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1