arkmanager / ark-server-tools

Set of server tools used to manage ARK: Survival Evolved servers on Linux
MIT License
678 stars 143 forks source link

Ask a question about mod #1178

Open Niexiawei opened 3 years ago

Niexiawei commented 3 years ago

Can you tell me how to decompress the mod file And how to generate xxxxx.mod files He didn't mention it in official documents

klightspeed commented 3 years ago

The mod file decompression is at https://github.com/arkmanager/ark-server-tools/blob/master/tools/arkmanager#L2755-L2788

find "$modsrcdir" -type f -name '*.z' -printf "%P\n" | while read -r f; do
  if [ ! -f "$modextractdir/${f%.z}" ] || [ "$modsrcdir/$f" -nt "$modextractdir/${f%.z}" ]; then
    printf "%10d  %s  " "$(stat -c '%s' "$modsrcdir/$f")" "${f%.z}"
    perl -M'Compress::Raw::Zlib' -e '
      my $sig;
      read(STDIN, $sig, 8) or die "Unable to read compressed file: $!";
      if ($sig != "\xC1\x83\x2A\x9E\x00\x00\x00\x00"){
        die "Bad file magic";
      }
      my $data;
      read(STDIN, $data, 24) or die "Unable to read compressed file: $!";
      my ($chunksizelo, $chunksizehi,
          $comprtotlo,  $comprtothi,
          $uncomtotlo,  $uncomtothi)  = unpack("(LLLLLL)<", $data);
      my @chunks = ();
      my $comprused = 0;
      while ($comprused < $comprtotlo) {
        read(STDIN, $data, 16) or die "Unable to read compressed file: $!";
        my ($comprsizelo, $comprsizehi,
            $uncomsizelo, $uncomsizehi) = unpack("(LLLL)<", $data);
        push @chunks, $comprsizelo;
        $comprused += $comprsizelo;
      }
      foreach my $comprsize (@chunks) {
        read(STDIN, $data, $comprsize) or die "File read failed: $!";
        my ($inflate, $status) = new Compress::Raw::Zlib::Inflate();
        my $output;
        $status = $inflate->inflate($data, $output, 1);
        if ($status != Z_STREAM_END) {
          die "Bad compressed stream; status: " . ($status);
        }
        if (length($data) != 0) {
          die "Unconsumed data in input"
        }
        print $output;
      }
    ' <"$modsrcdir/$f" >"$modextractdir/${f%.z}"
    touch -c -r "$modsrcdir/$f" "$modextractdir/${f%.z}"
    echo -ne "\r\\033[K"
  fi
done

The .mod file creation is at https://github.com/arkmanager/ark-server-tools/blob/master/tools/arkmanager#L2800-L2827

perl -e '
  my $data;
  { local $/; $data = <STDIN>; }
  my $mapnamelen = unpack("@0 L<", $data);
  my $mapname = substr($data, 4, $mapnamelen - 1);
  my $nummaps = unpack("@" . ($mapnamelen + 4) . " L<", $data);
  my $pos = $mapnamelen + 8;
  my $modname = ($ARGV[2] || $mapname) . "\x00";
  my $modnamelen = length($modname);
  my $modpath = "../../../" . $ARGV[0] . "/Content/Mods/" . $ARGV[1] . "\x00";
  my $modpathlen = length($modpath);
  print pack("L< L< L< Z$modnamelen L< Z$modpathlen L<",
    $ARGV[1], 0, $modnamelen, $modname, $modpathlen, $modpath,
    $nummaps);
  for (my $mapnum = 0; $mapnum < $nummaps; $mapnum++){
    my $mapfilelen = unpack("@" . ($pos) . " L<", $data);
    my $mapfile = substr($data, $mapnamelen + 12, $mapfilelen);
    print pack("L< Z$mapfilelen", $mapfilelen, $mapfile);
    $pos = $pos + 4 + $mapfilelen;
  }
  print "\x33\xFF\x22\xFF\x02\x00\x00\x00\x01";
' "$arkserverdir" "$modid" "$modname" <"$modextractdir/mod.info" >"${modextractdir}.mod"
if [ -f "$modextractdir/modmeta.info" ]; then
  cat "$modextractdir/modmeta.info" >>"${modextractdir}.mod"
else
  echo -ne '\x01\x00\x00\x00\x08\x00\x00\x00ModType\x00\x02\x00\x00\x001\x00' >>"${modextractdir}.mod"
fi
Niexiawei commented 3 years ago

😊 😊 thank you