PHP-cli-factorio-updater/factorio_update.php

339 lines
10 KiB
PHP
Raw Normal View History

2024-11-10 03:40:05 +01:00
<?PHP
define("INDEX_DIR", __DIR__);
2024-11-10 03:40:05 +01:00
2024-11-10 21:58:32 +01:00
require __DIR__.'/scripts/class.TerminalMessage.php';
2024-11-10 03:40:05 +01:00
require __DIR__.'/scripts/func.downloadFile.php';
require __DIR__.'/scripts/class.FactorioVersion.php';
require __DIR__.'/scripts/class.Systemctl.php';
require __DIR__.'/scripts/class.ValveRcon.php';
2024-11-10 21:58:32 +01:00
$cli = new \NAE\Terminal\TerminalMessage();
2024-11-10 03:40:05 +01:00
// Welches Build ist gewünscht?
$target_build = "stable";
$target_edition = "headless";
// Wo wird der Server dieses Builds heruntergeladen?
$download_source = "https://factorio.com/get-download/stable/headless/linux64";
// sha256 hash Source
$download_hash_source = "https://www.factorio.com/download/sha256sums/";
2024-11-10 03:40:05 +01:00
// In welcher Datei soll der Download gespeichert werden?
// Wichtig da Factorio eine .tar.gz datei als linux64 Datei anbietet.
$download_output = __DIR__."/factorio.tar";
// Welche Dateien oder Ordner sollen vom alten Server übernommen werden?
$copy_paths = [
"/server-adminlist.json",
"/player-data.json",
"/config",
"/config-path.cfg"
2024-11-10 03:40:05 +01:00
];
// In welcher Datei steht die aktuelle Versionsnummer?
$current_version_str = (function(){
$env = file_get_contents(__DIR__."/factorio-settings.env");
$version = preg_replace("/.*FACTORIO_VERSION\=\"((\d+\.)+\d+)\".*/su","$1",$env);
return $version;
})();
$current_version = new \NAE\Factorio\FactorioVersion($current_version_str);
2024-11-10 21:58:32 +01:00
$cli->sendInfo( "CURRENT_VERSION: ".$current_version->getVersion() );
2024-11-10 03:40:05 +01:00
// Aktuelle Versionsnummern aus der Factorio-API abrufen.
$live_versions = json_decode(file_get_contents("https://factorio.com/api/latest-releases"), true);
// Anhand von Build und Edition die richtige Version auswählen.
$latest_version = new \NAE\Factorio\FactorioVersion($live_versions[$target_build][$target_edition]);
2024-11-10 21:58:32 +01:00
$cli->sendInfo( "LATEST_VERSION: ".$latest_version->getVersion() );
echo PHP_EOL;
2024-11-10 03:40:05 +01:00
/**
* Schreibt die neue Versionsnummer in die environment (env) datei des servers
* @return bool Schreiben erfolgreich?
*/
function writeBackVersion() : bool {
global $latest_version;
$env_file = __DIR__."/factorio-settings.env";
$env = file_get_contents($env_file);
$new_env = preg_replace("/FACTORIO_VERSION\=\"((\d+\.)+\d+)\"/su", "FACTORIO_VERSION=\"".$latest_version->getVersion()."\"", $env);
return ( file_put_contents($env_file, $new_env) !== false );
}
2024-11-10 03:40:05 +01:00
// Variablen zum speichern des Fortschrittes bzw. Erfolgs.
$download_success = false;
$extract_success = false;
2024-11-10 21:58:32 +01:00
$cli->sendTitle( "PRÜFE AUF FACTORIO UPDATES" );
2024-11-10 03:40:05 +01:00
if($latest_version->isNewer($current_version)) { // neue Version verfügbar?
2024-11-10 21:58:32 +01:00
$cli->sendTitle( "NEUE VERSION GEFUNDEN : UPDATE STARTET" );
2024-11-10 03:40:05 +01:00
if(file_exists($download_output)) { // liegt noch ein altes Server Archiv im Vertzeichnis?
2024-11-10 21:58:32 +01:00
$cli->sendTitle( "ALTE SERVER FILES GEFUNDEN : STARTE LÖSCHVORGANG", 1 );
2024-11-10 03:40:05 +01:00
if( unlink($download_output) ) { // altes Archiv löschen
2024-11-10 21:58:32 +01:00
$cli->sendSuccess( "ALTE SERVER FILES ERFOLGREICH GELÖSCHT!" );
2024-11-10 03:40:05 +01:00
} else {
2024-11-10 21:58:32 +01:00
$cli->sendError( "ALTE SERVER FILES KONNTEN NICHT GELÖSCHT WERDEN!", true );
2024-11-10 03:40:05 +01:00
}
}
2024-11-10 21:58:32 +01:00
echo PHP_EOL;
$cli->sendTitle( "STARTE DOWNLOAD DER SERVER FILES", 1 );
2024-11-10 03:40:05 +01:00
if(\NAE\Functions\Curl\downloadFile($download_output, $download_source)) { // Download der neuen Server Files
$dl_real_out = $download_output;
$sha256file = file_get_contents($download_hash_source); // sha256 hash liste von factorio
$fileHash = hash_file("sha256", $download_output);
$cli->sendInfo("Umbenennen des Heruntergeladenen Archivs..");
$realFilename = (function(array $lst, string $hash) : ?string {
$hashLen = strlen($hash);
foreach($lst as $file) {
if(substr($file, 0, $hashLen) == $hash && substr($file, $hashLen, 1) == " ") {
return trim(substr($file, $hashLen+1));
}
}
return null;
})(explode("\n", $sha256file), $fileHash);
if($realFilename === null) {
$cli->sendError( "FEHLGESCHLAGEN: Kann den richtigen Dateinamen aus der sha256 hash liste nicht ermitteln!", true );
} else {
$orig_download_output = $download_output;
$download_output = __DIR__."/$realFilename";
if(@rename( $orig_download_output, $download_output )) {
$cli->sendSuccess( "DOWNLOAD SUCCESS!" );
$download_success = true;
}
}
2024-11-10 03:40:05 +01:00
} else {
2024-11-10 21:58:32 +01:00
$cli->sendError( "DOWNLOAD FEHLGESCHLAGEN!", true );
2024-11-10 03:40:05 +01:00
}
if($download_success) {
2024-11-10 21:58:32 +01:00
echo PHP_EOL;
$cli->sendTitle( "STARTE DAS ENTPACKEN DER NEUEN SERVER FILES", 1 );
2024-11-10 03:40:05 +01:00
$unxz_download_output = preg_replace("/.tar.xz$/", ".tar", $download_output);
exec("unxz -vfd \"$download_output\" && tar -xvf \"$unxz_download_output\" > /dev/null", $output, $return); // Entpacken
2024-11-10 03:40:05 +01:00
if($return === 0) {
if( @rename(__DIR__."/factorio", __DIR__."/factorio-".$latest_version->getVersion()) ) { // Umbenennen mit Versionsnummer
2024-11-10 03:40:05 +01:00
2024-11-10 21:58:32 +01:00
$cli->sendSuccess( "Neue Server Files wurden Erfolgreich entpackt!" );
2024-11-10 03:40:05 +01:00
$extract_success = true;
} else {
2024-11-10 21:58:32 +01:00
$cli->sendError( "Umbenennen des Factorio Ordners mit Versionsnummer Fehlgeschlagen!", true );
2024-11-10 03:40:05 +01:00
}
} else {
2024-11-10 21:58:32 +01:00
$cli->sendError( "Entpacken der Server Files ist Fehlgeschlagen!", true );
2024-11-10 03:40:05 +01:00
}
}
if($extract_success) {
// RCON Kommunikation zum Server starten
$rcon_data = (function() : ?array {
global $current_version;
$cfg = parse_ini_file(__DIR__."/factorio-".$current_version->getVersion()."/config/config.ini", true);
if(!$cfg) return null;
$cd = [];
if(isset($cfg["other"])) {
$parts = explode(":", $cfg["other"]["local-rcon-socket"]??"127.0.0.1:27015");
$cd["ip"] = $parts[0];
$cd["port"] = $parts[1];
if(isset($cfg["other"]["local-rcon-socket"])) {
$cd["password"] = $cfg["other"]["local-rcon-password"]??"";
}
}
return $cd;
})();
$rcon = null;
if($rcon_data) {
try {
$rcon = new \NAE\Valve\Rcon\ValveRcon($rcon_data["ip"], $rcon_data["port"], $rcon_data["password"]);
$rcon->sendCommand("ACHTUNG: Server wird in kürze für ein Update gestoppt, bitte trennen Sie Ihre Verbindung zum Server. Der Server wird in kürze wieder verfügbar sein. Zeit bis zum Stopp: 60 Sekunden.", false);
if($rcon->getError() !== null) {
2024-11-10 21:58:32 +01:00
$cli->sendWarning( "RCON Verbindung konnte nicht aufgebaut werden!" );
2024-11-10 03:40:05 +01:00
$rcon = null;
}
} catch(\Exception $e) {
2024-11-10 21:58:32 +01:00
$cli->sendWarning( "RCON Verbindung konnte nicht aufgebaut werden!" );
2024-11-10 03:40:05 +01:00
$rcon = null;
}
}
if($rcon) sleep(60); // Falls die Meldung geklappt hat 60s warten, damit Spieler den Server verlassen können.
// inititialize Systemctl Service interface
$service = new \NAE\Service\Systemctl("factorio");
// Server Stoppen
if($service->stop()) {
2024-11-10 21:58:32 +01:00
$cli->sendInfo( "FACTORIO SERVER WURDE GESTOPPT!" );
2024-11-10 03:40:05 +01:00
}
// neue Versionsnummer in .env Datei übernehmen
if(writeBackVersion()) {
2024-11-10 21:58:32 +01:00
$cli->sendInfo( "Version in Environment File wurde aktualisiert" );
2024-11-10 03:40:05 +01:00
}
// Dateien aus alten Server Files kopieren..
if( is_dir(__DIR__."/factorio-".$current_version->getVersion()) && is_dir(__DIR__."/factorio-".$latest_version->getVersion()) ) {
2024-11-10 21:58:32 +01:00
echo PHP_EOL;
$cli->sendTitle( "Kopiere Konfigurations-Dateien in den neuen Server Pfad", 1 );
2024-11-10 03:40:05 +01:00
foreach($copy_paths as $copy_id => $copy_name) {
$copy_source = __DIR__."/factorio-".$current_version->getVersion().$copy_name;
$copy_dest = __DIR__."/factorio-".$latest_version->getVersion().$copy_name;
2024-11-10 03:40:05 +01:00
if(file_exists($copy_source)) {
if(is_dir($copy_source)) {
$cli->sendTitle( "Kopierenvorgang Nr. ".($copy_id+1)." von ".count($copy_paths)." - $copy_name", 2 );
try {
\NAE\Functions\Folder\rcopy($copy_source, $copy_dest);
$cli->sendSuccess( "Kopiervorgang Erfolgreich!" );
} catch (\Exception $e) {
$cli->sendError( "Kopiervorgang Fehlgeschlagen!" );
2024-11-10 03:40:05 +01:00
}
2024-11-10 03:40:05 +01:00
} else {
$cli->sendTitle( "Kopierenvorgang Nr. ".($copy_id+1)." von ".count($copy_paths)." - $copy_name", 2 );
if(@copy($copy_source, $copy_dest)) {
$cli->sendSuccess( "Kopiervorgang Erfolgreich!" );
} else {
$cli->sendError( "Kopiervorgang Fehlgeschlagen!" );
}
2024-11-10 03:40:05 +01:00
}
} else {
2024-11-10 21:58:32 +01:00
$cli->sendWarning( "Quelle nicht vorhanden!" );
2024-11-10 03:40:05 +01:00
}
}
}
// Fix file permissions..
(function(){
2024-11-10 21:58:32 +01:00
global $latest_version, $cli;
2024-11-10 03:40:05 +01:00
2024-11-10 21:58:32 +01:00
$cli->sendTitle( "Rechte im neuen Server-Verzeichnis werden korrigiert", 1 );
2024-11-10 03:40:05 +01:00
exec("chown -R factorio:factorio \"".__DIR__."/factorio-".$latest_version->getVersion()."\"", $output, $return);
if($return === 0) {
2024-11-10 21:58:32 +01:00
$cli->sendSuccess( "Rechte erfolgreich korrigiert!" );
2024-11-10 03:40:05 +01:00
} else {
2024-11-10 21:58:32 +01:00
$cli->sendError( "Rechte konnten nicht korrigiert werden!", true );
2024-11-10 03:40:05 +01:00
}
})();
if($service->start()) {
2024-11-10 21:58:32 +01:00
$cli->sendSuccess( "FACTORIO SERVER WURDE WIEDER GESTARTET!" );
} else {
$cli->sendError( "FACTORIO SERVER KONNTE NICHT WIEDER GESTARTET WERDEN!", true );
2024-11-10 03:40:05 +01:00
}
}
} else {
// Keine aktuellere Version verfügbar!
2024-11-10 21:58:32 +01:00
$cli->sendInfo( "Kein Update verfügbar." );
2024-11-10 03:40:05 +01:00
}