Difference between revisions of "DEM Format:ru"

From Valve Developer Community
Jump to: navigation, search
m (otherlang2'd)
(I just added this page)
Line 2: Line 2:
 
|en=DEM_Format
 
|en=DEM_Format
 
}}
 
}}
Note that it is not possible to edit what happens in a Source demo, it basically stores the packets right off the wire, and we don't know the packet format.
+
'''DEM''' (сокращение от демонстрации) - это формат исходного файла демо. Используется совместно с Source рекордером для записи демонстраций, которые содержат записанные события, которые можно редактировать и воспроизводить в игре. Демо может быть отредактирован для изменения углов камеры, ускорения, замедления, воспроизведения музыки и других функций.
  
For the purpose of this, I will be referring to each collection of events as a frame.  This may or may not add up to the number of frames given by the header.
+
{{note|В настоящее время нет инструментов для редактирования демонстраций после их записи.}}
  
 +
For the purpose of this we will be referring to each collection of events as a frame. This may or may not add up to the number of frames given by the header.
  
 
===Заголовок Демо===
 
===Заголовок Демо===
Line 11: Line 12:
 
! Тип || Поле || Значение
 
! Тип || Поле || Значение
 
|-
 
|-
| [[String]] || Заголовок || 7+NULL characters, should be "HL2DEMO"
+
| [[String]] || Заголовок || 8 символов, должно быть "HL2DEMO"+NULL
 
|-
 
|-
| [[Int]] || Демо Протокол || Версия протокола демо, например '3'
+
| [[Int]] || Демо Протокол || Версия демо протокола
 
|-
 
|-
| [[Int]] || Протокол Сети || Версия Сетевого протокола  
+
| [[Int]] || Протокол Сети || Номер версии сетевого протокола
 
|-
 
|-
| [[String]] || Имя Сервера || Длиной в 260 символов  
+
| [[String]] || Имя сервера || Длинной в 260 символов
 
|-  
 
|-  
| [[String]] || Имя клиента || Длиной в 260 символов  
+
| [[String]] || Имя клиента || Длинной в 260 символов
 
|-
 
|-
| [[String]] || Имя Карты || Длиной в 260 символов  
+
| [[String]] || Имя карты || Длинной в 260 символов
 
|-
 
|-
| [[String]] || Директория Игры  || Длиной в 260 символов  
+
| [[String]] || Директория игры || Длинной в 260 символов
 
|-
 
|-
| [[Float]] || Время игры || Продолжительность записи Демо, в секундах
+
| [[Float]] || Время воспроизведения || Продолжительность демонстрации в секундах
 
|-
 
|-
| [[Int]] || Ticks || The number of ticks in the demo
+
| [[Int]] || Тиков || Количество тиков в демонстрации
 
|-  
 
|-  
| [[Int]] || Кадры || Количество кадров в Демо
+
| [[Int]] || Кадров || Количество кадров в демо
 
|-
 
|-
| [[Int]] || Sign on length || ?
+
| [[Int]] || Длина записи || Длина знаков до первого кадра
 
|}
 
|}
  
===Frame===
+
===Кадр===
Each frame begins with 0 or more of these commands:
+
Каждый кадр начинается с 0 или более следующих команд:
These are described in hl2sdk\utils\demoinfo\demoformat.h
+
Они описаны в hl2sdk\utils\demofile\demoformat.h / hl2sdk-ob\public\demofile\demoformat.h / hl2sdk-l4d\public\demofile\demoformat.h
 +
 
 +
====Сетевые протоколы 7 и 8====
 
{| class=standard-table
 
{| class=standard-table
 
! Тип || Значение
 
! Тип || Значение
Line 57: Line 60:
 
|}
 
|}
  
Depending on the command that was received, a different action needs to be taken.
+
====Сетевые протоколы 14 и 15====
 +
{| class=standard-table
 +
! Тип || Значение
 +
|-
 +
| dem_stringtables || 8
 +
|-
 +
| dem_lastcommand || dem_stringtables
 +
|}
  
====dem_stop, dem_lastcommand====
+
====Сетевые протоколы 36 и выше====
This is a signal that the demo is over, and there is no more data to be parsed.
+
{| class=standard-table
 +
! Тип || Значение
 +
|-
 +
| dem_customdata || 8
 +
|-
 +
| dem_stringtables || 9
 +
|-
 +
| dem_lastcommand || dem_stringtables
 +
|}
  
====dem_consolecmd, dem_datatables, dem_usercmd====
+
В зависимости от полученной команды необходимо выполнить другое действие.
Read a standard data packet, deal with it as necessary.
+
 
 +
====dem_stop====
 +
Это сигнал о том, что демо закончилось, и больше данных не нужно разбирать.
 +
 
 +
====dem_consolecmd, dem_datatables, dem_usercmd, dem_stringtables====
 +
Чтение стандартных пакет данных, при необходимости они обработываются.
  
 
====dem_synctick, dem_signon, dem_packet====
 
====dem_synctick, dem_signon, dem_packet====
Ignore.
+
Игнорирование.
 +
 
 +
===Стандартные данные "Пакета"===
 +
Каждый раз, когда читается более одного байта, используется стандартный формат.
 +
 
 +
Это начинается с целого числа, которое имеет количество байтов в этом пакете.
 +
 
 +
Пример кода для этого:
 +
 
 +
<source lang="cpp">
 +
int ReadData(char **buffer)
 +
{
 +
int len;
 +
fread (&len,sizeof(int),1,fDemo);
 +
if (len > 0)
 +
{
 +
*buffer = new char[len];
 +
fread(*buffer,len,1,fDemo);
 +
}
 +
return len;
 +
}
 +
</source>
 +
 
 +
=== Формат Кадров ===
 +
<source lang="cpp">
 +
Frame {
 +
      int ServerFrame;
 +
      int ClientFrame; // ServerFrame и ClientFrame delta, вероятно, соответствуют отклику клиента.
 +
      int SubPacketSize;
 +
      *buffer = new char[SubPacketSize]; // Сообщение о состоянии обновлений
 +
      Packet pkt = (rest of frame as data exists) // Все демо-команды объединены в этой области, структура ниже...
 +
      JunkData data = (unknown) // Бывший: 0x8f 5a b5 04 94 e6 7c 24 00 00 00 00 00 ... (40 байт 0x00 после 0x24)
 +
                                // Это может быть либо конец кадра, либо начало следующего кадра.
 +
}
 +
</source>
 +
 
 +
<source lang="cpp">
 +
Packet {
 +
      char CmdType;
 +
      int Unknown;
 +
      int TickCount; // Это только периодический появляется.
 +
      int SizeOfPacket;
 +
      *buffer = new char[SizeOfPacket];
 +
}
 +
</source>
 +
 
 +
===Пример использования===
 +
 
 +
Может быть интересно захватить заголовок демонстрационных файлов на случай, если вы запустите веб-сервер, на котором размещены ваши демонстрации / телевизоры.
 +
Вот скрипт PHP, который выполняет эту работу за вас, и имеет возможность рассказать вам, является ли демонстрационный файл записью от глаза клиента или SourceTV.
 +
 
 +
Вы можете легко преобразовать его в код C++, если вы планируете использовать его для другой необходимости.
 +
<source lang="php">
 +
<?
 +
/* Source & OrangeBox demos header reader.
 +
By PoLaRiTy (nocheatz.com)
 +
 
 +
Help from  : https://developer.valvesoftware.com/wiki/DEM_Format#Demo_Header
 +
              http://hg.alliedmods.net/hl2sdks/hl2sdk-css/file/1901d5b74430/public/demofile/demoformat.h
 +
 
 +
Types sizes :
 +
Int : 4 bytes
 +
Float : 4 bytes
 +
String : 260 bytes
 +
*/
 +
 
 +
 
 +
class DemoInfo_s
 +
{
 +
var $dem_prot;      // Demo protocol version
 +
var $net_prot;      // Network protocol versio
 +
var $host_name;      // HOSTNAME in case of TV, and IP:PORT or localhost:PORT in case of RIE (Record In eyes).
 +
var $client_name;    // Client name or TV name.
 +
var $map_name;      // Map name
 +
var $gamedir;        // Root game directory
 +
var $time;          // Playback time (s)
 +
var $ticks;          // Number of ticks
 +
var $frames;        // Number of frames
 +
var $tickrate;      // Tickrate
 +
var $type;          // TV or RIE ? (0 = RIE, 1 = TV)
 +
var $status_present; // true if a status command is available in the demo.
 +
}
 +
 
 +
function ExtOfFile($pathtofile)
 +
{
 +
return end(explode('.',$pathtofile));
 +
}
 +
 
 +
function ReadString($handle, $n = 260)
 +
{
 +
$buffer = "";
 +
for($d = 1; ((($char = fgetc($handle)) !== false) && ($d < $n)); $d++) $buffer = $buffer.$char;
 +
return trim($buffer);
 +
}
  
===Standard Data "Packet"===
+
function ReadInt($handle, $n = 4)
Any time there is more than one byte to be read in, a standard format is used.
+
{
 +
$buf = fread($handle, $n);
 +
$number = unpack("i", $buf);   
 +
return $number[1];
 +
}
  
This begins with an integer that has the number of bytes in this packet.
+
function ReadFloat($handle)
 +
{
 +
$buf = fread($handle, 4);
 +
$number = unpack("f", $buf);   
 +
return $number[1];
 +
}
  
Example code to handle this:
+
function IsGoodIPPORTFormat($string)
 +
{
 +
if(preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}/', $string)) return true;
 +
else return false;
 +
}
  
int ReadData(char **buffer)
+
function GetDemoInfo($pathtofile, $fast = false) // BOOL fast : if true, doesn't check the presence of the status
{
+
{
int len;
+
$infos = NULL;
fread (&len,sizeof(int),1,fDemo);
+
if(ExtOfFile($pathtofile) === "dem")
if (len > 0)
+
{
{
+
$handle = fopen($pathtofile, "r");
*buffer = new char[len];
+
if($handle)
fread(*buffer,len,1,fDemo);
+
{
}
+
if(ReadString($handle, 8) === "HL2DEMO")
return len;
+
{
}
+
$infos = new DemoInfo_s;
 +
$infos->dem_prot = ReadInt($handle);
 +
$infos->net_prot = ReadInt($handle);
 +
$infos->host_name = ReadString($handle);
 +
$infos->client_name = ReadString($handle);
 +
$infos->map_name = ReadString($handle);
 +
$infos->gamedir = ReadString($handle);
 +
$infos->time = ReadFloat($handle);
 +
$infos->ticks = ReadInt($handle);
 +
$infos->frames = ReadInt($handle);
 +
$infos->tickrate = intval($infos->ticks / $infos->time);
 +
if(IsGoodIPPORTFormat($infos->host_name)) $infos->type = 0; // RIE  TODO : Add localhost:PORT check.
 +
else $infos->type = 1; // TV
 +
$infos->status_present = false;
 +
if(!$fast && !($infos->type == 1)) // No status in TV records.
 +
{
 +
while(!(($l = fgets($handle)) === false))
 +
{
 +
if(stripos($l, "\x00status\x00") !== false)
 +
{
 +
$infos->status_present = true;
 +
break;
 +
}
 +
}
 +
}
 +
}
 +
else
 +
{
 +
echo "Bad file format.";
 +
}
 +
fclose($handle);
 +
}
 +
else
 +
{
 +
echo "File not found or unable to read.";
 +
}
 +
}
 +
else
 +
{
 +
echo "Bad file extension.";
 +
}
 +
return $infos;
 +
}
 +
?>
 +
</source>
  
 +
==Смотрите также==
 +
*[[Demo Recording Tools]]
 +
*[[Demo Video Creation]]
  
[[Category:Technical:ru]]
+
[[Category:File formats]]

Revision as of 15:54, 18 October 2018

English

DEM (сокращение от демонстрации) - это формат исходного файла демо. Используется совместно с Source рекордером для записи демонстраций, которые содержат записанные события, которые можно редактировать и воспроизводить в игре. Демо может быть отредактирован для изменения углов камеры, ускорения, замедления, воспроизведения музыки и других функций.

Note:В настоящее время нет инструментов для редактирования демонстраций после их записи.

For the purpose of this we will be referring to each collection of events as a frame. This may or may not add up to the number of frames given by the header.

Заголовок Демо

Тип Поле Значение
String Заголовок 8 символов, должно быть "HL2DEMO"+NULL
Int Демо Протокол Версия демо протокола
Int Протокол Сети Номер версии сетевого протокола
String Имя сервера Длинной в 260 символов
String Имя клиента Длинной в 260 символов
String Имя карты Длинной в 260 символов
String Директория игры Длинной в 260 символов
Float Время воспроизведения Продолжительность демонстрации в секундах
Int Тиков Количество тиков в демонстрации
Int Кадров Количество кадров в демо
Int Длина записи Длина знаков до первого кадра

Кадр

Каждый кадр начинается с 0 или более следующих команд: Они описаны в hl2sdk\utils\demofile\demoformat.h / hl2sdk-ob\public\demofile\demoformat.h / hl2sdk-l4d\public\demofile\demoformat.h

Сетевые протоколы 7 и 8

Тип Значение
dem_signon 1
dem_packet 2
dem_synctick 3
dem_consolecmd 4
dem_usercmd 5
dem_datatables 6
dem_stop 7
dem_lastcommand dem_stop

Сетевые протоколы 14 и 15

Тип Значение
dem_stringtables 8
dem_lastcommand dem_stringtables

Сетевые протоколы 36 и выше

Тип Значение
dem_customdata 8
dem_stringtables 9
dem_lastcommand dem_stringtables

В зависимости от полученной команды необходимо выполнить другое действие.

dem_stop

Это сигнал о том, что демо закончилось, и больше данных не нужно разбирать.

dem_consolecmd, dem_datatables, dem_usercmd, dem_stringtables

Чтение стандартных пакет данных, при необходимости они обработываются.

dem_synctick, dem_signon, dem_packet

Игнорирование.

Стандартные данные "Пакета"

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

Это начинается с целого числа, которое имеет количество байтов в этом пакете.

Пример кода для этого:

int ReadData(char **buffer)
{
	int len;
	fread (&len,sizeof(int),1,fDemo);
	if (len > 0)
	{
		*buffer = new char[len];
		fread(*buffer,len,1,fDemo);
	}
	return len;
}

Формат Кадров

Frame {
       int ServerFrame;
       int ClientFrame; // ServerFrame и ClientFrame delta, вероятно, соответствуют отклику клиента.
       int SubPacketSize;
       *buffer = new char[SubPacketSize]; // Сообщение о состоянии обновлений
       Packet pkt = (rest of frame as data exists) // Все демо-команды объединены в этой области, структура ниже...
       JunkData data = (unknown) // Бывший: 0x8f 5a b5 04 94 e6 7c 24 00 00 00 00 00 ... (40 байт 0x00 после 0x24)
                                 // Это может быть либо конец кадра, либо начало следующего кадра.
}
Packet {
       char CmdType;
       int Unknown;
       int TickCount; // Это только периодический появляется.
       int SizeOfPacket;
       *buffer = new char[SizeOfPacket];
}

Пример использования

Может быть интересно захватить заголовок демонстрационных файлов на случай, если вы запустите веб-сервер, на котором размещены ваши демонстрации / телевизоры. Вот скрипт PHP, который выполняет эту работу за вас, и имеет возможность рассказать вам, является ли демонстрационный файл записью от глаза клиента или SourceTV.

Вы можете легко преобразовать его в код C++, если вы планируете использовать его для другой необходимости.

<?
/* Source & OrangeBox demos header reader.
By PoLaRiTy (nocheatz.com)

Help from   : https://developer.valvesoftware.com/wiki/DEM_Format#Demo_Header
              http://hg.alliedmods.net/hl2sdks/hl2sdk-css/file/1901d5b74430/public/demofile/demoformat.h

Types sizes :
Int : 4 bytes
Float : 4 bytes
String : 260 bytes
*/


class DemoInfo_s
{
	var $dem_prot;       // Demo protocol version 
	var $net_prot;       // Network protocol versio
	var $host_name;      // HOSTNAME in case of TV, and IP:PORT or localhost:PORT in case of RIE (Record In eyes).
	var $client_name;    // Client name or TV name.
	var $map_name;       // Map name
	var $gamedir;        // Root game directory
	var $time;           // Playback time (s)
	var $ticks;          // Number of ticks
	var $frames;         // Number of frames
	var $tickrate;       // Tickrate
	var $type;           // TV or RIE ? (0 = RIE, 1 = TV)
	var $status_present; // true if a status command is available in the demo.
}

function ExtOfFile($pathtofile)
{
	return end(explode('.',$pathtofile));
}

function ReadString($handle, $n = 260)
{
	$buffer = "";
	for($d = 1; ((($char = fgetc($handle)) !== false) && ($d < $n)); $d++) $buffer = $buffer.$char;
	return trim($buffer);
}

function ReadInt($handle, $n = 4)
{
	$buf = fread($handle, $n);
	$number = unpack("i", $buf);     
	return $number[1];
}

function ReadFloat($handle)
{
	$buf = fread($handle, 4);
	$number = unpack("f", $buf);     
	return $number[1];
}

function IsGoodIPPORTFormat($string)
{
	if(preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}/', $string))	return true;
	else return false;
}

function GetDemoInfo($pathtofile, $fast = false) // BOOL fast : if true, doesn't check the presence of the status 
{
	$infos = NULL;
	if(ExtOfFile($pathtofile) === "dem")
	{
		$handle = fopen($pathtofile, "r");
		if($handle)
		{
			if(ReadString($handle, 8) === "HL2DEMO")
			{
				$infos = new DemoInfo_s;
				$infos->dem_prot = ReadInt($handle);
				$infos->net_prot = ReadInt($handle);
				$infos->host_name = ReadString($handle);
				$infos->client_name = ReadString($handle);
				$infos->map_name = ReadString($handle);
				$infos->gamedir = ReadString($handle);
				$infos->time = ReadFloat($handle);
				$infos->ticks = ReadInt($handle);
				$infos->frames = ReadInt($handle);
				$infos->tickrate = intval($infos->ticks / $infos->time);
				if(IsGoodIPPORTFormat($infos->host_name)) $infos->type = 0; // RIE   TODO : Add localhost:PORT check.
				else $infos->type = 1; // TV
				$infos->status_present = false;
				if(!$fast && !($infos->type == 1)) // No status in TV records.
				{
					while(!(($l = fgets($handle)) === false))
					{
						if(stripos($l, "\x00status\x00") !== false)
						{
							$infos->status_present = true;
							break;
						}
					}
				}
			}
			else
			{
				echo "Bad file format.";
			}
			fclose($handle);
		}
		else
		{
			echo "File not found or unable to read.";
		}
	}
	else
	{
		echo "Bad file extension.";
	}
	return $infos;
}
?>

Смотрите также