div0test is no more
[divverent/nexuiz.git] / misc / demosplit.pl
1 #!/usr/bin/perl
2
3 # usage:
4 #   ./demosplit.pl demo.dem
5 # splits the demo into separate demos for each map played and writes them
6 # to demo-0000.dem, demo-0001.dem ...
7
8 use strict;
9 use warnings;
10
11 # constants
12 my $svc_signon = "\001";
13
14 # opening the files
15
16 die "Usage: $0 infile"
17         if @ARGV != 1;
18 my ($in) = @ARGV;
19
20 my $demoname = [$in =~ /^(.*)\.dem$/]->[0];
21 $demoname = "out"
22         if not defined $demoname;
23
24 open my $infh, "<", $in
25         or die "open $in: $!";
26 binmode $infh;
27
28 # 1. CD track
29
30 $/ = "\012";
31 my $cdtrack = <$infh>;
32
33 # 2. packets
34
35 my $outfh;
36 my $outnum = 0;
37
38 for(;;)
39 {
40         last
41                 unless 4 == read $infh, my $length, 4;
42         $length = unpack("V", $length);
43         die "Invalid demo packet"
44                 unless 12 == read $infh, my $angles, 12;
45         die "Invalid demo packet"
46                 unless $length == read $infh, my($data), $length;
47
48         if($data =~ m{
49                 ^
50                 $svc_signon
51                 $
52         }sx)
53         {
54                 close $outfh
55                         if $outfh;
56                 my $outname = sprintf("%s-%04d.dem", $demoname, $outnum++);
57                 open $outfh, ">", $outname
58                         or die "open $outname: $!";
59                 binmode $outfh;
60                 print $outfh $cdtrack;
61                 print "Writing to $outname...\n";
62         }
63
64         die "No signon received"
65                 unless $outfh;
66         print $outfh pack("V", length $data);
67         print $outfh $angles;
68         print $outfh $data;
69 }
70
71 close $outfh;
72 close $infh;