Консоль разработчика

From Valve Developer Community
< Ru
Jump to navigation Jump to search
English (en)Deutsch (de)Русский (ru)中文 (zh)Translate (Translate)

Developer console 01.gif

Этот документ объясняет, как писать код в консоль(en), как исполнять и создавать консольные команды и переменные. Смотрите Консоль разработчика(en) для обзора возможностей консоли.

Печать в консоли

Ввод текста в консоль доступен из всех модулей и контролируется через Tier(). Есть 3 дополнительные команды Msg(), DevMsg() и Warning() которые поддерживают вывод форматированной строки, как sprintf():

DevMsg (char const* pMsg, ... ) - только в режиме разработчика
Msg(char const* pMsg, ... )	- всегда, белый текст
Warning(char const *pMsg, ... ) - всегда, красный текст

Для обратной совместимости с HL1 сохранены команды Con_Printf() и Con_DPrintf().

Исполнение команд

Движок использует интерфейс сервера и клиента, чтобы исполнять команды (строки). Сервер использует интерфейс IVEngineServer::ServerCommand():

engine->ServerCommand("changelevel de_dust\n");

Клиент использует интерфейс IVEngineClient и выбирает между двумя командами, от этого зависит, будет ли команда исполняться сначала на клиенте или посылаться непосредственно серверу:

engine->ServerCmd( "say hello\n" ); // послать команду на сервер

или

engine->ClientCmd( "say hello\n" ); // выполнить команду на клиенте

Добавление новых команд и переменных

Консоль разработчика - это подсистема движка Source, которая дает доступ к различным модулям, это осуществляется через интерфейс ICvar ( см. \public\icvar.h). Этот интерфейс регистрирует новые команды и ищет существующие. Этот интрефейс доступен через глобальную переменную CVAR(en) в клиент-серверном коде (cv в коде движка). Консольные команды принадлежат классу ConCommand, а консольные переменные ConVar, которые оба происходят от базового класса ConCommandBase (см. \public\convar.h).

Добавление новых команд и переменных довольно просто и дуступно для использования и для серверных и для клиентских (одинаково для всего движка) модулей. Конструктор этих классов автоматически регистрирует новую команду/переменную в системе консоли. Этот короткий пример кода добавляет новую команду my_function и новую переменную my_variable инициализированную значение 42:

#include <convar.h>
ConVar my_variable( "my_variable", "42", FCVAR_ARCHIVE, "My favorite number" );	

void MyFunction_f( void )
{
    Msg("This is my function\n");
}

ConCommand my_function( "my_function", MyFunction_f, "Shows a message.", FCVAR_CHEAT );

Это обычное использование когда имя объекта и команды одинаковое и переменные используются только в одном исходнике описываются как static.

Использование класса ConVar(en)

Для начала рассмотрим наиболее используемый ConVar(en) конструктор:

ConVar( char const *pName,
  char const *pDefaultValue,
  int flags,
  char const *pHelpString )

Первый аргумент pName это имя переменной (без пробелов), следующий pDefaultValue,всегда является строковым, даже для ConVar(en)'s с числовыми значениями. Flags пределяет специальные характеристики переменной, все описания флагов начинаются с FCVAR_*, но об этом позже. Очень хорошо использовать pHelpString, чтобы пользователи могли понять для чего эта переменная предназначена. ConVar(en)s не огрнаичиваются определненным типом, их значение может быть целым или вещественным или строкой и вы можете его использовать как вам угодно. Так долго как у вас есть ConVar(en) объект сам или указатель на него, вы можете смотреть и изменять его значение напрямую. Все эти примеры правильны и дадут одинаковый результат:

if ( my_variable.GetInt() == 42 ) DoSomething();
if ( my_variable.GetFloat() == 42.0f ) DoSomething();
if ( strcmp(my_variable.GetString(), "42")==0 ) DoSomething();

Для установки значения ConVar(en) вы должны использовать функцию SetValue(), использующая любые типы данных:

my_variable.SetValue( 42 );
my_variable.SetValue( 42.0f );
my_variable.SetValue( "42" );

В любое время вы можете вернуть значение [ConVar]] назад к значению по-умолчанию использовав функцию Revert().

Если ConVar(en) создан в разных модулях, то в интерфейсе ICvar функция FindVar()спользуется для получения указателя на объект, если имя переменной установлено. Вот простой пример, который проверяет установлена ли ConVar(en) sv_cheats(en) определенная в модуле движка:

ConVar *pCheats  = cvar->FindVar( "sv_cheats" );

    if ( pCheats && pCheats->GetInt() == 1 ) AllowCheating();

Диапозон правильных значений может быть определен для числовых ConVar(en)s используя другой конструктор. Тогда ConVar(en) автоматически проверяется консольной системой всякий когда она изменяется вручную. Если введенное число выходит за границы диапозона, оно округляется к следующему правильному значению. Установка диапозона правильных значений от 1 до 100:

ConVar my_variable( "my_variable", "42", 0, "helptext", true, 1, true, 100 );

Иногда необходимо чтобы вы получали извещение когда пользователь или другая подсистема меняет значение вашей ConVar(en), поэтому может быть установлена функция обратного вызова:

static void OnChangeMyVariable ( ConVar *var, char const *pOldString )
{
    DevMsg( "ConVar %s was changed from %s to %s\n", var->GetName(), pOldString, var->GetString() );
}

ConVar my_variable( "my_variable", "42", 0, "My favorite number", OnChangeMyVariable );

Использование класса ConCommand

Class ConCommand проще чем ConVar и у него только один конструктор:

ConCommand( char const *pName,
    FnCommandCallback callback,
    char const *pHelpString = 0,
    int flags = 0,
    FnCommandCompletionCallback completionFunc = 0 );

Как и у ConVar pName определяет имя команды (без пробелов!). callback эта функция выполняемая когда пользователь исполняет эту команду, pHelpString и флаги имебт те же функции что и в ConVar. ConCommands поддерживает автозавершение для первого параметра, особенно используемый для которые обрабатывают файлы. Например, вы используете команду loadtext lt;textfilegt; которая предполагает .txt файл для ввода, консоль ищет все доступные .txt файлы и позволяет пользователю выбрать один из списка. Если правильно то completionFunc проходит, она вызывается каждый раз когда консольной системе требуется список доступных аргументов.

Когда callback фунция выполняется, параметры введенные в консоле не подаются как аргументы функции. callback функциям необходимо запрашивать у движка как много аргументов поступило используя фунцию интерфейса движка Cmd_Argc(). Затем можно получить отдельные аргументы используя Cmd_Argv(index), где index 1 это первый аргумент. Аргументы всегда возвращаются как строки.

void MySay_f ( void )
{
    if ( engine->Cmd_Argc() < 1 )
    {
        Msg(""Usage: my_say <text>\n");
        return;
    }

    Msg("I say: %s\n", engine->Cmd_Argv(1) );
}

ConCommand my_say( "my_say", MySay_f, "say something", 0);

Это пример как построить простой спивок авто завершения. Неполный параметр не используется здесь; он содержит символы введеные так давно (включая само имя команды) :

static int MySayAutoComplete ( char const *partial, 
char commands[ COMMAND_COMPLETION_MAXITEвMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
{
    strcpy( commands[0], "hello" );
    strcpy( commands[1], "goodbye" );
    return 2; // number of entries
}

ConCommand my_say( "my_say", MySay_f, "say something", 0, MySayAutoComplete);

Флаги FCVAR_

Консольные команды/переменные используют флаги, которые обладают определенными характеристиками и должны обрабатываться с осторожностью. Эти флаги используются конструктором и могут быть изменены с помощью ConCommandBase::AddFlags() (не используются сильно часто). Невозможно изменить эти флаги подругому как в исходных кодах чтобы избежать читов. Некоторые флаги должны быть установлены вручную, другие устанавливаются автоматически консольной системой:

FCVAR_LAUNCHER, FCVAR_GAMEDLL, FCVAR_CLIENTDLL, FCVAR_MATERIAL_SYSTEM, FCVAR_STUDIORENDER

Эти флаги устанавливаются в процессе регистрации и указывают на модуль, где команда создана (вам не нужно устанавливать их). Следующие флаги должны быть установлены вручную:

FCVAR_CHEAT
Используются при отладке, не удаляются из релиза по причине того, что могут потребоваться разработчикам модов и карт. К сожелению мы неможем позволить нормальным игрокам использовать эти инструменты отладки так как это бы было нечестно по отношению к другим игрокам (читерство). Хорошее правило добавлять FCVAR_CHEAT по началу ко всем новым консольным командам которые вы добавляете, если это не конечная и законная опция для игроков. Опыт показывает что даже наиболее безвредные отладочные команды могут быть использоваться тем или иным образом как чит.

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

FCVAR_USERINFO
Некоторые консольные переменные содержат клиентскую информацию о которой должен знать сервер, такое как имаена пользователей или их четевые настройки. Эти переменные должны быть помечены флагом FCVAR_USERINFO, тогда они будут преданы серверу и обновляться каждый раз когда пользователь изменяет их. Когда пользователь изменяет эти переменные движок оповещает серверный код с помощью ClientSettingsChanged(). Затем сервер может запросить движок отдельные клиентские настройки с помощью GetClientConVarValue().
FCVAR_REPLICATED
Игровой сервер и клиент используют общий код, поэтому важно чтобы обе стороны выполнялись по одиноковому пути используя одинаковые данные (например предсказание движения/оружий, правил игы). Если этот код использует консольные переменные, они должны иметь одинаковые значения на обоих сторонах. Флаг FCVAR_REPLICATED гарантирует рассылку значений всем клиентам. Пока подключены, клиенты немогут менять эти значения так как будут использовать серверные значения.
FCVAR_ARCHIVE
Некоторые консольные переменные содержат пользовательские настройки мы хотим их востанавливать кадый раз когда игра запущена ( как имя или network_rate). Если консольная переменная помечена как FCVAR_ARCHIVE, она сохраняется в файл config.cfg когда игра завершается и она будет загружена при следующем запуске. (Также команда host_writeconfig сохранет все FCVAR_ARCHIVE значения в файл).
FCVAR_NOTIFY
Если консольная переменная помечена как FCVAR_NOTIFY, сервер отправляет сообщение всем клиентам всякий раз когда переменная изменена. Это должно быть использовано для перменных которые меняют правила игры, которые важны для всех игроков (mp_friendlyfire например).
FCVAR_PROTECTED
Жта консольная перменная содержащая частную информацию (пароль например), мы нехотим чтобы она была видна другим пользователям. Для этого должен быть установлен флаг FCVAR_PROTECTED чтобы пометить эту информацию как конфиденциальную.
FCVAR_SPONLY
Иногда исполнение команды или изменение переменной может быть правильно только в однопользовательском режиме, тогда пометьте эту команду как FCVAR_SPONLY.
FCVAR_PRINTABLEONLY
Некоторые важные переменные тяжелые или шировещательные (например правила игры) и важно что они содержат только печатные сиволы (например нет управляющих символов).
FCVAR_NEVER_AS_STRING
Этот флаг говорит движку никогда невыводить эту переменную как строку так как она содержит последовательность управляющих символов.
FCVAR_DEMO
Когда на чинаешь записывать демо файл, некоторые консольные перменные должны быть добавлены к записи чтобы быть уверенными что она правильна будет воспроизведена.
FCVAR_DONTRECORD
Это обратно FCVAR_DEMO, некоторые консольные переменные не должны быть записаны в демо файлы.