#!/bin/bash -
#===============================================================================
#
#          FILE: TestCtrl
#
#         USAGE: TestCtrl <Command>
#
#   DESCRIPTION: TEST Server Controller
#
#       OPTIONS: All options: run this script without any command will show
#
#  REQUIREMENTS:
#
#         NOTES: ALL CONFIG INSIDE ~/.gamerc, DO NOT EDIT THIS FILE.
#
#          BUGS:  ---
#        AUTHOR: rickz (Rick Zhang), xlrickz@gmail.com
#       COMPANY: X-LEGEND Entertainment Corp.
#       CREATED: Mon May 16 22:41:52 EDT 2011
#      REVISION: 1.0
#
#          TODO:
#
#===============================================================================

#set -o nounset                              # Treat unset variables as an error
set -m                                       # Enable job control

#############################################################################
#                                                                           #
#                           DO NOT EDIT THIS FILE                           #
#                            EDIT ~/.gamerc ONLY                            #
#                                                                           #
#############################################################################
[ -r ~/.gamerc ] && source ~/.gamerc || exec echo "Error: Read ~/.gamerc failed."

egrep -q "TEST|CTRL|SUB|DATA|DLC|TIME1|MEDIA" <<< "$HOST_NAME" || exec echo "Error: TestCtrl can only run on TEST server."

# What to do?
ACTION="$1"

# The customized function file
NANO_SECOND="$(date +%N)"
CUSTFUNC="/tmp/customized_function.$NANO_SECOND"
sed '/ -> /,/^}/d' $(dirname $0)/customized_function > $CUSTFUNC
echo >> $CUSTFUNC

# Log on begin
TTY="$(awk -F/dev/ '{print $2}' <<< "$SSH_TTY")"
SOURCEIP="$(try_to_get_full_hostname $(awk '{print $1}' <<< "$SSH_CLIENT"))"
LOGIN_USER=$(who -m|awk '{print $1}')
DATE_NOW="$(date +%Y/%m/%dT%H:%M:%S)"
[ "$ACTION" == "" ] && DO="NOTHING-TO-DO" || DO="$(head -c 12 <<< "$ACTION                 ")"
echo -e "$DATE_NOW\tBegin\t$DO\tAns:$ANSWER\tLogin:$LOGIN_USER\tUser:$USER\tTTY:$TTY\tIP:$SOURCEIP\tARG:$*" >> "$TESTCTRL_LOGFILE"

ulogger $0 Begin $DO <<< $*

# Detect the ACTION right or not
grep -h "^[A-Za-z0-9_-]* *(" $CUSTFUNC "$0"|awk '{print $1}'|grep -q "^$ACTION$" || ACTION="show_help"
[ "$ACTION" == "" ] && ACTION="show_help"
DESCRIPTION="$(grep "^$ACTION .*" $0 $CUSTFUNC|tail -1|awk -F"# " '{print $2}'|awk -F'..argument' '{print $1}'|tr -d '\n')"

#############################
# Built-in script functions #
#############################
show_cmd () {
  for CMD in $(grep -h "^[a-zA-Z0-9_-].*().* # " $CUSTFUNC $0|grep -v "##"|grep -v -- " -> "|awk '{print $1}'|sort|uniq) ; do
	  DESCRIPTION="$(grep -h "^$CMD.* # " $CUSTFUNC $0|head -1|awk -F"# " '{print $2}')"
          echo -n "$CMD" | colorize cyan black
	  echo " -> $DESCRIPTION"
  done
}

show_help () {
	echo $"Usage: $0 <Command>

Commands:
$(show_cmd)

Usage of patch:
$0 patch <target> <client patch(ZIP) or server data and binary(tarball)> [noftp|norestart|noserver|noclient]

for example.
$0 patch TEST 20110601165519bz2.zip/servers-001.002.02.10.tgz.271
or
$0 patch TEST 001.001.24.24_5

PS. target name please refer to the file ~/bin/worlds.test
"
}

#####################
# Command functions #
#####################
patch () { # Apply the patch (arguments: "noftp", "norestart", "noserver", "noclient", "nobuild")
   PATCH_TARGET="$ARG2"
   CLIENT_PATCH_DIRNAME="$(echo $CLIENT_PATCH_PACKAGE|awk -F\. '{print $1}')"
   [ "$ARG3" == "" ] && exec echo "Usage: $0 patch <target> <server> <client> [noftp|norestart|noserver|noclient|nobuild]"
   [ "$(get_world_num $PATCH_TARGET)" == "" ] && exec echo "Error: Target $PATCH_TARGET not found."
   mkdir -p $LOCAL_PATCH_DIR
   grep -q "noftp" <<< "$ALLARGS" || get_patch_from_remote $ARG3 $ARG4 $ARG5 $ARG6

   if [ "$GAME_TYPE" == "N1" ]; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls [sS]erver*.tar.gz 2>/dev/null | head -1)"
        SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls [cC]lient*.tar.gz 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        H5_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls h5_client*.tar.gz 2>/dev/null | head -1)"
        H5_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        APK_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.apk 2>/dev/null | head -1)"
        APK_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        IPA_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.ipa 2>/dev/null | head -1)"
        IPA_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        AAB_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.aab 2>/dev/null | head -1)"
        AAB_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        AAB_SYMBOLS_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.symbols.zip 2>/dev/null | head -1)"
        AAB_SYMBOLS_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   fi

   echo -n "Server file: " | colorize yellow
   [ -f "$SERVER_PATCH_FULL_PATH/$SERVER_PATCH_PACKAGE" ] \
   && echo "$SERVER_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   echo -n "Client file: " | colorize yellow
   [ -f "$CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE" ] \
   && echo "$CLIENT_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   echo -n "APK file: " | colorize yellow
   [ -f "$APK_PATCH_FULL_PATH/$APK_PATCH_PACKAGE" ] \
   && echo "$APK_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   echo -n "IPA file: " | colorize yellow
   [ -f "$IPA_PATCH_FULL_PATH/$IPA_PATCH_PACKAGE" ] \
   && echo "$IPA_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   #echo -n "OBB file: " | colorize yellow
   #[ -f "$OBB_PATCH_FULL_PATH/$OBB_PATCH_PACKAGE" ] \
   #&& echo "$OBB_PATCH_PACKAGE" | colorize green \
   #|| echo "Not found." | colorize red

   #echo -n "APKS file: " | colorize yellow
   #[ -f "$APKS_PATCH_FULL_PATH/$APKS_PATCH_PACKAGE" ] \
   #&& echo "$APKS_PATCH_PACKAGE" | colorize green \
   #|| echo "Not found." | colorize red

   echo -n "AAB file: " | colorize yellow
   [ -f "$AAB_PATCH_FULL_PATH/$AAB_PATCH_PACKAGE" ] \
   && echo "$AAB_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   echo -n "AAB Symbols file: " | colorize yellow
   [ -f "$AAB_SYMBOLS_PATCH_FULL_PATH/$AAB_SYMBOLS_PATCH_PACKAGE" ] \
   && echo "$AAB_SYMBOLS_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   echo -n "H5 file: " | colorize yellow
   [ -f "$H5_PATCH_FULL_PATH/$H5_PATCH_PACKAGE" ] \
   && echo "$H5_PATCH_PACKAGE" | colorize green \
   || echo "Not found." | colorize red

   sleep 5

   # Server side patch
   if [ -f "$SERVER_PATCH_FULL_PATH/$SERVER_PATCH_PACKAGE" ] && ! grep -q "noserver" <<< "$ALLARGS" ; then
	grep -q "norestart" <<< "$ALLARGS" && ulogger_echo "Okay, you choose to manually stop." | colorize cyan || $0 stop
	mkdir -p $WORKING_DIRECTORY/common-$PATCH_TARGET

	mkdir -p $WORKING_DIRECTORY/servers1
	mkdir -p $WORKING_DIRECTORY/servers10
	mkdir -p $WORKING_DIRECTORY/servers20
	mkdir -p $WORKING_DIRECTORY/servers30

	echo -n "Extracting the server file $SERVER_PATCH_PACKAGE ... " | colorize yellow
	tar zxf "$SERVER_PATCH_FULL_PATH/$SERVER_PATCH_PACKAGE" -C $WORKING_DIRECTORY/common-$PATCH_TARGET \
	&& echo "OK" | colorize green || exec echo "FAILED"

	if ! grep -q "nobuild" <<< "$ALLARGS";then
        # Verify and Update PEM
        verify_and_update_pem

		# Common
		echo yes|SKServer BuildIfNotExist SetDir 1
		echo yes|SKServer BuildIfNotExist ACCOUNTDB 1

		# Region 1, 2, 3
		echo yes|SKServer BuildIfNotExist SetDir 10
		echo yes|SKServer BuildIfNotExist SetDir 20
		echo yes|SKServer BuildIfNotExist SetDir 30

        if [ "$ENABLE_SOCIETY" == "1" ]; then
            echo yes|SKServer BuildIfNotExist SOCIETYDB 10
            echo yes|SKServer BuildIfNotExist SocietyS 10

            echo yes|SKServer BuildIfNotExist SOCIETYDB 20
            echo yes|SKServer BuildIfNotExist SocietyS 20

            echo yes|SKServer BuildIfNotExist SOCIETYDB 30
            echo yes|SKServer BuildIfNotExist SocietyS 30
        fi

		echo yes|SKServer BuildIfNotExist GAMEDB 10
		echo yes|SKServer BuildIfNotExist GAMEDB 20
		echo yes|SKServer BuildIfNotExist GAMEDB 30

		echo yes|SKServer BuildIfNotExist WORLDDB 10 1001
		echo yes|SKServer BuildIfNotExist WORLDDB 20 2001
		echo yes|SKServer BuildIfNotExist WORLDDB 30 3001

		echo yes|SKServer BuildIfNotExist Ticket 1
		echo yes|SKServer BuildIfNotExist Login 1 1
		echo yes|SKServer BuildIfNotExist Login 1 2
		echo yes|SKServer BuildIfNotExist Httpa 1 1
		echo yes|SKServer BuildIfNotExist Httpa 1 2
		echo yes|SKServer BuildIfNotExist LWebSocketProxyS 1 1
		echo yes|SKServer BuildIfNotExist LWebSocketProxyS 1 2

        #echo yes|SKServer BuildIfNotExist SocietyS 10
        #echo yes|SKServer BuildIfNotExist SocietyS 20
        #echo yes|SKServer BuildIfNotExist SocietyS 30

		echo yes|SKServer BuildIfNotExist GameDBS 10
		echo yes|SKServer BuildIfNotExist GameDBS 20
		echo yes|SKServer BuildIfNotExist GameDBS 30

		echo yes|SKServer BuildIfNotExist Mission 10
		echo yes|SKServer BuildIfNotExist Mission 20
		echo yes|SKServer BuildIfNotExist Mission 30

		echo yes|SKServer BuildIfNotExist WorldS 10 1001
		echo yes|SKServer BuildIfNotExist WorldS 20 2001
		echo yes|SKServer BuildIfNotExist WorldS 30 3001
		echo yes|SKServer BuildIfNotExist WorldHttpa 10 10011
		echo yes|SKServer BuildIfNotExist WorldHttpa 20 20011
		echo yes|SKServer BuildIfNotExist WorldHttpa 30 30011
		echo yes|SKServer BuildIfNotExist WWebSocketProxyS 10 10011
		echo yes|SKServer BuildIfNotExist WWebSocketProxyS 20 20011
		echo yes|SKServer BuildIfNotExist WWebSocketProxyS 30 30011

		echo yes|SKServer BuildIfNotExist RankS 10
		echo yes|SKServer BuildIfNotExist RankS 20
		echo yes|SKServer BuildIfNotExist RankS 30

		echo yes|SKServer BuildIfNotExist ChatS 10
		echo yes|SKServer BuildIfNotExist ChatS 20
		echo yes|SKServer BuildIfNotExist ChatS 30

		echo yes|SKServer BuildIfNotExist AcctDBS 1

		update_society_ip EXT
		update_society_ip INT
		update_empty_society_port EXT
		update_empty_society_port INT
		update_empty_gds_port
        update_empty_ms_ip
		update_empty_ranks_port
		update_empty_chats_port

		ln -s ~/bin/S_RootCmds.ini_test_$GAME_TYPE_LOWER $WORKING_DIRECTORY/common-$PATCH_TARGET/Data/db/s_rootcmds.ini 2> /dev/null
	else
		ulogger_echo "Okay, nobuild this time." | colorize cyan
	fi
        ulogger_echo "Starting backup accountdb database(${ACCOUNT_DB_NAME})-$(date +%Y%m%dT%H%M))" | colorize green black
	    DBbackup ${ACCOUNT_DB_NAME}
        ulogger_echo "Starting backup game database(${GAME_DB_NAME}10)-$(date +%Y%m%dT%H%M))" | colorize green black
    	DBbackup ${GAME_DB_NAME}10
        sleep 2
        ulogger_echo "Starting backup game database(${GAME_DB_NAME}20)-$(date +%Y%m%dT%H%M))" | colorize green black
	    DBbackup ${GAME_DB_NAME}20
        sleep 2
        ulogger_echo "Starting backup game database(${GAME_DB_NAME}30)-$(date +%Y%m%dT%H%M))" | colorize green black
    	DBbackup ${GAME_DB_NAME}30
        sleep 2
        ulogger_echo "Starting backup world database(${WORLD_DB_NAME}1001)-$(date +%Y%m%dT%H%M))" | colorize green black
	    DBbackup ${WORLD_DB_NAME}1001
        sleep 2
        ulogger_echo "Starting backup world database(${WORLD_DB_NAME}2001)-$(date +%Y%m%dT%H%M))" | colorize green black
    	DBbackup ${WORLD_DB_NAME}2001
        sleep 2
        ulogger_echo "Starting backup world database(${WORLD_DB_NAME}3001)-$(date +%Y%m%dT%H%M))" | colorize green black
	    DBbackup ${WORLD_DB_NAME}3001
        sleep 2
	(
 	   cd $WORKING_DIRECTORY/common-$PATCH_TARGET/db/
	   psql $ACCOUNT_DB_NAME <<< "delete from configuration where schema_version=0;"
	   perl db_account_alter :$ACCOUNT_DB_NAME

	   perl db_game_alter :${GAME_DB_NAME}10
	   perl db_game_alter :${GAME_DB_NAME}20
	   perl db_game_alter :${GAME_DB_NAME}30

	   perl db_world_alter :${WORLD_DB_NAME}1001
	   perl db_world_alter :${WORLD_DB_NAME}2001
	   perl db_world_alter :${WORLD_DB_NAME}3001

       if [ "$ENABLE_SOCIETY" == "1" ]; then
           perl db_society_alter :${SOCIETY_DB}10
           perl db_society_alter :${SOCIETY_DB}20
           perl db_society_alter :${SOCIETY_DB}30
       fi
	)
	echo y|$0 itemmall

        if [ "$SET_EVERY_CHARACTERS_PRIVILEGE_TO_2" == "1" ] ; then
            echo "Set every character's privilege to 2 ... " | colorize yellow black
            psql -U postgres ${GAME_DB_NAME}10 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT 2;"
	        psql -U postgres ${GAME_DB_NAME}10 <<< "UPDATE player_characters SET privilege = 2;"

            psql -U postgres ${GAME_DB_NAME}20 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT 2;"
	        psql -U postgres ${GAME_DB_NAME}20 <<< "UPDATE player_characters SET privilege = 2;"

            psql -U postgres ${GAME_DB_NAME}30 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT 2;"
	        psql -U postgres ${GAME_DB_NAME}30 <<< "UPDATE player_characters SET privilege = 2;"
        fi

        if [ "$SET_EVERY_CHARACTERS_PRIVILEGE_AFTER_PATCH" == "1" ] ; then
            if [ "$SET_EVERY_CHARACTERS_PRIVILEGE_TO" == "" ] ; then
                echo "Warning: set privilege failed to unknown level." | colorize red black
            else
                echo "Set every character's privilege to $SET_EVERY_CHARACTERS_PRIVILEGE_TO ... " | colorize yellow black
                psql -U postgres ${GAME_DB_NAME}10 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"
                psql -U postgres ${GAME_DB_NAME}10 <<< "UPDATE player_characters SET privilege = $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"

                psql -U postgres ${GAME_DB_NAME}20 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"
                psql -U postgres ${GAME_DB_NAME}20 <<< "UPDATE player_characters SET privilege = $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"

                psql -U postgres ${GAME_DB_NAME}30 <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"
                psql -U postgres ${GAME_DB_NAME}30 <<< "UPDATE player_characters SET privilege = $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"
            fi
        fi

        if [ -e "$HOME/bin/ibackup.conf" ] ; then
            source $HOME/bin/ibackup.conf
            if [ "$PATCH_TARGET" == "TEST" ] ; then
                grep -q testserver $IBACKUP_LIST \
                && ibackup backup testserver "Restore to $SERVER_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file "
            else
                grep -q testserver-$PATCH_TARGET $IBACKUP_LIST \
                && ibackup backup testserver-$PATCH_TARGET "Restore to $SERVER_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file "
            fi
        fi
	grep -q "norestart" <<< "$ALLARGS" && ulogger_echo "Okay, you choose to manually start." | colorize cyan || $0 start
   fi

   if [ -f "$CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE" ] && ! grep -q "noclient" <<< "$ALLARGS" ; then
	mkdir -p $WORKING_DIRECTORY/patch/tmp $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET

        echo "Extracting client patch files ... " | colorize green
	if [ "$GAME_TYPE" == "N1" ] ; then
		tar xvf $CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE -C $WORKING_DIRECTORY/patch/tmp
	fi


        if [ "$GAME_TYPE" == "N1" ] ; then
        	cp -axfv $WORKING_DIRECTORY/patch/tmp/. $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/
        fi

        if [ -e "$HOME/bin/ibackup.conf" ] ; then
            source $HOME/bin/ibackup.conf
            if [ "$PATCH_TARGET" == "TEST" ] ; then
                grep -q clientpatch $IBACKUP_LIST \
                && ibackup backup clientpatch "Restore to $CLIENT_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file " \
                || echo "WARNING: incremental backup has not been set for client patch, please install rdiff-backup and setup ibackup." | colorize red black
            else
                grep -q clientpatch-$PATCH_TARGET $IBACKUP_LIST \
                && ibackup backup clientpatch-$PATCH_TARGET "Restore to $CLIENT_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file " \
                || echo "WARNING: incremental backup has not been set for client patch, please install rdiff-backup and setup ibackup." | colorize red black
            fi
        fi
	[ "$TEST_PATCH_CDN_SYNC_CMDLINE" == "" ] || eval $TEST_PATCH_CDN_SYNC_CMDLINE "$CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE"
	rm -rf $WORKING_DIRECTORY/patch/tmp
   fi

   # H5 patch
   if [ -f "$H5_PATCH_FULL_PATH/$H5_PATCH_PACKAGE" ] && ! grep -q "noclient" <<< "$ALLARGS" ; then
    mkdir -p $WORKING_DIRECTORY/patch/tmp_h5 $PATCH_TARGET_H5_DIR-$PATCH_TARGET

        echo "Extracting h5 patch files ... " | colorize green
    if [ "$GAME_TYPE" == "N1" ] ; then
        tar xvf $H5_PATCH_FULL_PATH/$H5_PATCH_PACKAGE -C $WORKING_DIRECTORY/patch/tmp_h5
    fi


        if [ "$GAME_TYPE" == "N1" ] ; then
            cp -axfv $WORKING_DIRECTORY/patch/tmp_h5/. $PATCH_TARGET_H5_DIR-$PATCH_TARGET/
        fi

        if [ -e "$HOME/bin/ibackup.conf" ] ; then
            source $HOME/bin/ibackup.conf
            if [ "$PATCH_TARGET" == "TEST" ] ; then
                grep -q h5 $IBACKUP_LIST \
                && ibackup backup h5 "Restore to $H5_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file " \
                || echo "WARNING: incremental backup has not been set for h5, please install rdiff-backup and setup ibackup." | colorize red black
            else
                grep -q h5-$PATCH_TARGET $IBACKUP_LIST \
                && ibackup backup h5-$PATCH_TARGET "Restore to $H5_PATCH_PACKAGE" 2>&1 | grep -v "Processing changed file " \
                || echo "WARNING: incremental backup has not been set for h5, please install rdiff-backup and setup ibackup." | colorize red black
            fi
        fi
    rm -rf $WORKING_DIRECTORY/patch/tmp_h5
   fi 

   # New Version Control Header Files Check Between Previous Version and This Version
   if [ -f "$SERVER_PATCH_FULL_PATH/$SERVER_PATCH_PACKAGE" ] && [[ $ENABLE_VERSIONDEF_CHECK -eq 1 ]]; then
	    if [ ! -e $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/VersionDef.h ]; then
		echo
		echo "VersionDef.h doesn't exist, please discuss with the programmer!" | colorize red black
	    else
   	    	version_def_check $PATCH_TARGET $(awk -F/ '{print $NF}' <<< "$ARG3")

   	    	[ -s /tmp/VersionDef.h-diff ]
   	    	empty_check=$(echo $?)

   	    	echo
   	    	if [[ $empty_check -eq 0 ]]; then
   	    	    echo "VersionDef.h Check (X)" | colorize red black
   	    	    echo "There are some differences between previous and this version." | colorize red black
   	    	    echo
   	    	    echo "===================================="
   	    	    cat /tmp/VersionDef.h-diff | grep "^[+-]"
   	    	    echo "===================================="
   	    	else
   	    	    echo "VersionDef.h Check (O)" | colorize green black
   	    	    echo "(O) There is no difference between previous and this version." | colorize green black
   	    	fi
	    fi
   	    echo
   fi

   # Deadline
   if [ -f "$SERVER_PATCH_FULL_PATH/$SERVER_PATCH_PACKAGE" ] && ! grep -q "noserver" <<< "$ALLARGS" ; then
        if [ "$GAME_TYPE" == "FF" ] || [ "$GAME_TYPE" == "AK" ] || [ "$GAME_TYPE" == "M11" ] || [ "$GAME_TYPE" == "M12" ] || [ "$GAME_TYPE" == "G1" ] || [ "$GAME_TYPE" == "G2" ] ; then
            DEADLINE="$(xcat $HOME/servers10/MissionServer10/Rank*.log.* | grep ",RankUpdate:" | sort -t , -k 2 | tail -1 \
                         | sed 's/^.*: Type=\([0-9]\+\) Group=\([0-9]\+\) Class=\([0-9]\+\),/20\1-\2-\3/g')"
        elif [ "$GAME_TYPE" == "AR" ] ; then
            DEADLINE="$(xcat $HOME/servers10/MissionServer10/Family.log.* | grep "FamilyUpdate," | sort -t , -k 2 | tail -1 \
                         | sed 's/^.*, Type=\([0-9]\+\) Group=\([0-9]\+\) Class=\([0-9]\+\)/20\1-\2-\3/g')"
        elif [ "$GAME_TYPE" == "DJ" ] ; then
            DEADLINE="$(xcat $HOME/servers10/MissionServer10/Isle.log.* | grep ",RankUpdate:" | sort -t , -k 2 | tail -1 \
                         | sed 's/^.*:Type=\([0-9]\+\) Group=\([0-9]\+\) Class=\([0-9]\+\),/20\1-\2-\3/g')"
        else
            DEADLINE="$(xcat $HOME/servers10/MissionServer10/Test.log.* | grep "Dead Line" | sort -t , -k 2 | tail -1 \
                         | sed 'y/\]\[/::/' | awk -F: '{print $(NF-3)}')"
        fi

        if [ -z "$DEADLINE" ] ; then
            echo "WARNING: No Deadline Found." | colorize red black 5
        else
            # DEADLINE ERROR DATE FIX
            DEADLINE_YEAR=$(echo ${DEADLINE} | cut -d - -f1)
            DEADLINE_MONTH=$(echo ${DEADLINE} | cut -d - -f2)
            DEADLINE_DAY=$(echo ${DEADLINE} | cut -d - -f3)

            if [ "${DEADLINE_MONTH}" == "2" ] && ([ "${DEADLINE_DAY}" == "29" ] || [ "${DEADLINE_DAY}" == "30" ]); then
                DEADLINE="${DEADLINE_YEAR}-2-28"
            elif ([ "${DEADLINE_MONTH}" == "2" ] || [ "${DEADLINE_MONTH}" == "4" ] || [ "${DEADLINE_MONTH}" == "6" ] || [ "${DEADLINE_MONTH}" == "9" ] || [ "${DEADLINE_MONTH}" == "11" ]) && ([ "${DEADLINE_DAY}" == "31" ]); then
                DEADLINE="${DEADLINE_YEAR}-${DEADLINE_MONTH}-30"
            fi

            DEADLINE_DATE="$(date -d $DEADLINE +%Y-%m-%d)"
            DEADLINE_DAY_REMAINING="$(( ($(date -d $DEADLINE +%s)-$(date +%s)) / 86400 ))"
            if [ $DEADLINE_DAY_REMAINING -lt 30 ] ; then
                echo -n "Deadline: $DEADLINE_DATE, " | colorize red black
                echo    "$DEADLINE_DAY_REMAINING days remaining." | colorize red black 5
            else
                echo "Deadline: $DEADLINE_DATE" | colorize green black
            fi
        fi
   fi

   # Mobile App
   if [ "$MOBILE" == "1" ] ; then
      #move_app_for_download $(basename $ARG3)
      #[ -f "$OBB_PATCH_FULL_PATH/$OBB_PATCH_PACKAGE" ] && move_android_file_for_download $(basename $ARG3) obb
      #[ -f "$APKS_PATCH_FULL_PATH/$APKS_PATCH_PACKAGE" ] && move_android_file_for_download $(basename $ARG3) apks
      [ -f "$AAB_PATCH_FULL_PATH/$AAB_PATCH_PACKAGE" ] && move_android_file_for_download $(basename $ARG3) aab
      [ -f "$IPA_PATCH_FULL_PATH/$IPA_PATCH_PACKAGE" ] && move_ios_file_for_download $(basename $ARG3) ipa
      [ -f "$APK_PATCH_FULL_PATH/$APK_PATCH_PACKAGE" ] && move_android_file_for_download $(basename $ARG3) apk
   fi

   # Parser INI to DB
   if [ "$GAME_TYPE" == "N1" ]; then
        ~/bin/check_resetservercmds_openacitvity 0 > /dev/null 2>&1
   fi

   output_filename="/tmp/test_patch_monitor.log"
   hostname_cht=$(hostname_mapping)
   echo "${hostname_cht}版本更新完成 可以測試囉!\n$ARG3\nServer: $SERVER_PATCH_PACKAGE\nClient: $CLIENT_PATCH_PACKAGE\nAAB: $AAB_PATCH_PACKAGE\nAAB Symbols: $AAB_SYMBOLS_PATCH_PACKAGE\nIPA: $IPA_PATCH_PACKAGE\nAPK: $APK_PATCH_PACKAGE\nH5: $H5_PATCH_PACKAGE" > $output_filename
   #send_messages_with_pic INFO test_patch  "測試機版本更新"
   send_messages_with_pic_by_thread_tag INFO test_patch  "${hostname_cht}版本更新" "test_patch" minute 10

   # Client Patch File Check
   #check_client_file $ARG3
   #check_client_file_should_not_exist bat lnk
   #generate_filelist_mapping_v2

   status
}

status () { # Status of the all test servers
   # List Test Server process
   ps -Ao pid,lstart,cmd f|grep "[A-Za-z]\+Server"|grep -v SKServer
}

start () { # Start all test servers
   SKServer start all
   status
}

stop () { # Stop all test servers
   SKServer stop all
}

restart () { # Restart all test servers
   stop
   start
}

itemmall () { # Update Promotion Files/Tables on TEST Server
   for SQL_FILE in $PROMOTION_FILES_APPLY_TO_TEST ; do
	echo "$SQL_FILE:" | colorize yellow
	psql $ACCOUNT_DB_NAME < $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE 2>&1 | uniq -c
   done
}

dbbackup () { # Backup databases
   DBbackup $ACCOUNT_DB_NAME
   DBbackup $MEMBER_DB_NAME
   if [ "$ENABLE_SOCIETY" == "1" ]; then
	for SET_ID in 10 20 30 ; do
	        DBbackup $SOCIETY_DB_NAME${SET_ID}
	done
   fi

   for SET_ID in 10 20 30 ; do
	DBbackup $GAME_DB_NAME${SET_ID}
   done

   for WORLD_ID in 1001 2001 3001 ; do
	DBbackup $WORLD_DB_NAME${WORLD_ID}
   done
}

reset () { # Reset the IP, Port, Server ID of the test servers

   if [ -f ~/bin/min_ports.$COUNTRY_CODE_LOWER ] ; then
       cat ~/bin/min_ports.$COUNTRY_CODE_LOWER > $WORKING_DIRECTORY/.min_ports
   else
       cat ~/bin/min_ports.default > $WORKING_DIRECTORY/.min_ports
   fi

   find ~/servers* | grep auto_start | xargs rm -fv

   rm -fv ~/.ports_should_not_public

   psql $ACCOUNT_DB_NAME <<< "delete from worlds;"

   for world in $(cat ~/bin/worlds.test) ; do
	psql $GAME_DB_NAME$(get_world_num $world) <<< "delete from serverstatus;"
   done

   echo "Okay, you can redo the patch to rebuild the test server right now." | colorize green
}

lgblock () { # Block the players by iptables firewall
    if [ "$LGFW_MODE" == "1" ] ; then
        sudo iptables-restore < $IPTABLES_LGFW_ON_CONFIG_FILE; sudo iptables -L -v -n
    elif [ "$LGFW_MODE" == "2" ] ; then
        for PORT in $LOGIN_SERVER_PORTS ;do
            for IP in $LOGIN_SERVER_ALLOW_IP ;do
                sudo iptables -v -A INPUT -p tcp -s $IP --dport $PORT -j ACCEPT
            done
            sudo iptables -v -A INPUT -p tcp --dport $PORT -j DROP
        done
        sudo iptables -L -v -n
    elif [ "$LGFW_MODE" == "3" ] ; then
        sudo su -l -c '/etc/init.d/iptables start'
        sudo su -l -c '/etc/init.d/iptables status'
    fi
}

lgallow () { # Allow the players by iptables firewall
    if [ "$LGFW_MODE" == "1" ] ; then
        sudo iptables-restore < $IPTABLES_LGFW_OFF_CONFIG_FILE; sudo iptables -L -v -n
    elif [ "$LGFW_MODE" == "2" ] ; then
        for PORT in $LOGIN_SERVER_PORTS ;do
            for IP in $LOGIN_SERVER_ALLOW_IP ;do
                sudo iptables -v -D INPUT -p tcp -s $IP --dport $PORT -j ACCEPT
            done
            sudo iptables -v -D INPUT -p tcp --dport $PORT -j DROP
        done
        sudo iptables -L -v -n
    elif [ "$LGFW_MODE" == "3" ] ; then
        sudo su -l -c '/etc/init.d/iptables stop'; sudo iptables -L -v -n
    fi
}

# Read customized function if exist
[ -f "$CUSTFUNC" ] && source $CUSTFUNC


###################################
# Start run the Command from here #
###################################
if [ "$ACTION" == "show_help" ] ; then
	show_help
else
	if grep -q "$ACTION" <<< "$DONT_ASK_YES_NO" ; then
		$ACTION
	else
		yesno2 $ACTION "$DESCRIPTION"
	fi
fi

rm -f $CUSTFUNC

# Log the time on the end
DATE_NOW="$(date +%Y/%m/%dT%H:%M:%S)"
echo -e "$DATE_NOW\t=End=\t$DO\tAns:$ANSWER\tLogin:$LOGIN_USER\tUser:$USER\tTTY:$TTY\tIP:$SOURCEIP\tARG:$*" >> "$TESTCTRL_LOGFILE"

ulogger $0 =End= $DO <<< $*

