332 lines
9.0 KiB
PHP
332 lines
9.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Namespace for classes and functions related to the game Factorio.
|
|
* @package NAE\Factorio
|
|
*/
|
|
namespace NAE\Factorio;
|
|
|
|
/**
|
|
* Class for managing Factorio mods.
|
|
* @author "Marcel Naeve" <php@naeve.info>
|
|
* @license MIT License (http://www.opensource.org/licenses/mit)
|
|
*/
|
|
class FactorioMod {
|
|
|
|
/**
|
|
* @var int INIT_TYPE_PATH - Mod is initialized from a zip file.
|
|
*/
|
|
const INIT_TYPE_PATH = 1;
|
|
|
|
/**
|
|
* @var int INIT_TYPE_NAME - Mod is initialized from a mod name.
|
|
*/
|
|
const INIT_TYPE_NAME = 3;
|
|
|
|
|
|
/**
|
|
* @var object|null $info - Mod information from Zip file.
|
|
*/
|
|
private $info = null;
|
|
|
|
/**
|
|
* @var object|null $api - Mod information from Factorio API.
|
|
*/
|
|
private $api = null;
|
|
|
|
/**
|
|
* @var object|null $mod_settings - Mod settings enabled/disabled from json in mods folder.
|
|
*/
|
|
private $mod_settings = null;
|
|
|
|
/**
|
|
* @var string|null $mod_folder - Path to the mods folder.
|
|
*/
|
|
private $mod_folder = null;
|
|
|
|
/**
|
|
* Reads all Mods as FactorioMod objects to an array.
|
|
* @param string $modFolder Path to the mods folder.
|
|
* @return array Array of FactorioMod objects.
|
|
*/
|
|
static function readModFolder(string $modFolder) : array {
|
|
|
|
$mods = [];
|
|
|
|
$dh = opendir($modFolder); // open the directory handle
|
|
|
|
while ( false !== ($entry = readdir($dh)) ) { // read directory entries
|
|
|
|
if(preg_match("/\.zip$/ui", $entry)) { // if the file is a zip file
|
|
|
|
$mods[] = new FactorioMod(
|
|
$modFolder. "/". $entry,
|
|
FactorioMod::INIT_TYPE_PATH
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir($dh); // close the directory handle
|
|
|
|
return $mods;
|
|
|
|
}
|
|
|
|
/**
|
|
* Reads mod information from info.json file in mod Zip file.
|
|
* @param string $zipPath Path to the mod Zip file.
|
|
* @return object|null Mod information from info.json file.
|
|
*/
|
|
private function readInfo(string $zipPath) : ?object {
|
|
|
|
if(!file_exists($zipPath)) { // file does not exist?
|
|
return null;
|
|
}
|
|
|
|
$za = new \ZipArchive();
|
|
$res = $za->open($zipPath); // open the zip file
|
|
|
|
if($res !== true) { // open the zip file failed?
|
|
return null;
|
|
}
|
|
|
|
$c = null;
|
|
for( $i = 0; $i < $za->numFiles; $i++ ){ // Iterate over all files in the zip file
|
|
|
|
$name = $za->getNameIndex( $i ); // get the name of current file
|
|
|
|
if(basename($name) == "info.json") { // if the file is info.json
|
|
$c = $za->getFromIndex($i); // get the content of info.json
|
|
$i = $za->numFiles; // break the loop by condition
|
|
break; // break the loop by force (double tap)
|
|
}
|
|
|
|
}
|
|
|
|
$za->close(); // close the zip file
|
|
|
|
return json_decode( $c, false ); // return decoded json object or null on failure
|
|
|
|
}
|
|
|
|
/**
|
|
* Sends a GET request to Factorio API to get mod information.
|
|
* @param string $name Mod name to get information from Factorio API.
|
|
* @return object|null Mod information from Factorio API.
|
|
*/
|
|
private function callApi(string $name="") : ?object {
|
|
|
|
if($name === "") { // no name given?
|
|
if($this->info === null) { // also no path to module for info.json?
|
|
return null;
|
|
}
|
|
$name = $this->info->name; // get name from info.json
|
|
}
|
|
|
|
$api = "https://mods.factorio.com/api/mods/" . $name;
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt($curl, CURLOPT_URL, $api);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
$response = curl_exec($curl);
|
|
$cri = curl_getinfo($curl);
|
|
|
|
curl_close($curl);
|
|
|
|
if($cri["http_code"] != 200) { // request failed?
|
|
return null;
|
|
}
|
|
|
|
if(trim($response) < 1) { // response body empty?
|
|
return null;
|
|
}
|
|
|
|
$r = json_decode($response, false); // decode json object or null on failure
|
|
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
* @param string $init Path to the mod Zip file or mod name.
|
|
* @param int $init_type Initialization type (FactorioMod::INIT_TYPE_PATH or FactorioMod::INIT_TYPE_NAME).
|
|
* @param string $mod_folder Path to the mods folder.
|
|
*/
|
|
public function __construct(string $init, int $init_type=self::INIT_TYPE_PATH, string $mod_folder="") {
|
|
|
|
if($init_type === self::INIT_TYPE_PATH) {
|
|
|
|
$this->info = $this->readInfo($init);
|
|
if($this->info !== null) {
|
|
$this->mod_folder = dirname($init);
|
|
$this->callApi();
|
|
}
|
|
|
|
}
|
|
|
|
if($init_type === self::INIT_TYPE_NAME) {
|
|
|
|
$this->mod_folder = $mod_folder;
|
|
$this->callApi($init);
|
|
|
|
// TODO: look if mod is installed..
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns last release version information of the mod.
|
|
* @return object|null Last release version information of the mod.
|
|
*/
|
|
public function getLastVersionInfo() : ?object {
|
|
|
|
$target = count($this->api->releases) - 1;
|
|
|
|
return $this->api->releases[ $target ];
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks if the latest release mod version is newer than the installed version.
|
|
* @return bool True if the latest release mod version is newer, false otherwise.
|
|
*/
|
|
public function isUpdateable() : bool {
|
|
|
|
$lv = new \NAE\Factorio\FactorioVersion(
|
|
$this->getLastVersionInfo()->version
|
|
);
|
|
|
|
$cv = new \NAE\Factorio\FactorioVersion(
|
|
$this->info->version
|
|
);
|
|
|
|
return $lv->isNewer($cv);
|
|
|
|
}
|
|
|
|
/**
|
|
* Deletes the mod from the mods folder file.
|
|
* @return bool True if the mod was deleted, false otherwise.
|
|
*/
|
|
private function delete() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Downloads the latest release mod version to the mods folder.
|
|
* @return bool True if the mod was downloaded, false otherwise.
|
|
*/
|
|
private function download() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Uninstalls the mod from the mods folder and the settings.json file.
|
|
* @return bool True if the mod was uninstalled, false otherwise.
|
|
*/
|
|
public function uninstall() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Installs the mod in the mods folder and adds it to the settings.json file as enabled.
|
|
* @return bool True if the mod was installed, false otherwise.
|
|
*/
|
|
public function install() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Updates the mod to the latest release mod version.
|
|
* @return bool True if the mod was updated, false otherwise.
|
|
*/
|
|
public function update() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Loads the mod settings for all mods (enabled/disabled) from the settings.json file.
|
|
* @return bool True if the mod settings have been loaded successfully, false otherwise.
|
|
*/
|
|
private function loadModSettings() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns the mod settings for all mods (enabled/disabled) from settings.json.
|
|
* @return object|null Mod settings for all mods.
|
|
*/
|
|
public function getModSettings() :?object {
|
|
return $this->mod_settings;
|
|
}
|
|
|
|
/**
|
|
* Saves the changes in the mod settings for all mods (enabled/disabled) to the settings.json file.
|
|
* @return bool True if the mod settings have been saved successfully, false otherwise.
|
|
*/
|
|
private function saveModSettings() : bool {
|
|
|
|
$j = json_encode($this->mod_settings);
|
|
// TODO: implement
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Sets the mod settings for all mods (enabled/disabled) in the settings.json file.
|
|
* @param object $mod_settings Mod settings for all mods.
|
|
* @return FactorioMod The instance of FactorioMod for chaining.
|
|
*/
|
|
public function setModSettings(object $mod_settings) : FactorioMod {
|
|
|
|
$this->mod_settings = $mod_settings;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks if this mod is enabled in the settings.json.
|
|
* @return bool True if this mod is enabled, false otherwise.
|
|
*/
|
|
public function isEnabled() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks if this mod is disabled in the settings.json.
|
|
* @return bool True if this mod is disabled, false otherwise.
|
|
*/
|
|
public function isDisabled() : bool {
|
|
// TODO: implement
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Sets this mod to enabled in the settings.json
|
|
*/
|
|
public function enable() {
|
|
// TODO: implement
|
|
}
|
|
|
|
/**
|
|
* Sets this mod to disabled in the settings.json
|
|
*/
|
|
public function disable() {
|
|
// TODO: implement
|
|
}
|
|
|
|
}
|