#!/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" == "FN" ] ; then
	#SERVER_PATCH_PACKAGE="$(echo $ARG3/$ARG4/$ARG5/$ARG6|tr '/' '\n'|grep servers- | head -1)"
	#SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR"
	#CLIENT_PATCH_PACKAGE="$(echo $ARG3/$ARG4/$ARG5/$ARG6|tr '/' '\n'|grep zip | head -1)"
	#CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR"
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.tgz* 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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "JS" ] ; then
	SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/server/ ; ls * 2>/dev/null | head -1)"
	SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/server/"
	CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/client/ ; ls * 2>/dev/null | head -1)"
	CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/client/"
   elif [ "$GAME_TYPE" == "DJ" ] ; then
        #SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/ ; ls *.tar.gz *.tgz 2>/dev/null | head -1)"
        #SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/"
        #CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/ ; ls *TAR 2>/dev/null | head -1)"
        #CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/"
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "GD" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "LH" ] ; then
	SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/server/ 2>/dev/null ; ls *.tar.gz *.tgz 2>/dev/null | head -1)"
	SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/server/"
	CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$ARG3/client/ 2>/dev/null ; ls *.tar 2>/dev/null | head -1)"
	CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$ARG3/client/"
   elif [ "$GAME_TYPE" == "FF" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "G2" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "DS" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/server/ ; ls server*.tgz 2>/dev/null | head -1)"
        SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/server/"
        CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/ ; ls *.zip 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/"
   elif [ "$GAME_TYPE" == "AR" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.tgz* 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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "M2" ] ; then
        SERVER_PATCH_PACKAGE="$(echo $ARG3/$ARG4/$ARG5/$ARG6|tr '/' '\n'|grep Server- | head -1)"
        SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR"
        CLIENT_PATCH_PACKAGE="$(echo $ARG3/$ARG4/$ARG5/$ARG6|tr '/' '\n'|grep zip | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR"
   elif [ "$GAME_TYPE" == "LA" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
   elif [ "$GAME_TYPE" == "AK" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        #PACKAGE_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls package.tar 2>/dev/null | head -1)"
        #PACKAGE_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"

	cat $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_item.ini $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_itemmall.ini | egrep '^[0-9].*' | awk -F"|" '{print $1","$6","$7}' | grep '^[0-9]\{5\},' | egrep -v '^6100[1-7],' > /tmp/powerupitem_tw.csv
	cat $TRANSLATED_INI_UPLOAD_DIR/t_item.ini $TRANSLATED_INI_UPLOAD_DIR/t_itemmall.ini | egrep ^[0-9].* | awk -F"|" '{print $1","$2}' | sed 's/, /,/' | grep '^[0-9]\{5\},' | egrep -v '^6100[1-7],' > /tmp/powerupitem_kr.csv
	scp /tmp/powerupitem_tw.csv /tmp/powerupitem_kr.csv ctrl:/tmp
	ssh ctrl "psql -U postgres WebTool -c \"delete from powerupitem where item_id not in (61001,61002,61003,61004,61005,61006,61007)\""
	ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem (item_id,itemname,item_type_id) from '/tmp/powerupitem_tw.csv' csv\""
	ssh ctrl "psql -U postgres WebTool -c \"create table powerupitem_kr_temp (item_id integer, item_name text)\""
	ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem_kr_temp from '/tmp/powerupitem_kr.csv' csv\""
	ssh ctrl "psql -U postgres WebTool -c \"update powerupitem set itemname_kr = powerupitem_kr_temp.item_name from powerupitem_kr_temp where powerupitem.item_id = powerupitem_kr_temp.item_id\""
	ssh ctrl "psql -U postgres WebTool -c \"drop table powerupitem_kr_temp\""
   elif [ "$GAME_TYPE" == "M3" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/server/ ; ls *.tar.gz 2>/dev/null | head -1)"
        SERVER_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/server/"
        CLIENT_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/ ; ls *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/"
        CLIENT_PATCH_PACKAGE_PKG="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/ ; ls pkg.zip 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH_PKG="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/client/"
   elif [ "$GAME_TYPE" == "M11" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        cat $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_item.ini $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_itemmall.ini | egrep '^[0-9].*'| awk -F"|" '{print $1","$5","$6}' | grep '^[0-9]\{5\},' > /tmp/powerupitem_tw.csv
        cat $TRANSLATED_INI_UPLOAD_DIR/t_item.ini $TRANSLATED_INI_UPLOAD_DIR/t_itemmall.ini | egrep ^[0-9].* | awk -F"|" '{print $1","$2}' | sed 's/, /,/' | grep '^[0-9]\{5\},' > /tmp/powerupitem_kr.csv
        scp /tmp/powerupitem_tw.csv /tmp/powerupitem_kr.csv ctrl:/tmp
        ssh ctrl "psql -U postgres WebTool -c \"truncate powerupitem\""
        ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem (item_id,itemname,item_type_id) from '/tmp/powerupitem_tw.csv' csv\""
        ssh ctrl "psql -U postgres WebTool -c \"create table powerupitem_kr_temp (item_id integer, item_name text)\""
        ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem_kr_temp from '/tmp/powerupitem_kr.csv' csv\""
        ssh ctrl "psql -U postgres WebTool -c \"update powerupitem set itemname_kr = powerupitem_kr_temp.item_name from powerupitem_kr_temp where powerupitem.item_id = powerupitem_kr_temp.item_id\""
        ssh ctrl "psql -U postgres WebTool -c \"drop table powerupitem_kr_temp\""
   elif [ "$GAME_TYPE" == "M12" ] ; then
        SERVER_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls server*.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 *.tar 2>/dev/null | head -1)"
        CLIENT_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")/"
        OBB_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.obb 2>/dev/null | head -1)"
        OBB_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        APKS_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.apks 2>/dev/null | head -1)"
        APKS_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")/"
   elif [ "$GAME_TYPE" == "UG1" ] || [ "$GAME_TYPE" == "G1" ]; 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 *.tar 2>/dev/null | head -1)"
        CLIENT_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")/"
        OBB_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.obb 2>/dev/null | head -1)"
        OBB_PATCH_FULL_PATH="$LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/"
        APKS_PATCH_PACKAGE="$(cd $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/ ; ls *.apks 2>/dev/null | head -1)"
        APKS_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")/"
   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

   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/servers$(get_world_num $PATCH_TARGET)
	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 [ "$GAME_TYPE" == "JS" ] || [ "$GAME_TYPE" == "LH" ] || [ "$GAME_TYPE" == "DS" ] ; then
		cp -axf $WORKING_DIRECTORY/common-$PATCH_TARGET/servers/* $WORKING_DIRECTORY/common-$PATCH_TARGET
		rm -rf $WORKING_DIRECTORY/common-$PATCH_TARGET/servers
	fi
	if ! grep -q "nobuild" <<< "$ALLARGS";then
		yes|SKServer BuildIfNotExist SetDir $PATCH_TARGET
		yes|SKServer BuildIfNotExist GAMEDB $PATCH_TARGET

		yes|SKServer BuildIfNotExist ACCOUNTDB $PATCH_TARGET
                if [ "$ENABLE_SOCIETY" == "1" ]; then
                        yes|SKServer BuildIfNotExist SOCIETYDB $PATCH_TARGET
                        yes|SKServer BuildIfNotExist Society $PATCH_TARGET
                fi
		yes|SKServer BuildIfNotExist Mission $PATCH_TARGET
		yes|SKServer BuildIfNotExist Ticket $PATCH_TARGET
		if [ "$GAME_TYPE" != "UG1" ] ; then
			yes|SKServer BuildIfNotExist Gateway $PATCH_TARGET
		fi
		yes|SKServer BuildIfNotExist HTTPA $PATCH_TARGET
		yes|SKServer BuildIfNotExist Login 1
		#[ "$GAME_TYPE" == "FN" ] && yes|SKServer BuildIfNotExist WorldZone $PATCH_TARGET 0
		for((CH=1;CH<=$TEST_SERVER_CHANNELS;CH++));do
		    yes|SKServer BuildIfNotExist WorldZone $PATCH_TARGET $CH
		done
		[ "$GAME_TYPE" == "LH" ] && yes|SKServer BuildIfNotExist WorldZone $PATCH_TARGET $TERRITORY_CHANNEL
		[ "$GAME_TYPE" == "DJ" ] && yes|SKServer BuildIfNotExist WorldZone $PATCH_TARGET 9
		[ "$GAME_TYPE" == "M2" ] && yes|SKServer BuildIfNotExist GlobalServer $PATCH_TARGET
		[ "$GAME_TYPE" == "M12" -o "$GAME_TYPE" == "G1" -o "$GAME_TYPE" == "FN" -o "$GAME_TYPE" == "AR" -o "$GAME_TYPE" == "DJ" -o "$GAME_TYPE" == "GD" ] && yes|SKServer BuildIfNotExist AcctDB $PATCH_TARGET
		[ "$GAME_TYPE" == "G1" -o "$GAME_TYPE" == "G2" ] && yes|SKServer BuildIfNotExist GameDBServer $PATCH_TARGET
		[ "$GAME_TYPE" == "M12" -o "$GAME_TYPE" == "G1" -o "$GAME_TYPE" == "G2" -o "$GAME_TYPE" == "FN" -o "$GAME_TYPE" == "AR" -o "$GAME_TYPE" == "DJ" -o "$GAME_TYPE" == "GD" ] && yes|SKServer BuildIfNotExist GameAgentServer $PATCH_TARGET
		[ "$GAME_TYPE" == "G1" -o "$GAME_TYPE" == "G2" ] && yes|SKServer BuildIfNotExist SatelliteServer $PATCH_TARGET 1

		[ "$MOBILE" == "1" ] && yes|SKServer BuildIfNotExist HTTPA $PATCH_TARGET

		if [ ! -z "$CROSS_ROUTER_SID_TEST" ]; then
			build_set $CROSS_ROUTER_SID_TEST
		fi
                [ "$GAME_TYPE" == "G1" ] && yes|SKServer BuildIfNotExist CentralServer $CROSS_ROUTER_SID_TEST

		if [ "$MOBILE" == "1" ] ; then
			ln -s ~/bin/S_RootCmds.ini_test_$GAME_TYPE_LOWER $WORKING_DIRECTORY/common-$PATCH_TARGET/Data/db/s_rootcmds.ini 2> /dev/null
			cd $WORKING_DIRECTORY/common-$PATCH_TARGET/
			mkdir -p bin
			cd bin
			GAME_TYPE_LOWERCASE=$(echo ${GAME_TYPE} | tr '[:upper:]' '[:lower:]')
			if [ "$GAME_TYPE" == "UG1" ] ; then
				ln -s ../HTTPAgentServer/HTTPAgentServer HTTPAServer
				ln -s ../LoginServer/LoginServer
				ln -s ../MissionServer/MissionServer
				ln -s ../WorldServer/WorldServer
			elif [ "$GAME_TYPE" == "G1" ] ; then
				ln -s GameAgent GameAgentServer
			else
				ln -s ${GAME_TYPE_LOWERCASE}LoginServer LoginServer
				ln -s ${GAME_TYPE_LOWERCASE}MissionServer MissionServer
				ln -s ${GAME_TYPE_LOWERCASE}WorldServer WorldServer
			fi
			if [ "$GAME_TYPE" != "UG1" ] ; then
				ln -s ${GAME_TYPE_LOWERCASE}ZoneServer ZoneServer
			fi
            if [ ! -h HTTPAServer ] ; then
			    ln -s HTTPAgent HTTPAServer
            fi
			if [ "$GAME_TYPE" == "M12" ] ; then
				ln -s ${GAME_TYPE_LOWERCASE}AccountDBServer AccountDBServer
				ln -s GameAgent GameAgentServer
			fi
		else
			ln -s ~/bin/S_RootCmds.ini_test_$GAME_TYPE_LOWER $WORKING_DIRECTORY/common-$PATCH_TARGET/Data/db/S_RootCmds.ini 2> /dev/null
			ln -s ~/bin/S_GMToolCmds.ini_$GAME_TYPE_LOWER $WORKING_DIRECTORY/common-$PATCH_TARGET/Data/db/S_GMToolCmds.ini 2> /dev/null
		fi

                if [ "$GAME_TYPE" == "UG1" ] ; then
                    cd $WORKING_DIRECTORY/common-$PATCH_TARGET/
                    ln -s DBSchema db
                    mkdir -p bin; cd bin
                    	ln -s ../TicketServer/TicketServer
		    	ln -s ../HTTPAgentServer/HTTPAgentServer HTTPAServer
                    	ln -s ../LoginServer/LoginServer
                    	ln -s ../MissionServer/MissionServer
                    	ln -s ../WorldServer/WorldServer
                fi
		if [ "$GAME_TYPE" == "G1" ] ; then
			cd $WORKING_DIRECTORY/common-$PATCH_TARGET/
			ln -s DBSchema db
		fi
	else
		ulogger_echo "Okay, nobuild this time." | colorize cyan
	fi
        ulogger_echo "Starting backup game database($GAME_DB_NAME$(get_world_num $PATCH_TARGET)-$(date +%Y%m%dT%H%M))" | colorize green black
	DBbackup $GAME_DB_NAME$(get_world_num $PATCH_TARGET)
        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 dbalter :$GAME_DB_NAME$(get_world_num $PATCH_TARGET)
           if [ "$ENABLE_SOCIETY" == "1" ]; then
                perl db_society_alter :$SOCIETY_DB_NAME
           fi
	)
	if [ ! -z "$CROSS_ROUTER_SID_TEST" ]; then
		DBbackup $GAME_DB_NAME${CROSS_ROUTER_SID_TEST}
		cd $WORKING_DIRECTORY/common-$PATCH_TARGET/db/
		perl dbalter :${GAME_DB_NAME}${CROSS_ROUTER_SID_TEST}
	fi
	#NODESTREAM_COUNT=$(psql -U postgres $GAME_DB_NAME$(get_world_num $PATCH_TARGET) -c "COPY (SELECT COUNT(*) FROM node_stream) to stdout;")
        #if [ "$NODESTREAM_COUNT" == "0" ] ; then
        #    LOWER_GAME_TYPE=$(echo $GAME_TYPE | tr '[A-Z]' '[a-z]')
	#	    if [ -e "$HOME/bin/node_stream_${LOWER_GAME_TYPE}.sql" ]; then
	#		    SET_ID=$(get_world_num $PATCH_TARGET)
	#		    CHANNEL_ID="${SET_ID}0${TEST_SERVER_CHANNELS}0"
	#		    cat $HOME/bin/node_stream_${LOWER_GAME_TYPE}.sql | sed "s/XXXX/$CHANNEL_ID/g;s/999/$SET_ID/g" > /tmp/node_stream_${LOWER_GAME_TYPE}_test_s${SET_ID}.sql
	#		    PGPASSWORD="$TEST_SERVER_DB_PASSWORD" psql -U postgres $GAME_DB_NAME$(get_world_num $PATCH_TARGET) < /tmp/node_stream_${LOWER_GAME_TYPE}_test_s${SET_ID}.sql 2>&1 | sed 's/^/node_stream: /g'
	#	    fi
        #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$(get_world_num $PATCH_TARGET) <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT 2;"
            psql -U postgres $GAME_DB_NAME$(get_world_num $PATCH_TARGET) <<< "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$(get_world_num $PATCH_TARGET) <<< "ALTER TABLE player_characters ALTER COLUMN privilege SET DEFAULT $SET_EVERY_CHARACTERS_PRIVILEGE_TO;"
                psql -U postgres $GAME_DB_NAME$(get_world_num $PATCH_TARGET) <<< "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" == "M2" ] ; then
		unzip -qo $WORKING_DIRECTORY/patch/$CLIENT_PATCH_PACKAGE -d $WORKING_DIRECTORY/patch/tmp
        elif [ "$GAME_TYPE" == "DS" ] ; then
                unzip -qo $CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE -d $WORKING_DIRECTORY/patch/tmp
	else
		tar xvf $CLIENT_PATCH_FULL_PATH/$CLIENT_PATCH_PACKAGE -C $WORKING_DIRECTORY/patch/tmp
	fi


	if [ -f $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/CompressionGameData/version.txt ];then
            if [ "$GAME_TYPE" == "LA" ] || [ "$GAME_TYPE" == "AK" ] || [ "$GAME_TYPE" == "M11" ] || [ "$GAME_TYPE" == "M12" ] || [ "$GAME_TYPE" == "UG1" ] || [ "$GAME_TYPE" == "G1" ] || [ "$GAME_TYPE" == "FN" ] || [ "$GAME_TYPE" == "AR" ] || [ "$GAME_TYPE" == "DJ" ] || [ "$GAME_TYPE" == "GD" ] || [ "$GAME_TYPE" == "FF" ] || [ "$GAME_TYPE" == "G2" ] ; then
                cp -axfv $WORKING_DIRECTORY/patch/tmp/. $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/
            else
		cp -axfv $WORKING_DIRECTORY/patch/tmp/20*/. $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/20*/
            fi
	else
		cp -axfv $WORKING_DIRECTORY/patch/tmp/* $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/
                if [ "$GAME_TYPE" != "M2" ] ; then
		    mkdir $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/CompressionGameData/
		    (cd $PATCH_TARGET_CLIENT_DIR-$PATCH_TARGET/;ls|grep 20 | tr -d '\n' > CompressionGameData/version.txt)
                fi
	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

   # Version control header files differences between previous version and this version
   if [ "$GAME_TYPE" == "DJ" ] || [ "$GAME_TYPE" == "GD" ] || [ "$GAME_TYPE" == "FF" ] || [ "$GAME_TYPE" == "AR" ] ;then
	mkdir -p $HOME/www/versioncontrol/
	VERSION_CONTROL_DIFF_FILE="$HOME/www/versioncontrol/$(awk -F/ '{print $NF}' <<< "$ARG3").php"
	cat $HOME/bin/versioncontrol.php > "$VERSION_CONTROL_DIFF_FILE"
	# Server-side
	if [ -e $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/S_VersionDef.h ] ; then
	    if [ -e $LOCAL_PATCH_DIR/S_VersionDef.h-previous ] ; then
		echo "Server-side:" >> "$VERSION_CONTROL_DIFF_FILE"
		diff -u $LOCAL_PATCH_DIR/S_VersionDef.h-previous $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/S_VersionDef.h \
		| grep "^[+-]" | tee -a "$VERSION_CONTROL_DIFF_FILE" | grep -q "^[+-]" \
		|| echo "There is no difference between previous and this version." | tee -a "$VERSION_CONTROL_DIFF_FILE"
		cp -af $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/S_VersionDef.h $LOCAL_PATCH_DIR/S_VersionDef.h-previous
	    else
		cp -a $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/S_VersionDef.h $LOCAL_PATCH_DIR/S_VersionDef.h-previous
	    fi
	fi
	# Client-side
        if [ -e $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/C_VersionDef.h ] ; then
            if [ -e $LOCAL_PATCH_DIR/C_VersionDef.h-previous ] ; then
		echo -e "\n\nClient-side:" >> "$VERSION_CONTROL_DIFF_FILE"
                diff -u $LOCAL_PATCH_DIR/C_VersionDef.h-previous $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/C_VersionDef.h \
                | grep "^[+-]" | tee -a "$VERSION_CONTROL_DIFF_FILE" | grep -q "^[+-]" \
		|| echo "There is no difference between previous and this version." | tee -a "$VERSION_CONTROL_DIFF_FILE"
                cp -af $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/C_VersionDef.h $LOCAL_PATCH_DIR/C_VersionDef.h-previous
	    else
		cp -a $LOCAL_PATCH_DIR/$(awk -F/ '{print $NF}' <<< "$ARG3")/C_VersionDef.h $LOCAL_PATCH_DIR/C_VersionDef.h-previous
            fi
        fi
	[ "$(wc -l < "$VERSION_CONTROL_DIFF_FILE")" -lt "14" ] && rm -f "$VERSION_CONTROL_DIFF_FILE"
	true
   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/servers$(get_world_num $PATCH_TARGET)/MissionServer$(get_world_num $PATCH_TARGET)/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/servers$(get_world_num $PATCH_TARGET)/MissionServer$(get_world_num $PATCH_TARGET)/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/servers$(get_world_num $PATCH_TARGET)/MissionServer$(get_world_num $PATCH_TARGET)/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/servers$(get_world_num $PATCH_TARGET)/MissionServer$(get_world_num $PATCH_TARGET)/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 [ "$GAME_TYPE" == "AK" ] || [ "$GAME_TYPE" == "M11" ] ; then
   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
   fi

   # Parser INI to DB
   if [ "$GAME_TYPE" == "FN" ]; then
	~/bin/update_item_itemmall_fn_v2_tw
	~/bin/update_item_itemmall_fn_v2_others
	~/bin/update_node_fn_v2
        ~/bin/update_title_fn
        ~/bin/update_achievement_fn
        ~/bin/update_mission_fn
        ~/bin/update_class_fn
        ~/bin/update_localize_info maintenance
   elif [ "$GAME_TYPE" == "AR" ]; then
        ~/bin/update_item_itemmall_ar_v3_tw
        ~/bin/update_item_itemmall_ar_v3_others
        ~/bin/update_node_ar_v2
        ~/bin/update_title_ar
        ~/bin/update_achievement_ar
        ~/bin/update_mission_ar
        ~/bin/update_class_ar
        ~/bin/update_localize_info maintenance
   elif [ "$GAME_TYPE" == "DJ" ]; then
   #     ~/bin/update_item_itemmall_djglobal_v1_tw
   #     ~/bin/update_item_itemmall_djglobal_v2_tw
        ~/bin/update_item_itemmall_djglobal_v3_tw
        ~/bin/update_item_itemmall_djglobal_v1_others
        ~/bin/update_node_djglobal
        ~/bin/update_title_djglobal
        ~/bin/update_achievement_djglobal
        ~/bin/update_mission_djglobal
   #     ~/bin/update_class_djglobal
   #     ~/bin/update_localize_info maintenance
	~/bin/update_elftablet_combo_djglobal
   elif [ "$GAME_TYPE" == "GD" ]; then
        ~/bin/update_item_itemmall_gdglobal_v3_tw
        ~/bin/update_item_itemmall_gdglobal_v1_others
        ~/bin/update_node_gdglobal
        ~/bin/update_title_gdglobal
        ~/bin/update_achievement_gdglobal
        ~/bin/update_mission_gdglobal
        ~/bin/update_class_gdglobal
        ~/bin/update_localize_info_gdglobal maintenance
   elif [ "$GAME_TYPE" == "FF" ]; then
        ~/bin/update_item_itemmall_ffglobal_v3_tw
        ~/bin/update_item_itemmall_ffglobal_v1_others
        ~/bin/update_node_ffglobal
        ~/bin/update_title_ffglobal
        ~/bin/update_achievement_ffglobal_v2
        ~/bin/update_mission_ffglobal
	    ~/bin/update_card_ffglobal_v2
    	~/bin/update_partner_ffglobal
        #~/bin/update_localize_info_ffglobal maintenance
   fi

   output_filename="/tmp/test_patch_monitor.log"
   echo "測試機版本更新完成 可以測試囉!\n$ARG3\nServer: $SERVER_PATCH_PACKAGE\nClient: $CLIENT_PATCH_PACKAGE" > $output_filename
   send_messages_with_pic INFO test_patch  "測試機版本更新"

   # 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
   #SKServer stop all
   #SKServer start all
   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
}

item2db () { # Convert the translated item name to the database
   SQL_TO_RECREATE_POWERUPITEM="CREATE TABLE powerupitem (item_id integer, note text, itemname text);COPY powerupitem (item_id,itemname) from STDIN with csv;
				GRANT SELECT on powerupitem to public;"
   cd "$TRANSLATED_INI_UPLOAD_DIR"
   if [ "$GAME_TYPE" == "LH" ] ; then
	( sed -n '3,$p' T_Item.ini ; sed -n '3,$p' T_ItemMall.ini ) | grep "^[0-9]\+|.*"|awk -F\| '{print $1" ,"$2}'|\
	sed 's/\([^,]\+,[^,]\+\),\([^,]\+\)/\1\2/g;s/\x27//g;s/\"//g'|awk -F, '{print $1","$2}'|LC_ALL=C cut -c 1-96 | sort | uniq | tr -d '\r' > /tmp/powerupitem.sql
   elif [ "$GAME_TYPE" == "AK" ] ; then
	cat $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_item.ini $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/s_itemmall.ini | egrep '^[0-9].*' | awk -F"|" '{print $1","$6","$7}' | grep '^[0-9]\{5\},' | egrep -v '^6100[1-7],' > /tmp/powerupitem_tw.csv
	cat $TRANSLATED_INI_UPLOAD_DIR/t_item.ini $TRANSLATED_INI_UPLOAD_DIR/t_itemmall.ini | egrep ^[0-9].* | awk -F"|" '{print $1","$2}' | sed 's/, /,/' | grep '^[0-9]\{5\},' | egrep -v '^6100[1-7],' > /tmp/powerupitem_kr.csv
	scp /tmp/powerupitem_tw.csv /tmp/powerupitem_kr.csv ctrl:/tmp
	ssh ctrl "psql -U postgres WebTool -c \"delete from powerupitem where item_id not in (61001,61002,61003,61004,61005,61006,61007)\""
	ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem (item_id,itemname,item_type_id) from '/tmp/powerupitem_tw.csv' csv\""
	ssh ctrl "psql -U postgres WebTool -c \"create table powerupitem_kr_temp (item_id integer, item_name text)\""
	ssh ctrl "psql -U postgres WebTool -c \"copy powerupitem_kr_temp from '/tmp/powerupitem_kr.csv' csv\""
	ssh ctrl "psql -U postgres WebTool -c \"update powerupitem set itemname_kr = powerupitem_kr_temp.item_name from powerupitem_kr_temp where powerupitem.item_id = powerupitem_kr_temp.item_id\""
	ssh ctrl "psql -U postgres WebTool -c \"drop table powerupitem_kr_temp\""

   else
        if [ "$COUNTRY_CODE" == "HK" ] || [ "$COUNTRY_CODE" == "TW" ]; then
                if [ "$GAME_TYPE" == "FF" ] || [ "$GAME_TYPE" == "FN" ] || [ "$GAME_TYPE" == "AR" ]; then
                    grep -h "^[0-9.]\+|" $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/S_Item.ini $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/S_ItemMall.ini \
                    | awk -F"|" '{print $1","$8}' | sed 's/\.0,/,/g' > /tmp/powerupitem.sql
                else
                    grep -h "^[0-9.]\+|" $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/S_Item.ini $WORKING_DIRECTORY/common-$SOURCE_OF_SYNC_TO_LIVE/Data/db/S_ItemMall.ini \
                    | awk -F"|" '{print $1","$10}' | sed 's/\.0,/,/g' > /tmp/powerupitem.sql
                fi
        else
	    sed -n '3,$p' T_Item.ini T_ItemMall.ini|grep "^[0-9][0-9][0-9][0-9][0-9]|*"|awk -F\| '{print $1" ,"$2}'|\
	    sed 's/\([^,]\+,[^,]\+\),\([^,]\+\)/\1\2/g;s/\x27//g;s/\"//g'|awk -F, '{print $1","$2}'|LC_ALL=C cut -c 1-96 | sort | uniq | tr -d '\r' > /tmp/powerupitem.sql
        fi
   fi

   # Stop the LIVEDBbackup and pg_dump to prevent table lock
   killall LIVEDBbackup 2> /dev/null ; killall pg_dump 2> /dev/null

   for DATABASE in $ACCOUNT_DB_NAME $MEMBER_DB_NAME $GAME_DB_NAME"1" log_search WebTool ; do
        if check_db_exist $DATABASE ; then
                echo "$DATABASE(on TEST):" | colorize yellow
		psql -q -d $DATABASE -c "DROP TABLE powerupitem;"
                cat /tmp/powerupitem.sql | psql -d $DATABASE -c "$SQL_TO_RECREATE_POWERUPITEM" \
                && echo "$DATABASE(on TEST) OK" | colorize green \
                || echo "$DATABASE(on TEST) FAILED" | colorize red
		echo
        fi
   done

   for DATABASE in $ACCOUNT_DB_NAME $MEMBER_DB_NAME log_search WebTool ; do
        echo "$DATABASE(on LIVE):" | colorize yellow
	PGPASSWORD="$LIVE_SERVER_DB_PASSWORD" psql -q -h accountdb -d $DATABASE -c "DROP TABLE powerupitem;"
        cat /tmp/powerupitem.sql | PGPASSWORD="$LIVE_SERVER_DB_PASSWORD" psql -h accountdb -d $DATABASE -c "$SQL_TO_RECREATE_POWERUPITEM" \
        && echo "$DATABASE(on LIVE) OK" | colorize green \
        || echo "$DATABASE(on LIVE) FAILED(Maybe the database doesn't exist on LIVE server)" | colorize red
	echo
   done

   for set in $SET_NUMBER_LIST ; do
        echo "$GAME_DB_NAME$set(on LIVE):" | colorize yellow
	PGPASSWORD="$LIVE_SERVER_DB_PASSWORD" psql -q -h gamedb$set -d $GAME_DB_NAME$set -c "DROP TABLE powerupitem;"
        cat /tmp/powerupitem.sql | PGPASSWORD="$LIVE_SERVER_DB_PASSWORD" psql -h gamedb$set -d $GAME_DB_NAME$set -c "$SQL_TO_RECREATE_POWERUPITEM" \
        && echo "$GAME_DB_NAME$set(on LIVE) OK" | colorize green \
        || echo "$GAME_DB_NAME$set(on LIVE) FAILED(Maybe the database doesn't exist)" | colorize red
	echo
   done
}

localize2db () { # FIXME(DO NOT USE)

   echo "DROP TABLE localize2db;" > ~/localize2db.sql
   echo "create table localize2db ( id integer, name text, type text , CONSTRAINT localize2db_pkey PRIMARY KEY(id,type));" >> ~/localize2db.sql
   echo "COPY localize2db (id, name, type) FROM stdin;" >> ~/localize2db.sql
   for LOCALIZE_TYPE in $LOCALIZE2DB_TRANSLATIONS ;do
	grep -h "^[0-9]\+[^0-9]" $TRANSLATED_INI_UPLOAD_DIR/T_$LOCALIZE_TYPE.ini \
	| grep -v "^[0-9]\+|[0-9]\+|" | sed "s/^/$LOCALIZE_TYPE|/g"
   done | awk -F\| '{print $2"\t"$3"\t"$1}' >> ~/localize2db.sql
   echo -e "\\.\n" >> ~/localize2db.sql

   ssh test cat ~/localize2db.sql | member_db

#   for LOCALIZE_TYPE in Title Mission Node Spell Item ItemMall;do


#   sendscript alldb <<< "source ~/.gamerc;game_db <<< '\q' 2> /dev/null && game_db <<< '\q'"
#   create table localize2db ( id integer, name text, type text , CONSTRAINT localize2db_pkey PRIMARY KEY(id,type));

}

dbbackup () { # Backup databases
   DBbackup $ACCOUNT_DB_NAME
   DBbackup $MEMBER_DB_NAME
   if [ "$ENABLE_SOCIETY" == "1" ]; then
        DBbackup $SOCIETY_DB_NAME
   fi

   for world in $(cat ~/bin/worlds.test) ; do
	DBbackup $GAME_DB_NAME$(get_world_num $world)
   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 <<< $*

