mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-08 21:24:03 +00:00
factorio-experimental: 2.0.8 -> 2.0.9 (#350528)
This commit is contained in:
commit
dd38576ba9
310
pkgs/by-name/fa/factorio/package.nix
Normal file
310
pkgs/by-name/fa/factorio/package.nix
Normal file
@ -0,0 +1,310 @@
|
||||
{
|
||||
lib,
|
||||
alsa-lib,
|
||||
factorio-utils,
|
||||
fetchurl,
|
||||
libGL,
|
||||
libICE,
|
||||
libSM,
|
||||
libX11,
|
||||
libXcursor,
|
||||
libXext,
|
||||
libXi,
|
||||
libXinerama,
|
||||
libXrandr,
|
||||
libpulseaudio,
|
||||
libxkbcommon,
|
||||
makeDesktopItem,
|
||||
makeWrapper,
|
||||
releaseType,
|
||||
stdenv,
|
||||
wayland,
|
||||
|
||||
mods-dat ? null,
|
||||
versionsJson ? ./versions.json,
|
||||
username ? "",
|
||||
token ? "", # get/reset token at https://factorio.com/profile
|
||||
experimental ? false, # true means to always use the latest branch
|
||||
...
|
||||
}@args:
|
||||
|
||||
assert
|
||||
releaseType == "alpha"
|
||||
|| releaseType == "headless"
|
||||
|| releaseType == "demo"
|
||||
|| releaseType == "expansion";
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) importJSON;
|
||||
|
||||
mods = args.mods or [ ];
|
||||
|
||||
helpMsg = ''
|
||||
|
||||
===FETCH FAILED===
|
||||
Please ensure you have set the username and token with config.nix, or
|
||||
/etc/nix/nixpkgs-config.nix if on NixOS.
|
||||
|
||||
Your token can be seen at https://factorio.com/profile (after logging in). It is
|
||||
not as sensitive as your password, but should still be safeguarded. There is a
|
||||
link on that page to revoke/invalidate the token, if you believe it has been
|
||||
leaked or wish to take precautions.
|
||||
|
||||
Example:
|
||||
{
|
||||
packageOverrides = pkgs: {
|
||||
factorio = pkgs.factorio.override {
|
||||
username = "FactorioPlayer1654";
|
||||
token = "d5ad5a8971267c895c0da598688761";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Alternatively, instead of providing the username+token, you may manually
|
||||
download the release through https://factorio.com/download , then add it to
|
||||
the store using e.g.:
|
||||
|
||||
releaseType=alpha
|
||||
version=0.17.74
|
||||
nix-prefetch-url file://\''$HOME/Downloads/factorio_\''${releaseType}_x64_\''${version}.tar.xz --name factorio_\''${releaseType}_x64-\''${version}.tar.xz
|
||||
|
||||
Note the ultimate "_" is replaced with "-" in the --name arg!
|
||||
'';
|
||||
|
||||
desktopItem = makeDesktopItem {
|
||||
name = "factorio";
|
||||
desktopName = "Factorio";
|
||||
comment = "A game in which you build and maintain factories.";
|
||||
exec = "factorio";
|
||||
icon = "factorio";
|
||||
categories = [ "Game" ];
|
||||
};
|
||||
|
||||
branch = if experimental then "experimental" else "stable";
|
||||
|
||||
# NB `experimental` directs us to take the latest build, regardless of its branch;
|
||||
# hence the (stable, experimental) pairs may sometimes refer to the same distributable.
|
||||
versions = importJSON versionsJson;
|
||||
binDists = makeBinDists versions;
|
||||
|
||||
actual =
|
||||
binDists.${stdenv.hostPlatform.system}.${releaseType}.${branch}
|
||||
or (throw "Factorio ${releaseType}-${branch} binaries for ${stdenv.hostPlatform.system} are not available for download.");
|
||||
|
||||
makeBinDists =
|
||||
versions:
|
||||
let
|
||||
f =
|
||||
path: name: value:
|
||||
if builtins.isAttrs value then
|
||||
if value ? "name" then makeBinDist value else builtins.mapAttrs (f (path ++ [ name ])) value
|
||||
else
|
||||
throw "expected attrset at ${toString path} - got ${toString value}";
|
||||
in
|
||||
builtins.mapAttrs (f [ ]) versions;
|
||||
makeBinDist =
|
||||
{
|
||||
name,
|
||||
version,
|
||||
tarDirectory,
|
||||
url,
|
||||
sha256,
|
||||
needsAuth,
|
||||
candidateHashFilenames ? [ ],
|
||||
}:
|
||||
{
|
||||
inherit version tarDirectory;
|
||||
src =
|
||||
if !needsAuth then
|
||||
fetchurl { inherit name url sha256; }
|
||||
else
|
||||
(lib.overrideDerivation
|
||||
(fetchurl {
|
||||
inherit name url sha256;
|
||||
curlOptsList = [
|
||||
"--get"
|
||||
"--data-urlencode"
|
||||
"username@username"
|
||||
"--data-urlencode"
|
||||
"token@token"
|
||||
];
|
||||
})
|
||||
(_: {
|
||||
# This preHook hides the credentials from /proc
|
||||
preHook =
|
||||
if username != "" && token != "" then
|
||||
''
|
||||
echo -n "${username}" >username
|
||||
echo -n "${token}" >token
|
||||
''
|
||||
else
|
||||
''
|
||||
# Deliberately failing since username/token was not provided, so we can't fetch.
|
||||
# We can't use builtins.throw since we want the result to be used if the tar is in the store already.
|
||||
exit 1
|
||||
'';
|
||||
failureHook = ''
|
||||
cat <<EOF
|
||||
${helpMsg}
|
||||
EOF
|
||||
'';
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
configBaseCfg = ''
|
||||
use-system-read-write-data-directories=false
|
||||
[path]
|
||||
read-data=$out/share/factorio/data/
|
||||
[other]
|
||||
check_updates=false
|
||||
'';
|
||||
|
||||
updateConfigSh = ''
|
||||
#! $SHELL
|
||||
if [[ -e ~/.factorio/config.cfg ]]; then
|
||||
# Config file exists, but may have wrong path.
|
||||
# Try to edit it. I'm sure this is perfectly safe and will never go wrong.
|
||||
sed -i 's|^read-data=.*|read-data=$out/share/factorio/data/|' ~/.factorio/config.cfg
|
||||
else
|
||||
# Config file does not exist. Phew.
|
||||
install -D $out/share/factorio/config-base.cfg ~/.factorio/config.cfg
|
||||
fi
|
||||
'';
|
||||
|
||||
modDir = factorio-utils.mkModDirDrv mods mods-dat;
|
||||
|
||||
base = with actual; {
|
||||
# remap -expansion to -space-age to better match the attr name in nixpkgs.
|
||||
pname = "factorio-${if releaseType == "expansion" then "space-age" else releaseType}";
|
||||
inherit version src;
|
||||
|
||||
preferLocalBuild = true;
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/{bin,share/factorio}
|
||||
cp -a data $out/share/factorio
|
||||
cp -a bin/${tarDirectory}/factorio $out/bin/factorio
|
||||
patchelf \
|
||||
--set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
|
||||
$out/bin/factorio
|
||||
'';
|
||||
|
||||
passthru.updateScript =
|
||||
if (username != "" && token != "") then
|
||||
[
|
||||
./update.py
|
||||
"--username=${username}"
|
||||
"--token=${token}"
|
||||
]
|
||||
else
|
||||
null;
|
||||
|
||||
meta = {
|
||||
description = "Game in which you build and maintain factories";
|
||||
longDescription = ''
|
||||
Factorio is a game in which you build and maintain factories.
|
||||
|
||||
You will be mining resources, researching technologies, building
|
||||
infrastructure, automating production and fighting enemies. Use your
|
||||
imagination to design your factory, combine simple elements into
|
||||
ingenious structures, apply management skills to keep it working and
|
||||
finally protect it from the creatures who don't really like you.
|
||||
|
||||
Factorio has been in development since spring of 2012, and reached
|
||||
version 1.0 in mid 2020.
|
||||
'';
|
||||
homepage = "https://www.factorio.com/";
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
|
||||
license = lib.licenses.unfree;
|
||||
maintainers = with lib.maintainers; [
|
||||
Baughn
|
||||
elitak
|
||||
priegger
|
||||
lukegb
|
||||
];
|
||||
platforms = [ "x86_64-linux" ];
|
||||
mainProgram = "factorio";
|
||||
};
|
||||
};
|
||||
|
||||
releases = rec {
|
||||
headless = base;
|
||||
demo = base // {
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
buildInputs = [ libpulseaudio ];
|
||||
|
||||
libPath = lib.makeLibraryPath [
|
||||
alsa-lib
|
||||
libGL
|
||||
libICE
|
||||
libSM
|
||||
libX11
|
||||
libXcursor
|
||||
libXext
|
||||
libXi
|
||||
libXinerama
|
||||
libXrandr
|
||||
libpulseaudio
|
||||
libxkbcommon
|
||||
wayland
|
||||
];
|
||||
|
||||
installPhase =
|
||||
base.installPhase
|
||||
+ ''
|
||||
wrapProgram $out/bin/factorio \
|
||||
--prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:$libPath \
|
||||
--run "$out/share/factorio/update-config.sh" \
|
||||
--argv0 "" \
|
||||
--add-flags "-c \$HOME/.factorio/config.cfg" \
|
||||
${lib.optionalString (mods != [ ]) "--add-flags --mod-directory=${modDir}"}
|
||||
|
||||
# TODO Currently, every time a mod is changed/added/removed using the
|
||||
# modlist, a new derivation will take up the entire footprint of the
|
||||
# client. The only way to avoid this is to remove the mods arg from the
|
||||
# package function. The modsDir derivation will have to be built
|
||||
# separately and have the user specify it in the .factorio config or
|
||||
# right along side it using a symlink into the store I think i will
|
||||
# just remove mods for the client derivation entirely. this is much
|
||||
# cleaner and more useful for headless mode.
|
||||
|
||||
# TODO: trying to toggle off a mod will result in read-only-fs-error.
|
||||
# not much we can do about that except warn the user somewhere. In
|
||||
# fact, no exit will be clean, since this error will happen on close
|
||||
# regardless. just prints an ugly stacktrace but seems to be otherwise
|
||||
# harmless, unless maybe the user forgets and tries to use the mod
|
||||
# manager.
|
||||
|
||||
install -m0644 <(cat << EOF
|
||||
${configBaseCfg}
|
||||
EOF
|
||||
) $out/share/factorio/config-base.cfg
|
||||
|
||||
install -m0755 <(cat << EOF
|
||||
${updateConfigSh}
|
||||
EOF
|
||||
) $out/share/factorio/update-config.sh
|
||||
|
||||
mkdir -p $out/share/icons/hicolor/{64x64,128x128}/apps
|
||||
cp -a data/core/graphics/factorio-icon.png $out/share/icons/hicolor/64x64/apps/factorio.png
|
||||
cp -a data/core/graphics/factorio-icon@2x.png $out/share/icons/hicolor/128x128/apps/factorio.png
|
||||
ln -s ${desktopItem}/share/applications $out/share/
|
||||
'';
|
||||
};
|
||||
alpha = demo // {
|
||||
|
||||
installPhase =
|
||||
demo.installPhase
|
||||
+ ''
|
||||
cp -a doc-html $out/share/factorio
|
||||
'';
|
||||
};
|
||||
expansion = alpha;
|
||||
};
|
||||
|
||||
in
|
||||
stdenv.mkDerivation (releases.${releaseType})
|
289
pkgs/by-name/fa/factorio/update.py
Executable file
289
pkgs/by-name/fa/factorio/update.py
Executable file
@ -0,0 +1,289 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python -p "python3.withPackages (ps: with ps; [ ps.absl-py ps.requests ])"
|
||||
|
||||
from collections import defaultdict
|
||||
import copy
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
import os.path
|
||||
from typing import Callable, Dict
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from absl import logging
|
||||
import requests
|
||||
|
||||
|
||||
FACTORIO_RELEASES = "https://factorio.com/api/latest-releases"
|
||||
FACTORIO_HASHES = "https://factorio.com/download/sha256sums/"
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
flags.DEFINE_string("out", "", "Output path for versions.json.")
|
||||
flags.DEFINE_list(
|
||||
"release_type",
|
||||
"",
|
||||
"If non-empty, a comma-separated list of release types to update (e.g. alpha).",
|
||||
)
|
||||
flags.DEFINE_list(
|
||||
"release_channel",
|
||||
"",
|
||||
"If non-empty, a comma-separated list of release channels to update (e.g. experimental).",
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class System:
|
||||
nix_name: str
|
||||
url_name: str
|
||||
tar_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReleaseType:
|
||||
name: str
|
||||
hash_filename_format: list[str]
|
||||
needs_auth: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReleaseChannel:
|
||||
name: str
|
||||
|
||||
|
||||
FactorioVersionsJSON = Dict[str, Dict[str, str]]
|
||||
OurVersionJSON = Dict[str, Dict[str, Dict[str, Dict[str, str]]]]
|
||||
|
||||
FactorioHashes = Dict[str, str]
|
||||
|
||||
|
||||
SYSTEMS = [
|
||||
System(nix_name="x86_64-linux", url_name="linux64", tar_name="x64"),
|
||||
]
|
||||
|
||||
RELEASE_TYPES = [
|
||||
ReleaseType(
|
||||
"alpha",
|
||||
needs_auth=True,
|
||||
hash_filename_format=["factorio_linux_{version}.tar.xz"],
|
||||
),
|
||||
ReleaseType("demo", hash_filename_format=["factorio_demo_x64_{version}.tar.xz"]),
|
||||
ReleaseType(
|
||||
"headless",
|
||||
hash_filename_format=[
|
||||
"factorio-headless_linux_{version}.tar.xz",
|
||||
"factorio_headless_x64_{version}.tar.xz",
|
||||
],
|
||||
),
|
||||
ReleaseType(
|
||||
"expansion",
|
||||
needs_auth=True,
|
||||
hash_filename_format=["factorio-space-age_linux_{version}.tar.xz"],
|
||||
),
|
||||
]
|
||||
|
||||
RELEASE_CHANNELS = [
|
||||
ReleaseChannel("experimental"),
|
||||
ReleaseChannel("stable"),
|
||||
]
|
||||
|
||||
|
||||
def find_versions_json() -> str:
|
||||
if FLAGS.out:
|
||||
return FLAGS.out
|
||||
try_paths = ["pkgs/by-name/fa/factorio/versions.json", "versions.json"]
|
||||
for path in try_paths:
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
raise Exception(
|
||||
"Couldn't figure out where to write versions.json; try specifying --out"
|
||||
)
|
||||
|
||||
|
||||
def fetch_versions() -> FactorioVersionsJSON:
|
||||
return json.loads(requests.get(FACTORIO_RELEASES).text)
|
||||
|
||||
|
||||
def fetch_hashes() -> FactorioHashes:
|
||||
resp = requests.get(FACTORIO_HASHES)
|
||||
resp.raise_for_status()
|
||||
out = {}
|
||||
for ln in resp.text.split("\n"):
|
||||
ln = ln.strip()
|
||||
if not ln:
|
||||
continue
|
||||
sha256, filename = ln.split()
|
||||
out[filename] = sha256
|
||||
return out
|
||||
|
||||
|
||||
def generate_our_versions(factorio_versions: FactorioVersionsJSON) -> OurVersionJSON:
|
||||
def rec_dd():
|
||||
return defaultdict(rec_dd)
|
||||
|
||||
output = rec_dd()
|
||||
|
||||
# Deal with times where there's no experimental version
|
||||
for rc in RELEASE_CHANNELS:
|
||||
if rc.name not in factorio_versions or not factorio_versions[rc.name]:
|
||||
factorio_versions[rc.name] = factorio_versions["stable"]
|
||||
for rt in RELEASE_TYPES:
|
||||
if (
|
||||
rt.name not in factorio_versions[rc.name]
|
||||
or not factorio_versions[rc.name][rt.name]
|
||||
):
|
||||
factorio_versions[rc.name][rt.name] = factorio_versions["stable"][
|
||||
rt.name
|
||||
]
|
||||
|
||||
for system in SYSTEMS:
|
||||
for release_type in RELEASE_TYPES:
|
||||
for release_channel in RELEASE_CHANNELS:
|
||||
version = factorio_versions[release_channel.name].get(release_type.name)
|
||||
if version is None:
|
||||
continue
|
||||
this_release = {
|
||||
"name": f"factorio_{release_type.name}_{system.tar_name}-{version}.tar.xz",
|
||||
"url": f"https://factorio.com/get-download/{version}/{release_type.name}/{system.url_name}",
|
||||
"version": version,
|
||||
"needsAuth": release_type.needs_auth,
|
||||
"candidateHashFilenames": [
|
||||
fmt.format(version=version)
|
||||
for fmt in release_type.hash_filename_format
|
||||
],
|
||||
"tarDirectory": system.tar_name,
|
||||
}
|
||||
output[system.nix_name][release_type.name][release_channel.name] = (
|
||||
this_release
|
||||
)
|
||||
return output
|
||||
|
||||
|
||||
def iter_version(
|
||||
versions: OurVersionJSON,
|
||||
it: Callable[[str, str, str, Dict[str, str]], Dict[str, str]],
|
||||
) -> OurVersionJSON:
|
||||
versions = copy.deepcopy(versions)
|
||||
for system_name, system in versions.items():
|
||||
for release_type_name, release_type in system.items():
|
||||
for release_channel_name, release in release_type.items():
|
||||
release_type[release_channel_name] = it(
|
||||
system_name, release_type_name, release_channel_name, dict(release)
|
||||
)
|
||||
return versions
|
||||
|
||||
|
||||
def merge_versions(old: OurVersionJSON, new: OurVersionJSON) -> OurVersionJSON:
|
||||
"""Copies already-known hashes from version.json to avoid having to re-fetch."""
|
||||
|
||||
def _merge_version(
|
||||
system_name: str,
|
||||
release_type_name: str,
|
||||
release_channel_name: str,
|
||||
release: Dict[str, str],
|
||||
) -> Dict[str, str]:
|
||||
old_system = old.get(system_name, {})
|
||||
old_release_type = old_system.get(release_type_name, {})
|
||||
old_release = old_release_type.get(release_channel_name, {})
|
||||
if FLAGS.release_type and release_type_name not in FLAGS.release_type:
|
||||
logging.info(
|
||||
"%s/%s/%s: not in --release_type, not updating",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
)
|
||||
return old_release
|
||||
if FLAGS.release_channel and release_channel_name not in FLAGS.release_channel:
|
||||
logging.info(
|
||||
"%s/%s/%s: not in --release_channel, not updating",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
)
|
||||
return old_release
|
||||
if "sha256" not in old_release:
|
||||
logging.info(
|
||||
"%s/%s/%s: not copying sha256 since it's missing",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
)
|
||||
return release
|
||||
if not all(
|
||||
old_release.get(k, None) == release[k] for k in ["name", "version", "url"]
|
||||
):
|
||||
logging.info(
|
||||
"%s/%s/%s: not copying sha256 due to mismatch",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
)
|
||||
return release
|
||||
release["sha256"] = old_release["sha256"]
|
||||
return release
|
||||
|
||||
return iter_version(new, _merge_version)
|
||||
|
||||
|
||||
def fill_in_hash(
|
||||
versions: OurVersionJSON, factorio_hashes: FactorioHashes
|
||||
) -> OurVersionJSON:
|
||||
"""Fill in sha256 hashes for anything missing them."""
|
||||
|
||||
def _fill_in_hash(
|
||||
system_name: str,
|
||||
release_type_name: str,
|
||||
release_channel_name: str,
|
||||
release: Dict[str, str],
|
||||
) -> Dict[str, str]:
|
||||
for candidate_filename in release["candidateHashFilenames"]:
|
||||
if candidate_filename in factorio_hashes:
|
||||
release["sha256"] = factorio_hashes[candidate_filename]
|
||||
break
|
||||
else:
|
||||
logging.error(
|
||||
"%s/%s/%s: failed to find any of %s in %s",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
release["candidateHashFilenames"],
|
||||
FACTORIO_HASHES,
|
||||
)
|
||||
return release
|
||||
if "sha256" in release:
|
||||
logging.info(
|
||||
"%s/%s/%s: skipping fetch, sha256 already present",
|
||||
system_name,
|
||||
release_type_name,
|
||||
release_channel_name,
|
||||
)
|
||||
return release
|
||||
return release
|
||||
|
||||
return iter_version(versions, _fill_in_hash)
|
||||
|
||||
|
||||
def main(argv):
|
||||
factorio_versions = fetch_versions()
|
||||
factorio_hashes = fetch_hashes()
|
||||
new_our_versions = generate_our_versions(factorio_versions)
|
||||
old_our_versions = None
|
||||
our_versions_path = find_versions_json()
|
||||
if our_versions_path:
|
||||
logging.info("Loading old versions.json from %s", our_versions_path)
|
||||
with open(our_versions_path, "r") as f:
|
||||
old_our_versions = json.load(f)
|
||||
if old_our_versions:
|
||||
logging.info("Merging in old hashes")
|
||||
new_our_versions = merge_versions(old_our_versions, new_our_versions)
|
||||
logging.info("Updating hashes from Factorio SHA256")
|
||||
new_our_versions = fill_in_hash(new_our_versions, factorio_hashes)
|
||||
with open(our_versions_path, "w") as f:
|
||||
logging.info("Writing versions.json to %s", our_versions_path)
|
||||
json.dump(new_our_versions, f, sort_keys=True, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(main)
|
102
pkgs/by-name/fa/factorio/versions.json
Normal file
102
pkgs/by-name/fa/factorio/versions.json
Normal file
@ -0,0 +1,102 @@
|
||||
{
|
||||
"x86_64-linux": {
|
||||
"alpha": {
|
||||
"experimental": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio_linux_2.0.9.tar.xz"
|
||||
],
|
||||
"name": "factorio_alpha_x64-2.0.9.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "34c21cd3cbe91b65483786ccb4467b5d4766c748cbbddd2ce3b30d319d163e3b",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.9/alpha/linux64",
|
||||
"version": "2.0.9"
|
||||
},
|
||||
"stable": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio_linux_2.0.8.tar.xz"
|
||||
],
|
||||
"name": "factorio_alpha_x64-2.0.8.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "94ea36a5b9103369df7158a8281039dd2f1d7fa7bb3a2d854c715250dd73e185",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/alpha/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
},
|
||||
"demo": {
|
||||
"experimental": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio_demo_x64_1.1.110.tar.xz"
|
||||
],
|
||||
"name": "factorio_demo_x64-1.1.110.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "bddb91dcba9f300c25d590f861772eaf41f0b6ce8ae6b754de00d0e5f3eb5a35",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/1.1.110/demo/linux64",
|
||||
"version": "1.1.110"
|
||||
},
|
||||
"stable": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio_demo_x64_1.1.110.tar.xz"
|
||||
],
|
||||
"name": "factorio_demo_x64-1.1.110.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "bddb91dcba9f300c25d590f861772eaf41f0b6ce8ae6b754de00d0e5f3eb5a35",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/1.1.110/demo/linux64",
|
||||
"version": "1.1.110"
|
||||
}
|
||||
},
|
||||
"expansion": {
|
||||
"experimental": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio-space-age_linux_2.0.9.tar.xz"
|
||||
],
|
||||
"name": "factorio_expansion_x64-2.0.9.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "6369d23550a7a721d3de1d34253e8321ee601fa759d1fb5efac9abc28aa7509d",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.9/expansion/linux64",
|
||||
"version": "2.0.9"
|
||||
},
|
||||
"stable": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio-space-age_linux_2.0.8.tar.xz"
|
||||
],
|
||||
"name": "factorio_expansion_x64-2.0.8.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "408eae824daa761564b1ea7b81925efe05298cbaffd120eea235341ac05a6a60",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/expansion/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
},
|
||||
"headless": {
|
||||
"experimental": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio-headless_linux_2.0.9.tar.xz",
|
||||
"factorio_headless_x64_2.0.9.tar.xz"
|
||||
],
|
||||
"name": "factorio_headless_x64-2.0.9.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "f499077b3e2c1313452c350f1faf17db31cae2a0fa738f69166e97c3caa3c86d",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.9/headless/linux64",
|
||||
"version": "2.0.9"
|
||||
},
|
||||
"stable": {
|
||||
"candidateHashFilenames": [
|
||||
"factorio-headless_linux_2.0.8.tar.xz",
|
||||
"factorio_headless_x64_2.0.8.tar.xz"
|
||||
],
|
||||
"name": "factorio_headless_x64-2.0.8.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "d9594c4d552a3e4f965b188a4774da8c8b010fc23ddb0efc63b1d94818dde1ca",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/headless/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
{ lib
|
||||
, alsa-lib
|
||||
, factorio-utils
|
||||
, fetchurl
|
||||
, libGL
|
||||
, libICE
|
||||
, libSM
|
||||
, libX11
|
||||
, libXcursor
|
||||
, libXext
|
||||
, libXi
|
||||
, libXinerama
|
||||
, libXrandr
|
||||
, libpulseaudio
|
||||
, libxkbcommon
|
||||
, makeDesktopItem
|
||||
, makeWrapper
|
||||
, releaseType
|
||||
, stdenv
|
||||
, wayland
|
||||
|
||||
, mods-dat ? null
|
||||
, versionsJson ? ./versions.json
|
||||
, username ? ""
|
||||
, token ? "" # get/reset token at https://factorio.com/profile
|
||||
, experimental ? false # true means to always use the latest branch
|
||||
, ...
|
||||
} @ args:
|
||||
|
||||
assert releaseType == "alpha"
|
||||
|| releaseType == "headless"
|
||||
|| releaseType == "demo"
|
||||
|| releaseType == "expansion";
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) importJSON;
|
||||
|
||||
mods = args.mods or [ ];
|
||||
|
||||
helpMsg = ''
|
||||
|
||||
===FETCH FAILED===
|
||||
Please ensure you have set the username and token with config.nix, or
|
||||
/etc/nix/nixpkgs-config.nix if on NixOS.
|
||||
|
||||
Your token can be seen at https://factorio.com/profile (after logging in). It is
|
||||
not as sensitive as your password, but should still be safeguarded. There is a
|
||||
link on that page to revoke/invalidate the token, if you believe it has been
|
||||
leaked or wish to take precautions.
|
||||
|
||||
Example:
|
||||
{
|
||||
packageOverrides = pkgs: {
|
||||
factorio = pkgs.factorio.override {
|
||||
username = "FactorioPlayer1654";
|
||||
token = "d5ad5a8971267c895c0da598688761";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Alternatively, instead of providing the username+token, you may manually
|
||||
download the release through https://factorio.com/download , then add it to
|
||||
the store using e.g.:
|
||||
|
||||
releaseType=alpha
|
||||
version=0.17.74
|
||||
nix-prefetch-url file://\''$HOME/Downloads/factorio_\''${releaseType}_x64_\''${version}.tar.xz --name factorio_\''${releaseType}_x64-\''${version}.tar.xz
|
||||
|
||||
Note the ultimate "_" is replaced with "-" in the --name arg!
|
||||
'';
|
||||
|
||||
desktopItem = makeDesktopItem {
|
||||
name = "factorio";
|
||||
desktopName = "Factorio";
|
||||
comment = "A game in which you build and maintain factories.";
|
||||
exec = "factorio";
|
||||
icon = "factorio";
|
||||
categories = [ "Game" ];
|
||||
};
|
||||
|
||||
branch = if experimental then "experimental" else "stable";
|
||||
|
||||
# NB `experimental` directs us to take the latest build, regardless of its branch;
|
||||
# hence the (stable, experimental) pairs may sometimes refer to the same distributable.
|
||||
versions = importJSON versionsJson;
|
||||
binDists = makeBinDists versions;
|
||||
|
||||
actual = binDists.${stdenv.hostPlatform.system}.${releaseType}.${branch} or (throw "Factorio ${releaseType}-${branch} binaries for ${stdenv.hostPlatform.system} are not available for download.");
|
||||
|
||||
makeBinDists = versions:
|
||||
let
|
||||
f = path: name: value:
|
||||
if builtins.isAttrs value then
|
||||
if value ? "name" then
|
||||
makeBinDist value
|
||||
else
|
||||
builtins.mapAttrs (f (path ++ [ name ])) value
|
||||
else
|
||||
throw "expected attrset at ${toString path} - got ${toString value}";
|
||||
in
|
||||
builtins.mapAttrs (f [ ]) versions;
|
||||
makeBinDist = { name, version, tarDirectory, url, sha256, needsAuth }: {
|
||||
inherit version tarDirectory;
|
||||
src =
|
||||
if !needsAuth then
|
||||
fetchurl { inherit name url sha256; }
|
||||
else
|
||||
(lib.overrideDerivation
|
||||
(fetchurl {
|
||||
inherit name url sha256;
|
||||
curlOptsList = [
|
||||
"--get"
|
||||
"--data-urlencode"
|
||||
"username@username"
|
||||
"--data-urlencode"
|
||||
"token@token"
|
||||
];
|
||||
})
|
||||
(_: {
|
||||
# This preHook hides the credentials from /proc
|
||||
preHook =
|
||||
if username != "" && token != "" then ''
|
||||
echo -n "${username}" >username
|
||||
echo -n "${token}" >token
|
||||
'' else ''
|
||||
# Deliberately failing since username/token was not provided, so we can't fetch.
|
||||
# We can't use builtins.throw since we want the result to be used if the tar is in the store already.
|
||||
exit 1
|
||||
'';
|
||||
failureHook = ''
|
||||
cat <<EOF
|
||||
${helpMsg}
|
||||
EOF
|
||||
'';
|
||||
}));
|
||||
};
|
||||
|
||||
configBaseCfg = ''
|
||||
use-system-read-write-data-directories=false
|
||||
[path]
|
||||
read-data=$out/share/factorio/data/
|
||||
[other]
|
||||
check_updates=false
|
||||
'';
|
||||
|
||||
updateConfigSh = ''
|
||||
#! $SHELL
|
||||
if [[ -e ~/.factorio/config.cfg ]]; then
|
||||
# Config file exists, but may have wrong path.
|
||||
# Try to edit it. I'm sure this is perfectly safe and will never go wrong.
|
||||
sed -i 's|^read-data=.*|read-data=$out/share/factorio/data/|' ~/.factorio/config.cfg
|
||||
else
|
||||
# Config file does not exist. Phew.
|
||||
install -D $out/share/factorio/config-base.cfg ~/.factorio/config.cfg
|
||||
fi
|
||||
'';
|
||||
|
||||
modDir = factorio-utils.mkModDirDrv mods mods-dat;
|
||||
|
||||
base = with actual; {
|
||||
pname = "factorio-${releaseType}";
|
||||
inherit version src;
|
||||
|
||||
preferLocalBuild = true;
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/{bin,share/factorio}
|
||||
cp -a data $out/share/factorio
|
||||
cp -a bin/${tarDirectory}/factorio $out/bin/factorio
|
||||
patchelf \
|
||||
--set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
|
||||
$out/bin/factorio
|
||||
'';
|
||||
|
||||
passthru.updateScript =
|
||||
if (username != "" && token != "") then [
|
||||
./update.py
|
||||
"--username=${username}"
|
||||
"--token=${token}"
|
||||
] else null;
|
||||
|
||||
meta = {
|
||||
description = "Game in which you build and maintain factories";
|
||||
longDescription = ''
|
||||
Factorio is a game in which you build and maintain factories.
|
||||
|
||||
You will be mining resources, researching technologies, building
|
||||
infrastructure, automating production and fighting enemies. Use your
|
||||
imagination to design your factory, combine simple elements into
|
||||
ingenious structures, apply management skills to keep it working and
|
||||
finally protect it from the creatures who don't really like you.
|
||||
|
||||
Factorio has been in development since spring of 2012, and reached
|
||||
version 1.0 in mid 2020.
|
||||
'';
|
||||
homepage = "https://www.factorio.com/";
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
|
||||
license = lib.licenses.unfree;
|
||||
maintainers = with lib.maintainers; [ Baughn elitak priegger lukegb ];
|
||||
platforms = [ "x86_64-linux" ];
|
||||
mainProgram = "factorio";
|
||||
};
|
||||
};
|
||||
|
||||
releases = rec {
|
||||
headless = base;
|
||||
demo = base // {
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
buildInputs = [ libpulseaudio ];
|
||||
|
||||
libPath = lib.makeLibraryPath [
|
||||
alsa-lib
|
||||
libGL
|
||||
libICE
|
||||
libSM
|
||||
libX11
|
||||
libXcursor
|
||||
libXext
|
||||
libXi
|
||||
libXinerama
|
||||
libXrandr
|
||||
libpulseaudio
|
||||
libxkbcommon
|
||||
wayland
|
||||
];
|
||||
|
||||
installPhase = base.installPhase + ''
|
||||
wrapProgram $out/bin/factorio \
|
||||
--prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:$libPath \
|
||||
--run "$out/share/factorio/update-config.sh" \
|
||||
--argv0 "" \
|
||||
--add-flags "-c \$HOME/.factorio/config.cfg" \
|
||||
${lib.optionalString (mods!=[]) "--add-flags --mod-directory=${modDir}"}
|
||||
|
||||
# TODO Currently, every time a mod is changed/added/removed using the
|
||||
# modlist, a new derivation will take up the entire footprint of the
|
||||
# client. The only way to avoid this is to remove the mods arg from the
|
||||
# package function. The modsDir derivation will have to be built
|
||||
# separately and have the user specify it in the .factorio config or
|
||||
# right along side it using a symlink into the store I think i will
|
||||
# just remove mods for the client derivation entirely. this is much
|
||||
# cleaner and more useful for headless mode.
|
||||
|
||||
# TODO: trying to toggle off a mod will result in read-only-fs-error.
|
||||
# not much we can do about that except warn the user somewhere. In
|
||||
# fact, no exit will be clean, since this error will happen on close
|
||||
# regardless. just prints an ugly stacktrace but seems to be otherwise
|
||||
# harmless, unless maybe the user forgets and tries to use the mod
|
||||
# manager.
|
||||
|
||||
install -m0644 <(cat << EOF
|
||||
${configBaseCfg}
|
||||
EOF
|
||||
) $out/share/factorio/config-base.cfg
|
||||
|
||||
install -m0755 <(cat << EOF
|
||||
${updateConfigSh}
|
||||
EOF
|
||||
) $out/share/factorio/update-config.sh
|
||||
|
||||
mkdir -p $out/share/icons/hicolor/{64x64,128x128}/apps
|
||||
cp -a data/core/graphics/factorio-icon.png $out/share/icons/hicolor/64x64/apps/factorio.png
|
||||
cp -a data/core/graphics/factorio-icon@2x.png $out/share/icons/hicolor/128x128/apps/factorio.png
|
||||
ln -s ${desktopItem}/share/applications $out/share/
|
||||
'';
|
||||
};
|
||||
alpha = demo // {
|
||||
|
||||
installPhase = demo.installPhase + ''
|
||||
cp -a doc-html $out/share/factorio
|
||||
'';
|
||||
};
|
||||
expansion = alpha;
|
||||
};
|
||||
|
||||
in
|
||||
stdenv.mkDerivation (releases.${releaseType})
|
@ -1,191 +0,0 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python -p "python3.withPackages (ps: with ps; [ ps.absl-py ps.requests ])" nix
|
||||
|
||||
from collections import defaultdict
|
||||
import copy
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
import os.path
|
||||
import subprocess
|
||||
from typing import Callable, Dict
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from absl import logging
|
||||
import requests
|
||||
|
||||
|
||||
FACTORIO_API = "https://factorio.com/api/latest-releases"
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
flags.DEFINE_string('username', '', 'Factorio username for retrieving binaries.')
|
||||
flags.DEFINE_string('token', '', 'Factorio token for retrieving binaries.')
|
||||
flags.DEFINE_string('out', '', 'Output path for versions.json.')
|
||||
flags.DEFINE_list('release_type', '', 'If non-empty, a comma-separated list of release types to update (e.g. alpha).')
|
||||
flags.DEFINE_list('release_channel', '', 'If non-empty, a comma-separated list of release channels to update (e.g. experimental).')
|
||||
|
||||
|
||||
@dataclass
|
||||
class System:
|
||||
nix_name: str
|
||||
url_name: str
|
||||
tar_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReleaseType:
|
||||
name: str
|
||||
needs_auth: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReleaseChannel:
|
||||
name: str
|
||||
|
||||
|
||||
FactorioVersionsJSON = Dict[str, Dict[str, str]]
|
||||
OurVersionJSON = Dict[str, Dict[str, Dict[str, Dict[str, str]]]]
|
||||
|
||||
|
||||
SYSTEMS = [
|
||||
System(nix_name="x86_64-linux", url_name="linux64", tar_name="x64"),
|
||||
]
|
||||
|
||||
RELEASE_TYPES = [
|
||||
ReleaseType("alpha", needs_auth=True),
|
||||
ReleaseType("expansion", needs_auth=True),
|
||||
ReleaseType("demo"),
|
||||
ReleaseType("headless"),
|
||||
]
|
||||
|
||||
RELEASE_CHANNELS = [
|
||||
ReleaseChannel("experimental"),
|
||||
ReleaseChannel("stable"),
|
||||
]
|
||||
|
||||
|
||||
def find_versions_json() -> str:
|
||||
if FLAGS.out:
|
||||
return FLAGS.out
|
||||
try_paths = ["pkgs/games/factorio/versions.json", "versions.json"]
|
||||
for path in try_paths:
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
raise Exception("Couldn't figure out where to write versions.json; try specifying --out")
|
||||
|
||||
|
||||
def fetch_versions() -> FactorioVersionsJSON:
|
||||
return json.loads(requests.get("https://factorio.com/api/latest-releases").text)
|
||||
|
||||
|
||||
def generate_our_versions(factorio_versions: FactorioVersionsJSON) -> OurVersionJSON:
|
||||
rec_dd = lambda: defaultdict(rec_dd)
|
||||
output = rec_dd()
|
||||
|
||||
# Deal with times where there's no experimental version
|
||||
for rc in RELEASE_CHANNELS:
|
||||
if not factorio_versions[rc.name]:
|
||||
factorio_versions[rc.name] = factorio_versions['stable']
|
||||
|
||||
for system in SYSTEMS:
|
||||
for release_type in RELEASE_TYPES:
|
||||
for release_channel in RELEASE_CHANNELS:
|
||||
version = factorio_versions[release_channel.name].get(release_type.name)
|
||||
if version == None:
|
||||
continue
|
||||
this_release = {
|
||||
"name": f"factorio_{release_type.name}_{system.tar_name}-{version}.tar.xz",
|
||||
"url": f"https://factorio.com/get-download/{version}/{release_type.name}/{system.url_name}",
|
||||
"version": version,
|
||||
"needsAuth": release_type.needs_auth,
|
||||
"tarDirectory": system.tar_name,
|
||||
}
|
||||
output[system.nix_name][release_type.name][release_channel.name] = this_release
|
||||
return output
|
||||
|
||||
|
||||
def iter_version(versions: OurVersionJSON, it: Callable[[str, str, str, Dict[str, str]], Dict[str, str]]) -> OurVersionJSON:
|
||||
versions = copy.deepcopy(versions)
|
||||
for system_name, system in versions.items():
|
||||
for release_type_name, release_type in system.items():
|
||||
for release_channel_name, release in release_type.items():
|
||||
release_type[release_channel_name] = it(system_name, release_type_name, release_channel_name, dict(release))
|
||||
return versions
|
||||
|
||||
|
||||
def merge_versions(old: OurVersionJSON, new: OurVersionJSON) -> OurVersionJSON:
|
||||
"""Copies already-known hashes from version.json to avoid having to re-fetch."""
|
||||
def _merge_version(system_name: str, release_type_name: str, release_channel_name: str, release: Dict[str, str]) -> Dict[str, str]:
|
||||
old_system = old.get(system_name, {})
|
||||
old_release_type = old_system.get(release_type_name, {})
|
||||
old_release = old_release_type.get(release_channel_name, {})
|
||||
if FLAGS.release_type and release_type_name not in FLAGS.release_type:
|
||||
logging.info("%s/%s/%s: not in --release_type, not updating", system_name, release_type_name, release_channel_name)
|
||||
return old_release
|
||||
if FLAGS.release_channel and release_channel_name not in FLAGS.release_channel:
|
||||
logging.info("%s/%s/%s: not in --release_channel, not updating", system_name, release_type_name, release_channel_name)
|
||||
return old_release
|
||||
if not "sha256" in old_release:
|
||||
logging.info("%s/%s/%s: not copying sha256 since it's missing", system_name, release_type_name, release_channel_name)
|
||||
return release
|
||||
if not all(old_release.get(k, None) == release[k] for k in ['name', 'version', 'url']):
|
||||
logging.info("%s/%s/%s: not copying sha256 due to mismatch", system_name, release_type_name, release_channel_name)
|
||||
return release
|
||||
release["sha256"] = old_release["sha256"]
|
||||
return release
|
||||
return iter_version(new, _merge_version)
|
||||
|
||||
|
||||
def nix_prefetch_url(name: str, url: str, algo: str = 'sha256') -> str:
|
||||
cmd = ['nix-prefetch-url', '--type', algo, '--name', name, url]
|
||||
logging.info('running %s', cmd)
|
||||
out = subprocess.check_output(cmd)
|
||||
return out.decode('utf-8').strip()
|
||||
|
||||
|
||||
def fill_in_hash(versions: OurVersionJSON) -> OurVersionJSON:
|
||||
"""Fill in sha256 hashes for anything missing them."""
|
||||
urls_to_hash = {}
|
||||
def _fill_in_hash(system_name: str, release_type_name: str, release_channel_name: str, release: Dict[str, str]) -> Dict[str, str]:
|
||||
if "sha256" in release:
|
||||
logging.info("%s/%s/%s: skipping fetch, sha256 already present", system_name, release_type_name, release_channel_name)
|
||||
return release
|
||||
url = release["url"]
|
||||
if url in urls_to_hash:
|
||||
logging.info("%s/%s/%s: found url %s in cache", system_name, release_type_name, release_channel_name, url)
|
||||
release["sha256"] = urls_to_hash[url]
|
||||
return release
|
||||
logging.info("%s/%s/%s: fetching %s", system_name, release_type_name, release_channel_name, url)
|
||||
if release["needsAuth"]:
|
||||
if not FLAGS.username or not FLAGS.token:
|
||||
raise Exception("fetching %s/%s/%s from %s requires --username and --token" % (system_name, release_type_name, release_channel_name, url))
|
||||
url += f"?username={FLAGS.username}&token={FLAGS.token}"
|
||||
release["sha256"] = nix_prefetch_url(release["name"], url)
|
||||
urls_to_hash[url] = release["sha256"]
|
||||
return release
|
||||
return iter_version(versions, _fill_in_hash)
|
||||
|
||||
|
||||
def main(argv):
|
||||
factorio_versions = fetch_versions()
|
||||
new_our_versions = generate_our_versions(factorio_versions)
|
||||
old_our_versions = None
|
||||
our_versions_path = find_versions_json()
|
||||
if our_versions_path:
|
||||
logging.info('Loading old versions.json from %s', our_versions_path)
|
||||
with open(our_versions_path, 'r') as f:
|
||||
old_our_versions = json.load(f)
|
||||
if old_our_versions:
|
||||
logging.info('Merging in old hashes')
|
||||
new_our_versions = merge_versions(old_our_versions, new_our_versions)
|
||||
logging.info('Fetching necessary tars to get hashes')
|
||||
new_our_versions = fill_in_hash(new_our_versions)
|
||||
with open(our_versions_path, 'w') as f:
|
||||
logging.info('Writing versions.json to %s', our_versions_path)
|
||||
json.dump(new_our_versions, f, sort_keys=True, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(main)
|
@ -1,68 +0,0 @@
|
||||
{
|
||||
"x86_64-linux": {
|
||||
"alpha": {
|
||||
"experimental": {
|
||||
"name": "factorio_alpha_x64-2.0.8.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "11g1fgfm0lki9j2jsfmvlxzisbyx7482ia2qf7gnjcqhp6jkdsll",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/alpha/linux64",
|
||||
"version": "2.0.8"
|
||||
},
|
||||
"stable": {
|
||||
"name": "factorio_alpha_x64-2.0.8.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "11g1fgfm0lki9j2jsfmvlxzisbyx7482ia2qf7gnjcqhp6jkdsll",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/alpha/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
},
|
||||
"demo": {
|
||||
"experimental": {
|
||||
"name": "factorio_demo_x64-1.1.110.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "0dasxgrybl00vrabgrlarsvg0hdg5rvn3y4hsljhqc4zpbf93nxx",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/1.1.110/demo/linux64",
|
||||
"version": "1.1.110"
|
||||
},
|
||||
"stable": {
|
||||
"name": "factorio_demo_x64-1.1.110.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "0dasxgrybl00vrabgrlarsvg0hdg5rvn3y4hsljhqc4zpbf93nxx",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/1.1.110/demo/linux64",
|
||||
"version": "1.1.110"
|
||||
}
|
||||
},
|
||||
"expansion": {
|
||||
"stable": {
|
||||
"name": "factorio_expansion_x64-2.0.8.tar.xz",
|
||||
"needsAuth": true,
|
||||
"sha256": "0q3abb01ld1mlbp21lgzpa62j1gybs982yzan5j1axma9n1ax3j0",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/expansion/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
},
|
||||
"headless": {
|
||||
"experimental": {
|
||||
"name": "factorio_headless_x64-2.0.8.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "1jp1vlc4indicgy0xnrxq87h32wcv9s4g2hqbfb4ygiaam6lqnfr",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/headless/linux64",
|
||||
"version": "2.0.8"
|
||||
},
|
||||
"stable": {
|
||||
"name": "factorio_headless_x64-2.0.8.tar.xz",
|
||||
"needsAuth": false,
|
||||
"sha256": "1jp1vlc4indicgy0xnrxq87h32wcv9s4g2hqbfb4ygiaam6lqnfr",
|
||||
"tarDirectory": "x64",
|
||||
"url": "https://factorio.com/get-download/2.0.8/headless/linux64",
|
||||
"version": "2.0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34534,7 +34534,7 @@ with pkgs;
|
||||
fltk = fltk-minimal;
|
||||
};
|
||||
|
||||
factorio = callPackage ../games/factorio { releaseType = "alpha"; };
|
||||
factorio = callPackage ../by-name/fa/factorio/package.nix { releaseType = "alpha"; };
|
||||
|
||||
factorio-experimental = factorio.override { releaseType = "alpha"; experimental = true; };
|
||||
|
||||
@ -34548,9 +34548,9 @@ with pkgs;
|
||||
|
||||
factorio-space-age-experimental = factorio.override { releaseType = "expansion"; experimental = true; };
|
||||
|
||||
factorio-mods = callPackage ../games/factorio/mods.nix { };
|
||||
factorio-mods = callPackage ../by-name/fa/factorio/mods.nix { };
|
||||
|
||||
factorio-utils = callPackage ../games/factorio/utils.nix { };
|
||||
factorio-utils = callPackage ../by-name/fa/factorio/utils.nix { };
|
||||
|
||||
fairymax = callPackage ../games/fairymax { };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user