Developer Console Control:ru

From Valve Developer Community
Revision as of 06:29, 29 August 2006 by KindDragon (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Developer console 01.gif

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

Вывод в консоль

Вывод текста в консоль доступен из всех модулей и контролируется через 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" ); // послать команду на сервер

or

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

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

Консоль разработчика - это подсистема движка Source, которая дает доступ к различным модулям, это осуществляется через интерфейс ICvar ( см. \public\icvar.h). Этот интерфейс регистрирует новые команды и ищет существующие. Этот интрефейс доступен через глобальную переменную CVAR в клиент-серверном коде (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 );

It is common use that the object name and the command name are the same and variables used only in a single source file are declared as static.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 function is executed, the parameters entered in console are not passed as function arguments. The callback function has to query the engine how many arguments where given using the engine interface function Cmd_Argc(). Then you can look at single arguments using Cmd_Argv(index), where index 1 is the first argument. The arguments are always returned as strings.

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);

Here an example how to build a simple auto complete list. The partial parameter isn't used here; it contains the characters entered so far (including the command name itself) :

static int MySayAutoComplete ( char const *partial, 
char commands[ COMMAND_COMPLETION_MAXITEMS ][ 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);

The FCVAR_ flags

The console command/variable flags can specify quite powerful characteristics and must be handled with care. These flags are usually set in the constructor but may be modified with ConCommandBase::AddFlags() (not used very often). It's not possible to change these flags other than in source code to avoid cheating. Some flags must be set manually, others are set automatically by then console system:

FCVAR_LAUNCHER, FCVAR_GAMEDLL, FCVAR_CLIENTDLL, FCVAR_MATERIAL_SYSTEM, FCVAR_STUDIORENDER

These flags are set by the registration process and specify the module, where the command was created (you don't need to set them). The following flags must be set manually:

FCVAR_CHEAT
Most commands and variables are for debugging proposes and not removed in release builds since they are useful 3rd party developers and map makers too. Unfortunately we cannot allow normal players to use these debugging tools since it's an unfair advantage over other players (cheating). A good rule is to add FCVAR_CHEAT basically to every new console command you add unless it's an explicit and legitimate options setting for players. Experience shows that even the most harmless looking debugging command can be misused as a cheat somehow.

The game server's setting of sv_cheats decides if cheats are enabled or not. If a client connects to a server where cheats are disabled (should be the default case), all client side console variables labeled as FCVAR_CHEAT are reverted to their default values and can't be changed as long as the client stays connected. Console commands marked as FCVAR_CHEAT can't be executed either.

FCVAR_USERINFO
Some console variables contain client information the server needs to know about, like the player's name or his network settings. These variables must be flagged as FCVAR_USERINFO, so they get transmitted to the server and updated every time the user changes them. When the player changes on of these variables the engine notifies the server code via ClientSettingsChanged(). Then the game server can query the engine for specific client settings with GetClientConVarValue().
FCVAR_REPLICATED
Game server and client are using shared code where it's important that both sides run the exact some path using the same data (e.g. predicted movement/weapons, game rules). If this code uses console variables, they must match the same values on both sides. The flag FCVAR_REPLICATED ensures that by broadcasting these values to all clients. While connected, clients can't change these values and are force to use the server side values.
FCVAR_ARCHIVE
Some console variables contain user specific settings we want to restore each time the game is started ( like name or network_rate). If a console variable is labeled as FCVAR_ARCHIVE, it is saved in the file config.cfg when the game shuts down and is reloaded with the next start. (Also the command host_writeconfig stores all FCVAR_ARCHIVE variables to a file).
FCVAR_NOTIFY
If a console variable is flagged as FCVAR_NOTIFY, a server sends a notification message to all clients whenever this variable is changed. This should be used for variables that change game play rules, which are important for all players (mp_friendlyfire etc).
FCVAR_PROTECTED
If console variables contain private information (passwords etc), we don't want them to be visible to other players. Then the FCVAR_PROTECTED flag should be set to label this information as confidential.
FCVAR_SPONLY
Sometimes executing commands or changing variables may be valid only in single player mode, then label these commands as FCVAR_SPONLY.
FCVAR_PRINTABLEONLY
Some important variables are logged or broadcasted (gamerules etc) and it is important that they contain only printable characters (no control chars etc).
FCVAR_NEVER_AS_STRING
The flag tells the engine never to print this variable as string since it contains control sequences.
FCVAR_DEMO
When starting recording a demo file, some console variables must explicitly added to the recording to ensure a correct playback.
FCVAR_DONTRECORD
This is the opposite of FCVAR_DEMO, some console commands shouldn't be recorded in demo files.