Author Topic: [Linux] Good Old Games installer base files extractor (bash script)  (Read 3553 times)

0 Members and 1 Guest are viewing this topic.

Offline Hellzed

  • 28
[Linux] Good Old Games installer base files extractor (bash script)
Hi,
As we all know, FreeSpace 2 still needs the original VP files in order to work.
That's why everyone who hasn't bought the game while it was in retail shops has now to buy it from Good Old Games...

Thats not a big deal for Microsoft Windows users, but Linux users have to use Wine to install the game, and then move these VPs to their FreeSpace 2 root/data folder. It's a hassle for some of the new players who are not used to the way fs2_open handles its files (the process can include some renaming).

I brought together a small bash script with a Zenity GUI to help with this part : it takes the good old games FS2 installer, gets the right files and put them in the right place.

This bash script has 2 dependencies : zenity and innoextract . Both are absolutely needed (zenity should be already installed on Ubuntu, innoextract has to be installed).

Hopefully, wxLauncher will soon include a part that does the same thing, except way cleaner, but maybe that can help to streamline the install process on Linux for the moment.

For now, sed is eating a bit too much CPU, so i'm searching for a lighter way to make a good progress bar...

Here's the code :
Code: [Select]
#!/bin/sh
#Script by Hellzed, use it, modify it, share it as you want.

#This script should check if we are running as superuser... Not implemented yet.

#What this script does : extract base VP files from the Good Old Games Installer, drop the useless stuff, and put the VPs into /data to complete a base fs2_open install.
zenity --question --width=450 --title="FreeSpace 2 Base Files Extractor" --text="This program will extract base files from the Good Old Games FreeSpace 2 installer for Microsoft Windows and place them into your FreeSpace 2 Open root folder.\n\nFreeSpace 2 Open may not work properly without these files.\n\nBefore starting the extraction process, please check that you have already bought and downloaded the FreeSpace 2 installer for Microsoft Windows from GoodOldGames.com .\n\nWARNING: Run this program as a superuser if FreeSpace 2 is installed as root.\n\nClick \"Yes\" to proceed with the extraction."

if [ $? = "0" ]
then
#User input : where is the GOG.com FS2 installer ? Plus a bunch of checks
GOG_INSTALLER=`zenity --file-selection --title="Select the Good Old Games installer"`

case $? in
0)
      echo "\"$GOG_INSTALLER\" is selected.";;
1)
      echo "No file selected.";;
-1)
      echo "Uneexpected error.";;
esac

#User input : where is FS2 installed ? Plus a bunch of checks
FS2_DIRECTORY=`zenity --file-selection --directory --title="Select FreeSpace 2 game root folder"`

case $? in
0)
      echo "\"$FS2_DIRECTORY\" is selected.";;
1)
      echo "No file selected.";;
-1)
      echo "Unexpected error.";;
esac

#We work in the FS2 install folder
cd $FS2_DIRECTORY

#/data folder is created
mkdir $FS2_DIRECTORY"/data"

#We need somewhere to put the mess included in the GOG installer, as the backend of this script (innoextract) is not able to extract individual files
mkdir $FS2_DIRECTORY"/tmp_"$$

cd $FS2_DIRECTORY"/tmp_"$$

#Important things going on here. innoextract is absolutely needed to crack open the GOG installer. It's in the Ubuntu repository, i don't know about other distros. I should include a check to verify if it's installed. Or even have innoextract as a dependency if somehow it gets packaged.
innoextract -L -q --progress=true -e $GOG_INSTALLER | sed -n -u -E 's/(^|.*[^0-9])([0-9]{1,3})(\.[0-9])%.*/\2\n# Extracting files... \2\%/p' | zenity --progress --width=450 --title="FreeSpace 2 Base Files Extractor"

if [ $? -gt 0 ]
then
#Extraction failure
    echo "ERROR! Extraction process aborted."
zenity --error --width=300 --title="FreeSpace 2 Base Files Extractor" --text="Extraction process aborted."
else
#If the extraction is successful, we move the VP files to the data folder.
mv $FS2_DIRECTORY"/tmp_"$$"/app/"*".vp" $FS2_DIRECTORY"/data/"
#we could also keep the MVE movies. I guess everyone uses the OGG ones now. Not sure. This part could also include md5sum checks, just to be sure...
zenity --info --width=450 --title="FreeSpace 2 Base Files Extractor" --text="Extraction process complete.\n\nYou may now run the original FreeSpace 2 game using an appropriate launcher, or acquire mods for an even better experience.\nMore information at www.hard-light.net ."
fi

#Anyway we remove useless
rm -Rf $FS2_DIRECTORY"/tmp_"$$

else
echo "Extraction aborted. Nothing to do"
fi

EDIT : this thing really needs some testing, so if you have the GOG FS2 installer on your linux computer, you know what to do !
« Last Edit: November 17, 2013, 05:20:58 pm by Hellzed »

 

Offline chief1983

  • Still lacks a custom title
  • Moderator
  • 212
  • ⬇️⬆️⬅️⬅️🅰➡️⬇️
    • Skype
    • Steam
    • Twitter
    • Fate of the Galaxy
Re: [Linux] Good Old Games installer base files extractor (bash script)
Very sweet.  I'd been planning on doing an innoextract script for a while, but would have rather that been the only dependency.  I doubt Zenity comes with a lot of other Linux distros by default, and it doesn't seem to be currently compatible with OS X.  Ideally we'd be able to integrate this into a general FSO installer.  Since most of the Linux install instructions are currently console based anyway, any chance it could be easily converted to console only, with no dialogs?  I may take a stab at converting this for zenity-less installs if not.  Looks like you spent a while getting the core innoextract functionality just right though, that will probably help with any other uses of innoextract in wxLauncher, etc in the future.  Great job.
Fate of the Galaxy - Now Hiring!  Apply within | Diaspora | SCP Home | Collada Importer for PCS2
Karajorma's 'How to report bugs' | Mantis
#freespace | #scp-swc | #diaspora | #SCP | #hard-light on EsperNet

"You may not sell or otherwise commercially exploit the source or things you created based on the source." -- Excerpt from FSO license, for reference

Nuclear1:  Jesus Christ zack you're a little too hamyurger for HLP right now...
iamzack:  i dont have hamynerge i just want ptatoc hips D:
redsniper:  Platonic hips?!
iamzack:  lays

 

Offline Hellzed

  • 28
Re: [Linux] Good Old Games installer base files extractor (bash script)
I'll look into it soon. Maybe I can make a script that can work both with GTK and fall back to any shell.

Right now i'm puzzled : whenever i run the script from a console it runs ok, but when i click on the file to run it from a file browser, the CPU usage of the bash script process rises pretty high, harming the global performance of innoextract...
I sense some output redirection issue caused by zenity, but i will need help to find a workaround.

 

Offline ngld

  • Administrator
  • 29
  • Knossos dev
Re: [Linux] Good Old Games installer base files extractor (bash script)
I removed the dependency on zenity and added the option to download innoextract if it's not installed.

If you run the script with "gui=bare sh ./script.sh" it will only use shell functions like echo and read to interact with the user.
If you use gui=dialog it will use dialog to provide a ncurses based UI and if you run it with gui=zenity it will use zenity.

If you don't set gui at all, it will try check if you have zenity or dialog. If you have neither, it will use the shell's functions.

Code: [Select]
#!/bin/bash
#Script by Hellzed, use it, modify it, share it as you want.
# Extended by ngld: Implemented support with dialog and removed the dependency on zenity. The script now automatically downloads innoextract if it's not installed.

#This script should check if we are running as superuser... Not implemented yet.

has() {
which "$1" > /dev/null 2>&1
}

if [ -z "$gui" ]; then
if has zenity; then
gui="zenity"
elif has dialog; then
gui="dialog"
else
gui="bare"
fi
fi

download() {
# TODO: Should this use show_progress ?
if has curl; then
curl -q -L -o "$1" "$2" 2>&1 | prog_output "Downloading..."
elif has wget; then
wget -O "$1" "$2" 2>&1 | prog_output "Downloading..."
else
fail "Download failed" "I need some kind of download program like \"curl\" or \"wget\"!"
fi
}

# GUI functions
fail() {
title="$1"
text="$2"

echo -e "FAIL: $2"
if [ ! "$gui" = "bare" ]; then
if [ "$gui" = "dialog" ]; then
dialog --title "$title" --msgbox "$text" 0 0
else
zenity --error --title="$title" --text="$text"
fi
fi
exit 1
}

info() {
        title="$1"
        text="$2"

        if [ "$gui" = "bare" ]; then
                echo -e "$2"
        elif [ "$gui" = "dialog" ]; then
                dialog --title "$title" --msgbox "$text" 0 0
        else
                zenity --info --title="$title" --text="$text"
        fi
}

prog_output() {
text="$1"

if [ "$gui" = "bare" ]; then
cat
elif [ "$gui" = "dialog" ]; then
dialog --progressbox "$text" 0 0
else
# TODO: Can zenity properly show the console output?
cat
fi
}


ask() {
title="$1"
gui_text="$2$3"
console_text="$2$4"

if [ "$gui" = "bare" ]; then
echo -en "$console_text"
while true; do
read answer
case "$answer" in
Yes|yes|y)
return 0;;
No|no|n)
return 1;;
*)
echo -n "Yes or no? (y/n): ";;
esac
done
elif [ "$gui" = "dialog" ]; then
dialog --title "$title" --yesno "$gui_text" 0 0
return "$?"
else
zenity --question --width=450 --title="$title" --text="$gui_text"
return "$?"
fi
}

file_select() {
question="$1"
stype="$2"

if [ "$gui" = "bare" ]; then
while true; do
echo "$question: " >&2
read -e path
if [ [ ! -f "$path" ] && [ "$stype" = "file" ] ] || [ [ ! -d "$path" ] && [ "$stype" = "dir" ] ]; then
echo "$path doesn't exist! Please enter a valid path!" >&2
else
echo "$path"
return 0
fi
done
elif [ "$gui" = "dialog" ]; then
while true; do
if [ "$stype" = "file" ]; then
path="$(dialog --title "$question" --output-fd 1 --fselect "$HOME" 0 0)"
else
path="$(dialog --title "$question" --output-fd 1 --dselect "$HOME" 0 0)"
fi
if [ ! "$?" = "0" ]; then
return "$?"
fi
if [ [ ! -f "$path" ] && [ "$stype" = "file" ] ] || [ [ ! -d "$path" ] && [ "$stype" = "dir" ] ]; then
dialog --title "$question" --msgbox "$path doesn't exist! Please enter a valid path!" >&2
else
echo "$path"
break
fi
done
return "0"
else
if [ "$stype" = "file" ]; then
zenity --file-selection --title="$question"
else
zenity --file-selection --directory --title="$question"
fi
return "$?"
fi
}

show_progress() {
title="$1"
text="$2"

if [ "$gui" = "bare" ]; then
echo -n "$text"
while read line; do
echo -en "\r$text $line%"
done
echo
elif [ "$gui" = "dialog" ]; then
dialog --title "$title" --gauge "$text" 0 0
return "$?"
else
zenity --progress --width=450 --text="$text"
return "$?"
fi
}


# main script

#What this script does : extract base VP files from the Good Old Games Installer, drop the useless stuff, and put the VPs into /data to complete a base fs2_open install.
ask "FreeSpace 2 Base Files Extractor" \
 "This program will extract base files from the Good Old Games FreeSpace 2 installer for Microsoft Windows and place them into your FreeSpace 2 Open root folder.\n\nFreeSpace 2 Open may not work properly without these files.\n\nBefore starting the extraction process, please check that you have already bought and downloaded the FreeSpace 2 installer for Microsoft Windows from GoodOldGames.com .\n\nWARNING: Run this program as a superuser if FreeSpace 2 is installed as root.\n\n" \
 "Click \"Yes\" to proceed with the extraction." \
 "Type \"yes\" to proceed with the extraction."

if [ $? = "0" ]
then
# Check for innoextract.
if ! has innoextract; then
ask "Download innoextract?" "This script requires innoextract to extract the files from the Good Old Games FreeSpace 2 installer. You don't have it on your system." \
"Do you want me to download it?" \
"\n Shall I download it? (y/n): "
if [ "$?" = "0" ]; then
innoextract="$(mktemp)"
innoextract_tmp="yes"
dest="$(mktemp -d)"

pushd "$dest" > /dev/null
# TODO: Is there a link which always references the latest version?
download innoextract.tar.xz "http://downloads.sourceforge.net/innoextract/innoextract-1.4-linux.tar.xz"
tar -xJf innoextract.tar.xz

# Determine the current architecture.
if [ "$(uname -m)" = "x86_64" ] || [ "$(uname -m)" = "amd64" ]; then
mv innoextract-*/bin/amd64/innoextract "$innoextract"
else
mv innoextract-*/bin/i686/innoextract "$innoextract"
fi
popd > /dev/null
rm -r "$dest"
else
fail "Need innoextract!" "I can't continue without innoextract. Check http://constexpr.org/innoextract/ for more information on innoextract."
fi
else
innoextract="$(which innoextract)"
innoextract_tmp="no"
fi

#User input : where is the GOG.com FS2 installer ? Plus a bunch of checks
GOG_INSTALLER=`file_select "Select the Good Old Games installer" file`

case $? in
0)
      echo "\"$GOG_INSTALLER\" is selected.";;
1)
      echo "No file selected.";;
-1)
      echo "Uneexpected error.";;
esac

#User input : where is FS2 installed ? Plus a bunch of checks
FS2_DIRECTORY=`file_select "Select FreeSpace 2 game root folder" dir`

case $? in
0)
      echo "\"$FS2_DIRECTORY\" is selected.";;
1)
      echo "No file selected.";;
-1)
      echo "Unexpected error.";;
esac

#We work in the FS2 install folder
cd "$FS2_DIRECTORY"

#/data folder is created
[ ! -d "$FS2_DIRECTORY/data" ] && mkdir "$FS2_DIRECTORY/data"

#We need somewhere to put the mess included in the GOG installer, as the backend of this script (innoextract) is not able to extract individual files
tmp_dest="$(mktemp -d)"
cd "$tmp_dest"

#Important things going on here. innoextract is absolutely needed to crack open the GOG installer. It's in the Ubuntu repository, i don't know about other distros. I should include a check to verify if it's installed. Or even have innoextract as a dependency if somehow it gets packaged.
"$innoextract" -L -q --progress=true -e "$GOG_INSTALLER" | sed -n -u -E 's/(^|.*[^0-9])([0-9]{1,3})(\.[0-9])%.*/\2/p' | show_progress "FreeSpace 2 Base Files Extractor" "Extracting files..."

if [ "$?" -gt 0 ]
then
#Extraction failure
    fail "FreeSpace 2 Base Files Extractor" "Extraction process aborted."
else
#If the extraction is successful, we move the VP files to the data folder.
mv app/*.vp "$FS2_DIRECTORY/data/"
#we could also keep the MVE movies. I guess everyone uses the OGG ones now. Not sure. This part could also include md5sum checks, just to be sure...
info "FreeSpace 2 Base Files Extractor" "Extraction process complete.\n\nYou may now run the original FreeSpace 2 game using an appropriate launcher, or acquire mods for an even better experience.\nMore information at www.hard-light.net ."
fi

#Anyway we remove useless
cd "$FS2_DIRECTORY"
rm -Rf "$tmp_dest"

if [ "$innoextract_tmp" = "yes" ]; then
rm "$innoextract"
fi

else
info "FreeSpace 2 Base Files Extractor" "Extraction aborted. Nothing to do."
fi

 

Offline Hellzed

  • 28
Re: [Linux] Good Old Games installer base files extractor (bash script)
That's awesome !

Maybe you want to take a look at what I did next ?
http://www.hard-light.net/forums/index.php?topic=86364.0

 

Offline ngld

  • Administrator
  • 29
  • Knossos dev
Re: [Linux] Good Old Games installer base files extractor (bash script)
Thanks! Did you check if it still works? It worked fine for me but you never know...


  

Offline Hellzed

  • 28
Re: [Linux] Good Old Games installer base files extractor (bash script)
I didn't try it yet, I'll have to download a new copy of the GOG installer (I recently made some space on my download folder...). I'll let you know.