Jump to content
Eternal Lands Official Forums
nightmarcus

Linux Game Installer

Recommended Posts

I decided that to help this game I'm going to write a python based installer for the game. The user needs to run the installer and it will automatically download and unzip the game folder to the location of their choosing, and then, if they instruct it to do so, download the music and place it in the correct location. It also will make a backup of the original el.ini file named el.ini.backup, and write a new one using only the necessary options, as well as changing the data_dir value so the game will work properly. The last part is just my attempt at making it completely automated because I'm not a python "expert" and I'm not too familiar with editing the contents of existing files, but I can make it write new ones, so that is the reason behind that. After I'm done, the only changes that ever need be made to the installer would be to change the filenames for the game and music zip files, and to accomodate any changes made to the el.ini file. I ran a search for Linux installer and didn't come up with anything in the forums, so I thought I would post this. When I'm done with the first draft, I will post the source code so you guys can fix any mistakes or make changes that would make the installer more efficient, etc. If I'm behind and there is an automated Linux installer in the works or already done and I've just missed it, let me know please.

Share this post


Link to post
Share on other sites

This isnt a suggestion (i suggest that)

But nice work btw

 

(ps. some mod should move this one to a better thread (my opinion))

Share this post


Link to post
Share on other sites

I've figured out the problem, fresh source coming soon.

Issue solved, I just removed EL from my computer altogether, .elc folder and everything, and used my own script to install it, and the game runs fine. Here's the fresh version of the installer.

If you want to run the installer right now here's how you can do it. Copy and paste the source into a text file and save it to your hard drive, then open a command line and cd into the folder where you saved it and run:

python filename

For example if you saved the file to your home folder as elinstaller you would just run:

python elinstaller

Hope this is helpful.

#Eternal Lands Python Installer
#This downloads and installs the MMORPG 'Eternal Lands'.
#Script written by Marcus Dean Adams (marcusdean.adams@gmail.com)
import os
import sys
import string
print ""
print "It is recommended that you have an 'always on' internet connection"
print "such as DSL, Cable, etc. because you are about to download the game."
print "If the download stalls or your internet connection gets interrupted,"
print "restarting this installer will resume the download where it left off."
print ""
print "Do not run this as root, if you do, you may be unable to play the game."
print ""
raw_input("Press Enter when you are ready to continue...")
print ""
ostype=sys.platform
if ostype=='linux' or ostype=='linux2':
#Begins the installation process if they are running linux.
os.system("wget -c http://el.other-life.com/downloads/el_133_linux_full.zip")
os.system("unzip el_133_linux_full.zip")
location=raw_input("Where do you want the game installed to? ")
os.system("mkdir '%s'" %(location))
os.system("mv -f 'Eternal Lands-1.33'/* '%s'" %(location))
#This asks the user if they want to download the game music, and acts accordingly.
getmusic=raw_input("Do you want to download the music?(An additional 66MB) ")
getmusic=string.lower(getmusic)
if getmusic=='y' or getmusic=='yes':
	os.system("wget -c http://www.eternalmusik.org/music/music_full.zip")
	os.system("unzip -d '%s'/music music_full.zip" %(location))
#Cleans up
	os.system("rmdir 'Eternal Lands-1.33'")
	os.system("rm music_full.zip")
	os.system("rm el_133_linux_full.zip")
#This creates a launcher.
launcher=open("eternallands", "w")
launcher.write("#!/bin/bash\n")
launcher.write("cd '%s'\n" %(location))
launcher.write("./el-133.x86.linux.static")
launcher.close()
os.system("chmod a+x eternallands")
os.system("mv -f eternallands $HOME/Desktop")
os.system("cp '%s'/el.ini '%s'/el.ini.backup" %(location, location))
#This writes a new el.ini file with only the necessary options
#and changes the data_dir according to the installation.
config=open("el.ini", "w")
config.write("This is a very barebones el.ini file created by Marcus's\n")
config.write("Python installer for Eternal Lands.  If you encounter any\n")
config.write("problems with it, delete this file, and rename the file\n")
config.write("el.ini.backup to just plain el.ini\n\n")
config.write("#server_address = game.eternal-lands.com\n")
config.write("#server_port = 2000\n")
config.write('#data_dir = "%s"\n'%(location))
config.close()
os.system("mv -f el.ini '%s'/el.ini" %(location))
#This launches the game for the user if they want.
print ""
print "A launcher named 'eternallands' for the game was placed on your"
print "Desktop.  To launch the game double click the launcher and if"
print "prompted click Run in Terminal."
print ""
print "To execute the game without the launcher just open the location"
print "the game was installed to and double click the el.x86.linux.static"
print "file and click 'Run in Terminal'."
print ""
launchnow=raw_input("Launch the game now?(y or n) ")
launchnow=string.lower(launchnow)
if launchnow=='y' or launchnow=='yes':
	os.system("$HOME/Desktop/eternallands")
else:
#This happens if they are not running Linux.
print ""
print "Sorry, this installer is for use only on Linux based operating"
print "systems.  The commands issued are only valid in such an environment."
print "It appears that you are using a(n)", ostype, "system."
print "To download Eternal Lands please visit www.eternal-lands.com"
raw_input("Press enter to exit...")

Edited by nightmarcus

Share this post


Link to post
Share on other sites

This is great and all, but can't you just do one post with the latest version and update that instead of making a new post every time you change one line?

Share this post


Link to post
Share on other sites

This is great and all, but can't you just do one post with the latest version and update that instead of making a new post every time you change one line?

 

Yeah sorry, I was kind of in a hurry, I've cleaned up the other posts now though, sorry for spamming so much.

Share this post


Link to post
Share on other sites

Nice work, I've always found installer type scripts difficult and time consuming to get working reliably. Yours works well. I have a few observations and suggestions :icon13:

 

1) The script probably needs a "#!" line at the start so it can be made executable.

 

2) The clean-up code is currently conditional on having downloaded the music.

 

3) You might want to make the removal of the zip files conditional.

 

4) I specified a relative path when I tested the script, e.g. "../el", this worked fine but put a relative path into the el.ini file and the launcher script too. This will fail when I run from another directory.

 

5) It might be nice to base the new el.ini file on any existing file in ~/.elc/ (sed springs to mind as a useful tool here).

 

6) Python is fine, I like and use it myself. However, when I see loads of os.system calls I can't help wondering why people just don't use bash directly. Its a very powerful language and could easily do this same job. Just an observation, that's all.

 

7) When is the GUI version coming? I'm a command line fan myself but this could easily have a GUI front end....

 

Edit:

8) You might want to put the changeable names and paths in as variables at the start of the script. Especially the ones that appear more than once.

Edited by bluap

Share this post


Link to post
Share on other sites

Thanks for the feedback. I'm not an "expert" programmer. I just threw this together in a little under a day so given some time I could probably learn what I need to in order to produce a good stable gui version. The reason I used python is because I can put together basic bash scripts to execute commands, but as far as taking input from a user and processing it I'm not sure how to do it with bash, and I wanted to get something put together so I used what I knew. I ship out for Basic Training (Army) next week though so I probably won't have much time to work on it for another month or so. I'll continue to work on it for the next week, and see what I can get done.

Edited by nightmarcus

Share this post


Link to post
Share on other sites

It wasn't meant as a criticisms, just an observation, plenty people write Python scripts doing lots of bash calls. I've been learning Python for a few years on and off and am still a just a beginner. If you want to do use input in bash, try the "read" command. The bash command "help" displays information about built-in bash functions, read included. So "help read" gives you the information on read.

Share this post


Link to post
Share on other sites

I don't know if we can assume all Linux players will have Python installed either. But, we also can't assume they all have sed for use with bash?

Share this post


Link to post
Share on other sites

But, we also can't assume they all have sed for use with bash?

 

I believe sed (and awk and the like) are a standard part of any *-ux distribution. I'd be less confident of having bash (vs other shells) than of having sed.

Share this post


Link to post
Share on other sites

But, we also can't assume they all have sed for use with bash?

 

I believe sed (and awk and the like) are a standard part of any *-ux distribution. I'd be less confident of having bash (vs other shells) than of having sed.

No, some have sed in an optional file or tex tools package. If an install script is going to be made some research should be done to see what method will have the least problems on current & recent distros.

Share this post


Link to post
Share on other sites

Until we get proper packaged versions of EL (e.g. deb/rpm etc which I believe some people are already working on) a Linux installer could be an optional tool for some people to use. Most people who might prefer to use an installer will be using one of the big distros, probably with a mostly default install. I would have thought bash/sh/sed and even python are available in most of these cases.

 

Having said all that, I agree, an official installer should be researched to make it work on as many systems as possible and to fail gracefully when things go wrong. A tall order as one of the best, fun aspects of Linux is how customisable it is and the fantastic diversity of distros. But you folks know all this so why am I wasting my keyboard. :happy:

Share this post


Link to post
Share on other sites

I wrote shell version (using only sh)

#!/bin/sh
adress="http://el.other-life.com/downloads/el_133_linux_full.zip"
zipname="el_133_linux_full.zip"
musicadress="http://www.eternalmusik.org/music/music_full.zip"
musicname="music_full.zip"
katname="Eternal Lands-1.33"
exename="./el-133.x86.linux.static"

echo "It is recommended that you have an 'always on' internet connection"
echo "such as DSL, Cable, etc. because you are about to download the game."
echo "If the download stalls or your internet connection gets interrupted,"
echo "restarting this installer will resume the download where it left off."
echo ""
echo "Do not run this as root, if you do, you may be unable to play the game."
echo ""
echo "Where do you want the game installed to?"
read location
mkdir "$location"
cd "$location"
wget -c $adress
unzip $zipname
mv -f "$katname"/* .
rmdir "$katname"

mv el.ini el.ini.backup
echo  "#server_address = game.eternal-lands.com" > el.ini
echo  "#server_port = 2000" >> el.ini
echo  "#data_dir = \"$location\"" >> el.ini

echo "#!/bin/sh" > eternallands
echo "cd \"$location\"" >> eternallands
echo "$exename" >> eternallands

chmod a+x eternallands
mv -f eternallands $HOME/Desktop

echo "Do you want to download the music? (An additional 66MB)  [y/n]"
read answer
if [[ $answer == "y" ]]; then
wget -c $musicadress;
unzip $musicname;
fi

echo "Delete .zip files ? [y/n]"
read answer
if [[ $answer == "y" ]]; then
 rm -f $zipname;
 rm -f $musicname;
fi

echo "Run game now ? [y/n]"
read answer
if [[ $answer == "y" ]]; then
$exename;
fi

 

It should do the same things as python script above but i have no time to test them both.

Share this post


Link to post
Share on other sites

This piques my interest. I will work on a system()-less script, and then on one that uses WxPython if DISPLAY is set, and on linux and the CLI if it's not, or on DOS, as if anyone could play EL that way... who knows [ELCHAT PLUG!!]. (WxPython because it's small enough to keep the download relatively small.) And removing sed refrences - python has a regex library to itself. This should come much much closer to working cross-system.. Getting started now!

 

There is a rather nice way to convert python scripts to a set of native executables and libraries. Frets on Fire uses it.. However, I hear the resulting binary gives a false positive on some AV tests.

Edited by freeone3000

Share this post


Link to post
Share on other sites

Done with the bash wrapper:

#!/bin/bash

#Checking for awk...
if [ -n `which awk` ]; then
awk=`which awk`
elif [ -n `which gawk` ]; then
awk=`which gawk`
else
echo "Please install AWK for install to proceed."
return 2;
fi
#End check

#Checking language...
if [ -z $1 ]; then
if [ -n `which locale` -a -n $awk ]; then
	mlocale=`echo $LANGUAGE | $awk -F: '{print $1}' | $awk -F_ '{print $1}'`
else
	while [ -z $mlocale ]; do
		echo "Please enter your two-letter language code.";
		read mlocale;
	done
fi
else
mlocale=$1;
fi
#End check

txtfile="run-text.${mlocale}.txt"
pyfile="main.py"

###
#This section should be changed on new versions, as it is dependant on EL.
address="http://el.other-life.com/downloads/el_133_linux_full.zip"
musicaddress="http://www.eternalmusik.org/music/music_full.zip"
dirname="Eternal Lands-1.33"
exename="./el-133.x86.linux.static"
ini="el.ini"
#End Section
###

function checkforyes {
unset resp;
while [ $resp != "y" -a $resp != "Y" ]; do
	echo $1;
	read resp;
	if [ $resp = "n" -o $resp = "N" ]; then
		return 1;
	fi
done
return 0;
}

function runcli {
unset words
#Checking that install is valid...
if [ ! -f $txtfile ]; then
	echo "There is no configuration file for your language.";
	return 1;
fi



wordlen=`wc -l $txtfile | $awk '{print $1}'`
i=1;
if [ -z `which head` -o -z `which tail` ]; then
	echo "Head or tail not found. Install both to continue.";
	return 1;
fi

words=( )
#Cutting file into array. # TODO: Make more efficient.
while [ $i -le `expr $wordlen + 1` ]; do
	words[$i]=`head -n $i < $txtfile | tail -n 1`;
	i=`expr $i + 1`
done
#Done cutting.

#From here on out, strings are localized.
echo ${words[1]}

#Root check..
if [ $UID -eq 0 ]; then
	checkforyes ${words[2]} || (echo ${words[11]} && return 3);
fi
#Done checking.

unset loc;
while [ -z $loc ]; do
	echo ${words[3]};
	read loc;
done

#Checking for dirname..
if [ -z `which dirname` ]; then
	echo ${words[12]}"dirname";
	return 1;
fi
#Done checking.

dir=`dirname $loc`
if [ -z $dir ]; then
	dir=$loc;
fi

#Checking for creation...
if [ ! -d $dir ]; then
	checkforyes ${words[5]} && mkdir -p $dir || (echo ${words[11]}; return 3);
fi
#End check

echo ${words[4]};

#Checking for writability...
fn=$RANDOM
while [ -f $dir/$fn ]; do
	fn=$RANDOM;
done

echo $RANDOM > $fn;
if [ ! -f $fn ]; then
	echo ${words[7]};
	return 4;
else
	echo ${words[6]};
	rm $fn;
fi
#End check

#Checking for wget
if [ -z `which wget` ]; then
	echo ${words[12]}"wget"
	return 4;
fi
#End check

#Checking for zip
if [ -z `which zip` ]; then
	echo ${words[12]}"unzip";
fi
#End Check

#Starting the install (FINALLY!)
cd "$dir"
wget -c "$address"
unzip "$zipname"
mv -f $dirname/* .
rm -rf $dirname

mv $ini $ini.backup
echo  "#server_address = game.eternal-lands.com" > $ini
echo  "#server_port = 2000" >> $ini
echo  "#data_dir = \"$dir\"" >> $ini

echo '#!/bin/sh' > 'eternallands'
echo "cd \"$dir\"" >> 'eternallands'
echo "$exename" >> 'eternallands'

if [ checkforyes ${words[8]} ]; then
	wget -c $musicaddress
	unzip $musicname
fi

if [ checkforyes ${words[9]} ]; then
	rm -f $musicname $zipname
fi

if [ -d $HOME/Desktop ]; then
	mv eternallands $HOME/Desktop
#else #Iunno.
fi

if [ checkforyes ${words[10]} ]; then
	$exename 2>&1 > /dev/null &
fi
echo "Install complete."
}

pyexe=`which python`
if [ -z $pyexe -o ! -f $pyfile ]; then
runcli;
else
$pyexe $pyfile $DISPLAY
fi

 

 

And the localization file (english):

It is reccomended that you have an 'always on' internet connection, such as DSL, cable, etc., because you are about to download the game. If the download stalls or your internet connection gets interrupted, this download will resume where it left off.
You are currently running as root. This may prevent you from playing the game. Continue? [y/n]
Where do you want the game installed to? (pathname)
Writing temp file...
The directory does not exist, create it?
Success! Starting install...
Failure. Please make sure you have permissions to write to the directory.
Do you want to download the music (Another 66MB)? [y/n]
Delete zip files? [y/n]
Run game now? [y/n]
Process cancelled by user.
Command required for install and not found: 

 

The bash script either uses builtins or checks which, since a lack of 'which' would be VERY, VERY bad.

Edited by freeone3000

Share this post


Link to post
Share on other sites

I like the shell script a lot. Hopefully we get someone to create a real rpm, that would be a major step forward.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×