Skip to content

Instantly share code, notes, and snippets.

@kphrx
Last active August 14, 2020 19:36
Show Gist options
  • Save kphrx/caf3c10e8d273630e1620ecb89f3e2d7 to your computer and use it in GitHub Desktop.
Save kphrx/caf3c10e8d273630e1620ecb89f3e2d7 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use feature qw(say);
use strict;
use warnings;
use Cwd 'abs_path';
use File::Basename 'dirname';
use File::Spec;
use Getopt::Long 'GetOptions';
use JSON::PP;
use LWP::Simple 'head', 'get', 'getstore', 'is_success';
use Pod::Usage 'pod2usage';
=head1 NAME
minecraft-forge-downloader.pl - Download MinecraftForge Installer
=head1 SYNOPSIS
minecraft-forge-downloader.pl [options]
Options:
-h, -help usage
-man manpage
-v, -verbose verbose log
-m, -minecraft-version=MINECRAFT_VERSION minecraft version
(default: 1.16.2)
-l, -latest download latest forge version
=head1 OPTIONS
=over 4
=item B<-h|-help>
Print this usage.
=item B<-man>
Output manpage.
=item B<-v|-verbose>
Print verbose output.
=item B<-o|-outout-directory>
Set directory for saving forge installer. Default script path.
=item B<-m|-minecraft-version>
Set minecraft version for forge installer.
=item B<-l|-latest>
Download latest forge version. This flag has priority over `-forge-version`.
=item B<-f|-forge-version>
Download fixed forge version. If set 'recommended' or 'latest', download recommended|latest version.
* If hasn't recommended version, download latest version.
=item B<-b|-forge-branch>
Forge branch name. Some version has branch name, so needed this flag.
=back
=cut
sub err {
my ($msg) = @_;
say "Error: $msg";
exit 1;
}
sub getForgeVersion {
my ($version, $latest, $forgeVersion) = @_;
my $json = get 'http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json';
err 'Couldn\'t get forge versions!' unless defined $json;
my $vers = JSON::PP->new->utf8->decode($json);
my $homepage = $vers->{'homepage'};
return ($homepage, $forgeVersion, undef) if $latest == -1;
my $promos = $vers->{'promos'};
if ($latest != 1 && (my $recommended = $promos->{"$version-recommended"})) {
return ($homepage, $recommended, 'recommended');
} elsif (my $latest = $promos->{"$version-latest"}) {
return ($homepage, $latest, 'latest');
}
err 'Not found forge version!';
}
sub forgeJarInfo {
my ($resourceURL, $mcVer, $forgeVer, $branch) = @_;
for my $version ("$mcVer-$forgeVer", "$mcVer-$forgeVer-$branch") {
my $url = "$resourceURL/$version/forge-$version-installer.jar";
if (head $url) {
return ($url, "forge-$version-installer.jar");
}
}
err 'Couldn\'t find forge installer!';
}
my ($help, $manual, $verbose, $latest, $versionLabel, $forgeBranch, $resourceURL);
my $outputDirectory = dirname abs_path $0;
my $minecraftVersion = '1.16.2';
my $forgeVersion = 'recommended';
GetOptions (
'h|help' => \$help,
'man' => \$manual,
'v|verbose' => \$verbose,
'l|latest' => \$latest,
'o|outout-directory=s' => \$outputDirectory,
'm|minecraft-version=s' => \$minecraftVersion,
'f|forge-version=s' => \$forgeVersion,
'b|forge-branch=s' => \$forgeBranch,
) || pod2usage;
pod2usage (-exitval => 0, -verbose => 1) if $help;
pod2usage (-exitval => 0, -verbose => 2) if $manual;
say 'Verbose Mode' if $verbose;
if ($latest || defined $forgeVersion && $forgeVersion eq 'latest') {
($resourceURL, $forgeVersion, $versionLabel) = getForgeVersion $minecraftVersion, 1;
} elsif (!defined $forgeVersion || $forgeVersion eq 'recommended') {
($resourceURL, $forgeVersion, $versionLabel) = getForgeVersion $minecraftVersion, 0;
} else {
($resourceURL, $forgeVersion) = getForgeVersion $minecraftVersion, -1, $forgeVersion;
}
print "Version: $minecraftVersion-$forgeVersion" if $verbose;
print "-$forgeBranch" if $verbose && $forgeBranch;
print " ($versionLabel)" if $verbose && $versionLabel;
print "\n" if $verbose;
say "Output Directory: $outputDirectory" if $verbose;
$forgeBranch = $minecraftVersion unless defined $forgeBranch;
my ($url, $name) = forgeJarInfo $resourceURL, $minecraftVersion, $forgeVersion, $forgeBranch;
my $saveFile = File::Spec->catfile($outputDirectory, $name);
say "Downloading: $url";
if (is_success getstore($url, $saveFile)) {
say 'Success!';
say "Save to: $saveFile";
} else {
err 'Failed!';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment