Kaynağa Gözat

Merge pull request #4 from OpenGamePanel/master

Updating
rocco27 8 yıl önce
ebeveyn
işleme
a3ee41f266
3 değiştirilmiş dosya ile 264 ekleme ve 70 silme
  1. 1 0
      FastDownload/ForkedDaemon.pm
  2. 29 41
      includes/ogp_agent.init.dbn
  3. 234 29
      ogp_agent.pl

+ 1 - 0
FastDownload/ForkedDaemon.pm

@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use lib ".";
 use FastDownload::Settings; # Daemon Settings
 use Cwd;					# Fast way to get the current directory
 use Fcntl ':flock';			# Import LOCK_* constants for file locking

+ 29 - 41
includes/ogp_agent.init.dbn

@@ -12,11 +12,6 @@
 # Description:       Start and stop the OGP Agent
 ### END INIT INFO
 #
-set -e
-set -u
-${DEBIAN_SCRIPT_DEBUG:+ set -v -x}
-
-. /lib/lsb/init-functions
 
 agent_dir=OGP_AGENT_DIR
 agent_user=OGP_USER
@@ -27,17 +22,17 @@ agent_user=OGP_USER
 
 if [ "X`whoami`" != "Xroot" ]
 then
-	log_failure_msg "Permission denied."
 	exit 1
 fi
 
 start() {
 	if [ -e "$agent_dir/ogp_agent_run.pid" ]
 	then
-		if [ "X$(ps -A | grep -o `cat $agent_dir/ogp_agent_run.pid`)" != "X" ]
+		pid=$(cat $agent_dir/ogp_agent_run.pid)
+		out=$(kill -0 $pid > /dev/null 2>&1)
+		if [ $? == 0 ]
 		then
-			log_failure_msg "OGP Agent already running."
-			return 1
+			exit 1
 		fi
 	fi
 
@@ -50,22 +45,22 @@ start() {
 		fi
 		usermod -aG sudo $agent_user >/dev/null 2>&1
 	fi
-
-	# Had to add the "|| true" part to the end of the below command due to chown causing the entire bash script to exit on failure in case of protected files (that have chattr +i applied)
-	# http://unix.stackexchange.com/questions/118217/chmod-silent-mode-how-force-exit-code-0-in-spite-of-error
-	chown -Rf `id -u $agent_user`:`id -g $agent_user` $agent_dir >/dev/null 2>&1 || true
-
+	
+	user_id=$(id -u $agent_user)
+	group_id=$(id -g $agent_user)
+	out=$(chown -Rf $user_id:$group_id $agent_dir >/dev/null 2>&1)
+	
 	# Lets the agent user to attach screens.
-	if [ "$( groups $agent_user | grep "\btty\b" )" == "" ]
+	if [ "$(groups $agent_user|grep -o "\stty\s")" == "" ]
 	then
 		usermod -aG tty $agent_user >/dev/null 2>&1
 	fi
-
-	chmod g+rw /dev/pts/* >/dev/null 2>&1
-	chmod g+rw /dev/tty* >/dev/null 2>&1
+	
+	out=$(chmod g+rw /dev/pts/* >/dev/null 2>&1)
+	out=$(chmod g+rw /dev/tty* >/dev/null 2>&1)
 
 	# Check the FTP status
-	if [ -f "/etc/init.d/pure-ftpd" ] && [ -e "/etc/pure-ftpd/conf" ]
+	if [ -f "/etc/init.d/pure-ftpd" ] && [ -d "/etc/pure-ftpd/conf" ]
 	then
 		echo no > /etc/pure-ftpd/conf/PAMAuthentication
 		echo no > /etc/pure-ftpd/conf/UnixAuthentication
@@ -90,52 +85,45 @@ start() {
 		then
 			ln -s /etc/pure-ftpd/pureftpd.pdb /etc/pureftpd.pdb
 		fi
-		pure-pw mkdb >/dev/null 2>&1
-		service pure-ftpd force-reload >/dev/null 2>&1 &
+		out=$(pure-pw mkdb >/dev/null 2>&1)
+		out=$(service pure-ftpd force-reload >/dev/null 2>&1)
 	fi
 
 	cd $agent_dir
-	su -c "screen -d -m -t ogp_agent -c ogp_screenrc -S ogp_agent ./ogp_agent_run -pidfile ogp_agent_run.pid" $agent_user &> $agent_dir/ogp_agent.svc &
-	log_success_msg "OGP Agent started successfully."
-	echo "Use \"sudo su -c 'screen -S ogp_agent -r' $agent_user\" to attach the agent screen,"
-	echo "and CTRL+A+D to detach it."
-	return 0
+	out=$(su -c "screen -d -m -t ogp_agent -c ogp_screenrc -S ogp_agent ./ogp_agent_run -pidfile ogp_agent_run.pid" $agent_user >/dev/null 2>&1)
+	exit 0
 }
 
 stop() {
 	if [ -e "$agent_dir/ogp_agent_run.pid" ]
 	then
-		if [ "X$(ps -A | grep -o `cat $agent_dir/ogp_agent_run.pid`)" == "X" ]
+		pid=$(cat $agent_dir/ogp_agent_run.pid)
+		kill -0 $pid > /dev/null 2>&1
+		if [ $? == 0 ]
 		then
-			log_failure_msg "OGP Agent not running."
-		else
-			kill `cat $agent_dir/ogp_agent_run.pid` >/dev/null 2>&1
-			log_success_msg "OGP Agent stopped successfully."
+			kill $pid >/dev/null 2>&1
+			exit $?
 		fi
 	else
-		log_failure_msg "PID file not found ($agent_dir/ogp_agent_run.pid)"
+		exit 1
 	fi
-	return 0
+	exit 0
 }
 
 case "${1:-''}" in
-	start)
+	'start')
 	start
-	RETVAL=$?
 	;;
-	stop)
+	'stop')
 	stop
-	RETVAL=$?
 	;;
-	restart)
+	'restart')
 	stop
 	sleep 1
 	start
-	RETVAL=$?
 	;;
  	*)
 	echo "Usage: service ogp_agent start|stop|restart"
-	RETVAL=1
+	exit 1
 	;;
 esac
-exit $RETVAL

+ 234 - 29
ogp_agent.pl

@@ -350,7 +350,8 @@ my $d = Frontier::Daemon::OGP::Forking->new(
 				 shell_action					=> \&shell_action,
 				 remote_query					=> \&remote_query,
 				 send_steam_guard_code  		=> \&send_steam_guard_code,
-				 steam_workshop					=> \&steam_workshop
+				 steam_workshop					=> \&steam_workshop,
+				 get_workshop_mods_info			=> \&get_workshop_mods_info
 			 },
 			 debug	 => 4,
 			 LocalPort => AGENT_PORT,
@@ -4048,45 +4049,249 @@ sub steam_workshop
 }
 
 #### Run the steam client ####
-### @return 1 If update started
-### @return 0 In error case.
+### @return 1 If installation started
+### @return -1 In error case.
 sub steam_workshop_without_decrypt
 {
-	my ($home_id, $mods_path, $workshop_id, $workshop_mod_id) = @_;
-	
-	# Creates home path if it doesn't exist
-	if ( check_b4_chdir($mods_path) != 0)
+	my ($home_id, $mods_full_path,
+		$workshop_id, $mods_list,
+		$regex, $mods_backreference_index,
+		$variable, $place_after, $mod_string, 
+		$string_separator, $config_file_path, 
+		$post_install, $mod_names_list,
+		$anonymous_login, $user, $pass,
+		$download_method, $url_list, $filename_list) = @_;
+	
+	# Creates mods path if it doesn't exist
+	if ( check_b4_chdir($mods_full_path) != 0)
 	{
 		return -1;
 	}
-  
-    # Changes into root steamcmd OGP directory
-	if ( check_b4_chdir(STEAMCMD_CLIENT_DIR) != 0)
+	
+	my $secure = "$mods_full_path/secure.sh";
+	my $home_path = $mods_full_path;
+	$home_path =~ s/('+)/'\"$1\"'/g;
+	my $sec = $secure;
+	$sec =~ s/('+)/'\"$1\"'/g;
+	open  FILE, '>', $secure;
+	print FILE	"chmod 771 '$home_path'\n".
+				"rm -f '$sec'";
+	close FILE;
+	
+	my $screen_id = create_screen_id(SCREEN_TYPE_UPDATE, $home_id);
+	my @workshop_mods = split /,/, $mods_list;
+	my @installcmds;
+	
+	if($download_method eq 'steamcmd')
 	{
-		return -1;
+		my $steam_binary = STEAMCMD_CLIENT_BIN;
+		my $installSteamFile = $screen_id . "_workshop.txt";	
+		my $installtxt = Path::Class::File->new(STEAMCMD_CLIENT_DIR, $installSteamFile);
+
+		open  FILE, '>', $installtxt;
+		print FILE "\@ShutdownOnFailedCommand 1\n";
+		print FILE "\@NoPromptForPassword 1\n";
+		if($anonymous_login eq "0")
+		{
+			print FILE "login $user $pass\n";
+		}
+		else
+		{
+			print FILE "login anonymous\n";
+		}
+		print FILE "force_install_dir \"$mods_full_path\"\n";
+		foreach my $workshop_mod (@workshop_mods)
+		{
+			print FILE "workshop_download_item $workshop_id $workshop_mod\n";
+		}
+		print FILE "exit\n";
+		close FILE;
+		@installcmds = ("$steam_binary +runscript $installtxt +exit");
 	}
 	
-	my $screen_id = create_screen_id(SCREEN_TYPE_UPDATE, $home_id);
-	my $steam_binary = STEAMCMD_CLIENT_BIN;
-	my $installSteamFile = $screen_id . "_workshop.txt";
-		
-	my $installtxt = Path::Class::File->new($installSteamFile);
+	if($download_method eq 'steamapi')
+	{
+		my @urls =  split /,/, $url_list;
+		my @filenames =  split /,/, $filename_list;
+		my $index = 0;
+		foreach my $workshop_mod_id (@workshop_mods)
+		{
+			my $steamcmd_download_path = '/steamapps/workshop/content/'.$workshop_id.'/'.$workshop_mod_id.'/';
+			
+			my $workshop_mod_path = $mods_full_path.$steamcmd_download_path;
+			if(!-d $workshop_mod_path && !mkpath $workshop_mod_path)
+			{
+				logger "Folder $workshop_mod_path could not be created.";
+				$index++;
+				next;
+			}
+			my $url = $urls[$index];
+			my $filename = $filenames[$index];
+			my $download_file_path = Path::Class::File->new($workshop_mod_path, "$filename");
+			$installcmds[$index] = "wget -O \"$download_file_path\" \"$url\"";
+			$index++;
+		}
+	}
 	
-	open  FILE, '>', $installtxt;
-	print FILE "\@ShutdownOnFailedCommand 1\n";
-	print FILE "\@NoPromptForPassword 1\n";
-	print FILE "login anonymous\n";
-	print FILE "force_install_dir \"$mods_path\"\n";
-	print FILE "workshop_download_item $workshop_id $workshop_mod_id\n";
-	print FILE "exit\n";
-	close FILE;
-		
 	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
-	backup_home_log( $home_id, $log_file );
-			
-	my $screen_cmd = create_screen_cmd($screen_id, "$steam_binary +runscript $installtxt +exit");
-	logger "Installing Steam Workshop content with workshop id " . $workshop_id . " and workshop_mod_id " . $workshop_mod_id . " on server Home ID " . $home_id;
+	backup_home_log($home_id, $log_file);
+		
+	my $precmd = "";
+	my $postcmd = "";
+	
+	$postcmd .= generate_post_install_scripts($mods_full_path, $workshop_id, $mods_list,
+											  $regex, $mods_backreference_index,
+											  $variable, $place_after, $mod_string, 
+											  $string_separator, $config_file_path, 
+											  $post_install, $mod_names_list);
+	
+	my $bash_scripts_path = MANUAL_TMP_DIR . "/home_id_" . $home_id;
+	
+	if ( check_b4_chdir($bash_scripts_path) != 0)
+	{
+		return -1;
+	}
+	
+	my $installfile = create_bash_scripts($mods_full_path, $bash_scripts_path, $precmd, $postcmd, @installcmds);
+	
+	my $screen_cmd = create_screen_cmd($screen_id, "./$installfile");
+	
+	logger "Installing Steam Workshop content on server Home ID " . $home_id;
 	system($screen_cmd);
 	
 	return 1;
+}
+
+sub	generate_post_install_scripts
+{
+	my ($mods_full_path, $workshop_id, $mods_list,
+		$regex, $mods_backreference_index,
+		$variable, $place_after, $mod_string, 
+		$string_separator, $config_file_path, 
+		$post_install, $mod_names_list) = @_;
+	
+	my $post_install_scripts = "";
+	my $mods_info_path = Path::Class::Dir->new(AGENT_RUN_DIR, 'WorkshopModsInfo');
+	$post_install_scripts .= "mods_full_path=\"$mods_full_path\"\n".
+							 "workshop_id=\"$workshop_id\"\n".
+							 "regex=\"$regex\"\n".
+							 "mods_backreference_index=\"$mods_backreference_index\"\n".
+							 "variable=\"$variable\"\n".
+							 "place_after=\"$place_after\"\n".
+							 "string_separator=\"$string_separator\"\n".
+							 "config_file_path=\"$config_file_path\"\n".
+							 "mods_info_path=\"$mods_info_path/\"\n";
+	my @workshop_mods = split /,/, $mods_list;
+	my @mod_names = split /,/, $mod_names_list;
+	
+	my $index = 0;
+	foreach my $workshop_mod_id (@workshop_mods)
+	{
+		my $steamcmd_download_path = '/steamapps/workshop/content/'.$workshop_id.'/'.$workshop_mod_id.'/';
+		my $workshop_mod_path = $mods_full_path.$steamcmd_download_path;
+		my $this_mod_string = $mod_string;
+		$this_mod_string =~ s/\%workshop_mod_id\%/$workshop_mod_id/g;
+		
+		$post_install_scripts .= "mod_string[$index]=\"$this_mod_string\"\n".
+								 "mod_name[$index]=\"".$mod_names[$index]."\"\n".
+								 "workshop_mod_id[$index]=\"$workshop_mod_id\"\n".
+								 "workshop_mod_path[$index]=\"$workshop_mod_path\"\n";
+		$index++;
+	}
+	
+	$post_install_scripts .= 'if [ ! -e $config_file_path ];then'."\n".
+							 '	if [ ! -d "$(dirname $config_file_path)" ];then mkdir -p "$(dirname $config_file_path)";fi'."\n".
+							 '	echo -e "${place_after}\n${variable}" > $config_file_path'."\n".
+							 'fi'."\n".
+							 'i=0'."\n".
+							 'for mod_id in "${workshop_mod_id[@]}"'."\n".
+							 'do'."\n".
+							 '	first_file="$(ls "${workshop_mod_path[$i]}"| sort -n | head -1)"'."\n";
+	
+	my @post_install_lines = split /[\r\n]+/, $post_install;
+	foreach my $line (@post_install_lines) {
+		if($line ne ""){
+			$line =~ s/\%mods_full_path\%/\$mods_full_path/g;
+			$line =~ s/\%workshop_mod_id\%/\$mod_id/g;
+			$line =~ s/\%first_file\%/\$first_file/g;
+			$post_install_scripts .= "\t".$line."\n";
+		}
+	}
+	
+	$post_install_scripts .= '	file_content=$(cat $config_file_path)'."\n".
+							 '	if [[ $file_content =~ $regex ]]; then'."\n".
+							 '		full_match="${BASH_REMATCH[0]}"'."\n".
+							 '		mods_match="${BASH_REMATCH[$mods_backreference_index]}"'."\n".
+							 '		found=1'."\n".
+							 '	else'."\n".
+							 '		found=0'."\n".
+							 '	fi'."\n".
+							 '	first_file_string="\%first_file%"'."\n".
+							 
+							 '	if [ -z "${mod_string[$i]##*$first_file_string*}" ];then'."\n".
+							 '		mod_string[$i]="${mod_string[$i]/$first_file_string/$first_file}"'."\n".
+							 '	fi'."\n".
+							 '	if [ $found == 1 ] && [ "X$full_match" != "X" ];then'."\n".
+							 '		if [ "X$mods_match" == "X" ];then'."\n".
+							 '			new_mods=$(echo -e "${full_match}${mod_string[$i]}")'."\n".
+							 '			echo -e "${file_content/$full_match/$new_mods}">"$config_file_path"'."\n".
+							 '		else'."\n".
+							 '			if [ ! -z "${mods_match##*${mod_string[$i]}*}" ];then'."\n".
+							 '				new_mods=$(echo -e "${full_match}${string_separator}${mod_string[$i]}")'."\n".
+							 '				echo -e "${file_content/$full_match/$new_mods}">"$config_file_path"'."\n".
+							 '			fi'."\n".
+							 '		fi'."\n".
+							 '	else'."\n".
+							 '		if [ "X$place_after" == "X" ];then'."\n".
+							 '			echo -e "${file_content}${variable}${mod_string[$i]}">"$config_file_path"'."\n".
+							 '		else'."\n".
+							 '			if [ -z "${file_content##*${place_after}*}" ];then'."\n".
+							 '				new_var="${variable}${mod_string[$i]}"'."\n".
+							 '				place_after_esc=$(echo -e "$place_after"|sed -e \'s/[]\\/$*.^[]/\\\\&/g\')'."\n".
+							 '				echo -e "$file_content"|sed \'/\'$place_after_esc\'/a \'$new_var>"$config_file_path"'."\n".
+							 '			else'."\n".
+							 '				echo -e "${file_content}${place_after}\n${variable}${mod_string[$i]}">"$config_file_path"'."\n".
+							 '			fi'."\n".
+							 '		fi'."\n".
+							 '	fi'."\n".
+							 '	if [ ! -d "${mods_info_path}" ];then mkdir -p "${mods_info_path}";fi'."\n".
+							 '	echo "${mod_name[$i]}" > "${mods_info_path}${mod_string[$i]}.ogpmod"'."\n".
+							 '	i=$(expr $i + 1)'."\n".
+							 'done'."\n";
+	return "$post_install_scripts";
+}
+
+sub get_workshop_mods_info()
+{
+	return "Bad Encryption Key" unless(decrypt_param(pop(@_)) eq "Encryption checking OK");
+	
+	my $mods_info_dir_path = Path::Class::Dir->new(AGENT_RUN_DIR, 'WorkshopModsInfo');
+	
+	if(-d $mods_info_dir_path)
+	{
+		opendir(MODS_INFO_DIR, $mods_info_dir_path) or return -1;
+		my @mods_info;
+		while(my $mod_info_file = readdir(MODS_INFO_DIR))
+		{
+			if($mod_info_file =~ /\.ogpmod$/)
+			{
+				my $mod_info_file_path = Path::Class::File->new($mods_info_dir_path, $mod_info_file);
+				if(open(my $fh, '<:encoding(UTF-8)', $mod_info_file_path))
+				{
+					my $row = <$fh>;
+					chomp $row;
+					if($row ne "")
+					{
+						my ($string_name, $ext) = split(/\.ogp/, $mod_info_file);
+						push @mods_info, "$string_name:$row";
+					}
+					close($fh);
+				}
+			}
+		}
+		closedir(MODS_INFO_DIR);
+		return "1;".encode_list(@mods_info);
+	}
+	
+	return -1;
 }