Хочу рассказать Вам о моем способе использования клиентских возможностей для работы с 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)
За меню игры отвечает файл 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 имеет как раз такой режим.
- Код: Выделить всё
"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] [/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] [/align]