Talk:DEM (file format)

From Valve Developer Community
Jump to navigation Jump to search

Control of "demoui" via console commands.

I need to find out which commands are tied to the buttons of the player "demoui", I want to make it possible to control the demo using the arrow keys, up - speed higher, down - lower, left - frame back, right frame forward. If someone knows, help me. Vi 19:01, 11.06.2022 (UTC)

Broken time

For some reason, when the demo is ended by the changelevel, the demo time and ticks show a negative value (both in console and demoui). Is there any way to fix it? --Execut4ble 04:35, 30 January 2013 (PST)

File format question

Anyone know why there is a secondary set of sign on data in the demo file for Demo format 3/Protocol 15 of roughly 196,000 bytes? It's full of art and sound asset caching as far as I can tell. Then it starts into the sound set up console commands ("dsp_..."), but then the format wacky. How does the engine parse the frame commands structure at the start of a frame?

The article implies something like:

{ Frame Command Index [ Len1 CMDData1 ] [ Len2 CMDData2 ] [ ... ] [ LenN CMDDataN ] }

But I don't really see this anywhere, or it is too difficult to find without additional information. Any help out there? Mdrowber 13:55, 3 October 2009 (UTC)

Header Format is wrong.

Hello I tried to inspect a replay of a match of Dota2, downloaded using the link found in the opendota API (Precisely using the /matches endpoint). But when I tried to analize it using the demoinfo2.exe for analizing the .dem file I get the an error saying that it cannot open the file. At this point I tried to open the .dem file using an Hex visualizer, and found out that the Header is not "HL2DEMO" but "PBDEMS", what am i missing here?

Also where can I find the .proto for the .dem?

Thanks for the time

Clean up the PHP code

I don't want to undermine the efforts of others, but I rewrote the PHP code in the article that parses demo files in a way that I believe is more readable, understandable, and flexible. I'm submitting this to the Talk page so that others can chip in and edit the proposed new code as they see fit, especially if the original author wants to keep their credit, as this was largely based off of their work. (I don't know if or how you can "ping" users on Wikimedia sites - could someone do that for me?)

Click to show/hide code
    <?
    // For the purposes of this program, the following
    // pairs of types and byte sizes are provided:
    // - int: 4 bytes (eqv. of int32_t)
    // - float: 4 bytes (eqv. of float32_t)
    // - string: N bytes (eqv. of char[N])

    class DemoInfo {
      public string $fileMagic;
      public int $demoProtoVersion;
      public int $netProtoVersion;
      public string $serverName;
      public string $clientName;
      public string $mapName;
      public string $gameDirectory;
      public float $playbackSeconds;
      public int $demoTickCount;
      public int $demoFrameCount;
      public int $signOnLength;
    }

    function getFileExtension (string $path) {
      $parts = explode('.', $path);
      return end($parts);
    }

    function readString ($handle, int $length = 260) {
      return unpack('a*', fread($handle, $length))[1];
    }

    function readInt ($handle) {
      return unpack('i', fread($handle, 4))[1];
    }

    function readFloat ($handle) {
      return unpack('f', fread($handle, 4))[1];
    }

    function isValidAddress (string $address) {
      $parts = explode(':', $address);

      if (count($parts) !== 2) {
        trigger_error("address should contain a hostname and a port", E_USER_ERROR);
        return false;
      }

      $host = $parts[0];
      $port = trim($parts[1]);

      if (!filter_var($host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
        trigger_error("invalid hostname in address", E_USER_ERROR);
        return false;
      }

      if (!is_numeric($port) || (int)$port < 0 || (int)$port > 65535) {
        trigger_error("invalid port in address", E_USER_ERROR);
        return false;
      }

      return true;
    }

    function parseDemoHeader (string $path, bool $strict = true) {
      if ($strict && getFileExtension($path) !== 'dem') {
        trigger_error("expected a .dem file", E_USER_WARNING);
        return null;
      }

      $header = new DemoInfo();
      $handle = fopen($path, 'rb');

      if (!$handle) {
        trigger_error("could not open file {$path}", E_USER_ERROR);
        return null;
      }

      $header->fileMagic = readString($handle, 8);
      if ($header->fileMagic !== "HL2DEMO\0") {
        trigger_error("invalid file magic '{$header->fileMagic}'", E_USER_ERROR);
        return null;
      }

      $header->demoProtoVersion = readInt($handle);
      $header->netProtoVersion = readInt($handle);
      $header->serverName = readString($handle, 260);
      $header->clientName = readString($handle, 260);
      $header->mapName = readString($handle, 260);
      $header->gameDirectory = readString($handle, 260);
      $header->playbackSeconds = readFloat($handle);
      $header->demoTickCount = readInt($handle);
      $header->demoFrameCount = readInt($handle);

      if ($strict && !isValidAddress($header->serverName)) {
        return null;
      }

      return $header;
    }
    ?>

--Furry (talk) 11:27, 11 December 2023 (PST)