NEW_CDN_client_rollback () { # Maintenance -> rollback client to previous version
    SYNC2LIVE_DIRECTORY="$HOME/www/${GAME_TYPE}-TEST_SYNCTOLIVE"
    CHECK_FILE="setup.txt"

    rsync -av --delete --progress CTRL:~/www/CDN/${GAME_TYPE}-LIVE_previous_version/NEWSYSTEM/ ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/

    OLD_NFSExtension=$(cat ${SYNC2LIVE_DIRECTORY}/${CHECK_FILE} | grep -E -a 'NFSExtension' | sed 's/NFSExtension=//')
    echo "Previous NFSExtension: ${OLD_NFSExtension}"

    YEAR=$(date +"%y")
    # Check Cross New Year or not ( 9999 times quota / year )
    if eval [[ ${OLD_NFSExtension} == "\.${YEAR}*" ]]; then
        OLD_NFSEx_NUM=$(echo ${OLD_NFSExtension} | sed "s/\.//;s/^${YEAR}0*//")
        echo "OLD_NFSEx_NUM: ${OLD_NFSEx_NUM}"
        let NEW_NFSEx_NUM=${OLD_NFSEx_NUM}+2
        NEW_NFSExtension=$(printf ".${YEAR}%04d" ${NEW_NFSEx_NUM})
    else
        NEW_NFSExtension=".${YEAR}0001"
    fi

    sed -i "s/NFSExtension=${OLD_NFSExtension}/NFSExtension=${NEW_NFSExtension}/" ${SYNC2LIVE_DIRECTORY}/${CHECK_FILE}
    echo "New NFSExtension: ${NEW_NFSExtension}"

    cd ${SYNC2LIVE_DIRECTORY}
    mv FileList.txt${OLD_NFSExtension} FileList.txt${NEW_NFSExtension}
    mv FileListPC.txt${OLD_NFSExtension} FileListPC.txt${NEW_NFSExtension}
    if [ "$GAME_TYPE" == "M12" ]; then
        for translate_file in $(ls GameDataTranslateFileList_*.txt${OLD_NFSExtension}); do
            empty_translate_file=$(echo ${translate_file} | sed "s/${OLD_NFSExtension}//")
            mv ${translate_file} ${empty_translate_file}
            mv ${empty_translate_file} ${empty_translate_file}${NEW_NFSExtension}
        done

        mv ImageFileList.txt${OLD_NFSExtension} ImageFileList.txt${NEW_NFSExtension}
    else
        mv GameDataTranslateFileList.txt${OLD_NFSExtension} GameDataTranslateFileList.txt${NEW_NFSExtension}
    fi
    find Android -type f -print0 | while read -d $'\0' f; do mv -- "$f" "${f%${OLD_NFSExtension}}${NEW_NFSExtension}"; done
}

NEW_CDN_prepatch_sync () { # Maintenance -> sync client or translate data to prepatch directory and flush CDN ( New Patch System: CLIENT (nobackup) / TRANSLATE (nobackup) / SETUP (nobackup) / NOTICE (nobackup) / MAINTENANCE (nobackup) / FORCESYNC (nobackup) )
    [ "$ARG2" == "" ] && exec echo "Usage: $0 NEW_CDN_prepatch_sync <CLIENT or TRANSLATE or SETUP or FORCESYNC>"

    #CHECK_TRANSLATE=$($HOME/bin/check_/translate_file_count_ret)
    #if [ "${CHECK_TRANSLATE}" == "0" ]; then
    #    exec automatic_send_messages_by_thread_tag ERROR check_translate_file_count "翻譯檔清單 檔案數目異常 請確認" "translate_check" minute 10
    #fi

    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    CDN_DIFF_FILE="$HOME/patch/cdn_diff_new.txt.$DATETIME"
    CDN_DIFF_FILE_TOTAL_COUNT_FILE="$HOME/patch/cdn_diff_count_new.$DATETIME"
    RSYNC_ERROR_LOG="/tmp/rsync_cdn_prepatch_sync_monitor.log"
    MACHINE_HOSTNAME="$(echo $HOST_NAME)"

    [ -f "${RSYNC_ERROR_LOG}" ] && rm -rf ${RSYNC_ERROR_LOG}

    if [ "$MACHINE_HOSTNAME" == "TEST" ]; then
        rm -rf /tmp/setup.txt.old
        cp -arf ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/setup.txt /tmp/setup.txt.old
    elif [ "$MACHINE_HOSTNAME" == "CTRL" ]; then
        rm -rf /tmp/setup.txt.old
        cp -arf ~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM/setup.txt /tmp/setup.txt.old
    fi

    PROCEDURE_NAME=$(psql -U postgres Tools -c "COPY (SELECT procedure_name FROM web_maintenance_procedure_mapping WHERE sub_command_name = '$ARG2') TO STDOUT;")

    if [ "$MACHINE_HOSTNAME" == "TEST" ]; then
        if [ "$ARG2" == "CLIENT" ]; then
            C_PART="全部"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            rename_client_extension
        elif [ "$ARG2" == "TRANSLATE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="翻譯 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                rename_translate_extension
            else
                C_PART="翻譯 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                rename_translate_extension $ARG3
            fi
        elif [ "$ARG2" == "SETUP" ]; then
            C_PART="setup.txt"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            norename_setup_update
        elif [ "$ARG2" == "NOTICE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="遊戲內公告 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                norename_notice_update
            else
                C_PART="遊戲內公告 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                norename_notice_update $ARG3
            fi
        elif [ "$ARG2" == "MAINTENANCE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="維護公告 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                norename_maintenance_update
            else
                C_PART="維護公告 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                norename_maintenance_update $ARG3
            fi
        elif [ "$ARG2" == "FORCESYNC" ]; then
            C_PART="全部 強制重新刷新"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            OLD_VERSION=$(grep -E -a NFSExtension /tmp/setup.txt.old | sed 's/NFSExtension=//')
            rm -rf ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/Android/version${OLD_VERSION}
            touch ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/Android/version${OLD_VERSION}
            rename_client_extension
        else
            exec echo "ERROR: Wrong parameter 2 (Only accept for CLIENT or TRANSLATE or SETUP or FORCESYNC)"
        fi

        if [ ! -f "/tmp/setup.txt.old" ]; then
            ssh CTRL "if [ ! -d "~/www/CDN/${GAME_TYPE}-LIVE_previous_version/" ]; then mkdir -p ~/www/CDN/${GAME_TYPE}-LIVE_previous_version/; fi"
            if test -z $CLIENT_PATCH_NFS_START; then
                DIRECTORY_NEWNUM=$(grep -E -a 'NFSExtension' ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/setup.txt | sed "s/NFSExtension=//;s/.//")
            else
                DIRECTORY_NEWNUM="${CLIENT_PATCH_NFS_START}"
            fi
        else
            rsync -i -avn --exclude="nfs" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/ CTRL:~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\/NEWSYSTEM\//g' > $CDN_DIFF_FILE
            [ "$(wc -l < $CDN_DIFF_FILE)" -eq "0" ] && exec echo "ERROR: No file to flush or cannot compare with prepatch directory, please try again."

            if [ "$ARG3" == "nobackup" -o "$ARG4" == "nobackup" ]; then
                echo "INFO: No Backup prepatch" | colorize red black
            else
                DIRNAME=$(ssh CTRL "readlink -f ~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM" | awk -F'/' '{print $NF}')
                ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE_previous_version/; unlink NEWSYSTEM; ln -s ../${GAME_TYPE}-LIVE/${DIRNAME} NEWSYSTEM"
            fi

            DIRECTORY_OLDNUM=$(grep -E -a 'NFSExtension' /tmp/setup.txt.old | sed "s/NFSExtension=//;s/.//")
            DIRECTORY_NEWNUM=$(grep -E -a 'NFSExtension' ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/setup.txt | sed "s/NFSExtension=//;s/.//")
        fi

        ssh CTRL "if [ ! -d \"${HOME}/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}\" ]; then mkdir -p ${HOME}/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}; fi"
        rsync -av --timeout=60 --delete --progress ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/ CTRL:~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}/ 2> ${RSYNC_ERROR_LOG}
        if [[ -s "${RSYNC_ERROR_LOG}" ]]; then
            automatic_send_messages_by_thread_tag ERROR rsync_cdn_prepatch_sync "Client Patch Rsync ${C_PART} 同步異常" "${PROCEDURE_NAME}" minute 10
        else
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client Patch Rsync ${C_PART} 同步正常" minute 10
        fi
        if [ "$ARG2" == "CLIENT" ] || [ "$ARG2" == "TRANSLATE" ] || [ "$ARG2" == "FORCESYNC" ]; then
            ssh CTRL "if [ ! -d \"${HOME}/www/CDN/${GAME_TYPE}-LIVE/patch\" ]; then mkdir -p ${HOME}/www/CDN/${GAME_TYPE}-LIVE/patch; fi"
            for FILE in ${CLIENT_PATCH_FILENAME_LISTS}; do
                FILE_CHECK=$(ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/; if [ -f \"${FILE}\" ]; then echo 1; else echo 0; fi")
                if [ "${FILE_CHECK}" -eq 0 ]; then
                    ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/; echo \"default=https://${CLIENT_PATCH_DOMAIN_NAME}/NEWSYSTEM.${DIRECTORY_NEWNUM}/\" > ${FILE}"
                fi
            done

            if test -z ${DIRECTORY_OLDNUM}; then
                ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/; ln -s NEWSYSTEM.${DIRECTORY_NEWNUM} NEWSYSTEM"
            else
                ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/; sed -i -r \"s|NEWSYSTEM.${DIRECTORY_OLDNUM}|NEWSYSTEM.${DIRECTORY_NEWNUM}|\" ${GAME_TYPE,,}_${COUNTRY_CODE,,}*.txt"
                ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/; sed -i -r \"s|NEWSYSTEM.${DIRECTORY_OLDNUM}|NEWSYSTEM.${DIRECTORY_NEWNUM}|\" ${GAME_TYPE,,}${COUNTRY_CODE,,}*.txt"
                ssh CTRL "cd ~/www/CDN/${GAME_TYPE}-LIVE/; unlink NEWSYSTEM; ln -s NEWSYSTEM.${DIRECTORY_NEWNUM} NEWSYSTEM"
            fi
        fi

        cat $HOME/patch/flush_all.txt > $HOME/patch/tmp1_new
        php $HOME/patch/flush.php $HOME/patch/tmp1_new
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步完成" minute 10

    elif [ "$MACHINE_HOSTNAME" == "CTRL" ]; then
        if [ "$ARG2" == "CLIENT" ]; then
            C_PART="全部"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            ssh TEST "rename_client_extension"
        elif [ "$ARG2" == "TRANSLATE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="翻譯 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "rename_translate_extension"
            else
                C_PART="翻譯 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "rename_translate_extension $ARG3"
            fi
        elif [ "$ARG2" == "SETUP" ]; then
            C_PART="setup.txt"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            ssh TEST "norename_setup_update"
        elif [ "$ARG2" == "NOTICE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="遊戲內公告 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "norename_notice_update"
            else
                C_PART="遊戲內公告 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "norename_notice_update $ARG3"
            fi
        elif [ "$ARG2" == "MAINTENANCE" ]; then
            if [ "$ARG3" == "nobackup" ]; then
                C_PART="維護公告 全語系"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "norename_maintenance_update"
            else
                C_PART="維護公告 $ARG3"
                automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

                ssh TEST "norename_maintenance_update $ARG3"
            fi
        elif [ "$ARG2" == "FORCESYNC" ]; then
            C_PART="全部 強制重新刷新"
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步開始" minute 10

            OLD_VERSION=$(ssh TEST "grep -E -a 'NFSExtension' /tmp/setup.txt.old | sed 's/NFSExtension=//'")
            ssh TEST "rm -rf ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/Android/version${OLD_VERSION}"
            ssh TEST "touch ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/Android/version${OLD_VERSION}"
            ssh TEST "rename_client_extension"
        else
            exec echo "ERROR: Wrong parameter 2 (Only accept for CLIENT or TRANSLATE or SETUP or FORCESYNC)"
        fi

        if [ ! -f "/tmp/setup.txt.old" ]; then
            if [ ! -d "~/www/CDN/${GAME_TYPE}-LIVE_previous_version/" ]; then mkdir -p ~/www/CDN/${GAME_TYPE}-LIVE_previous_version/; fi
            if test -z $CLIENT_PATCH_NFS_START; then
                DIRECTORY_NEWNUM=$(ssh TEST "grep -E -a 'NFSExtension' ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/setup.txt | sed \"s/NFSExtension=//;s/.//\"")
            else
                DIRECTORY_NEWNUM="${CLIENT_PATCH_NFS_START}"
            fi
        else
            ssh TEST "rsync -i -avn --exclude=\"nfs\" --out-format=\"FILE:%n\" ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/ CTRL:~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM/ | grep -a \"^FILE:\" | grep -a -v \"/$\" | sed 's/^FILE:/\/NEWSYSTEM\//g' > $CDN_DIFF_FILE"
            ssh TEST "wc -l < $CDN_DIFF_FILE > $CDN_DIFF_FILE_TOTAL_COUNT_FILE"
            CDN_DIFF_FILE_TOTAL_COUNT=$(ssh TEST "cat $CDN_DIFF_FILE_TOTAL_COUNT_FILE")
            [ "$CDN_DIFF_FILE_TOTAL_COUNT" -eq "0" ] && exec echo "ERROR: No file to flush or cannot compare with prepatch directory, please try again."

            if [ "$ARG3" == "nobackup" -o "$ARG4" == "nobackup" ]; then
                echo "INFO: No Backup prepatch" | colorize red black
            else
                DIRNAME=$(readlink -f ~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM | awk -F'/' '{print $NF}')
                cd ~/www/CDN/${GAME_TYPE}-LIVE_previous_version/
                unlink NEWSYSTEM
                ln -s ../${GAME_TYPE}-LIVE/${DIRNAME} NEWSYSTEM
            fi

            DIRECTORY_OLDNUM=$(grep -E -a 'NFSExtension' /tmp/setup.txt.old | sed "s/NFSExtension=//;s/.//")
            DIRECTORY_NEWNUM=$(ssh TEST "grep -E -a 'NFSExtension' ~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/setup.txt | sed \"s/NFSExtension=//;s/.//\"")
        fi

        if [ ! -d "${HOME}/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}" ]; then mkdir -p ${HOME}/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}; fi
        rsync -av --timeout=60 --delete --progress TEST:~/www/${GAME_TYPE}-TEST_SYNCTOLIVE/ ~/www/CDN/${GAME_TYPE}-LIVE/NEWSYSTEM.${DIRECTORY_NEWNUM}/ 2> ${RSYNC_ERROR_LOG}
        if [[ -s "${RSYNC_ERROR_LOG}" ]]; then
            automatic_send_messages_by_thread_tag ERROR rsync_cdn_prepatch_sync "Client Patch Rsync ${C_PART} 同步異常" "${PROCEDURE_NAME}" minute 10
        else
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client Patch Rsync ${C_PART} 同步正常" minute 10
        fi
        if [ "$ARG2" == "CLIENT" ] || [ "$ARG2" == "TRANSLATE" ] || [ "$ARG2" == "FORCESYNC" ]; then
            if [ ! -d "${HOME}/www/CDN/${GAME_TYPE}-LIVE/patch" ]; then mkdir -p ${HOME}/www/CDN/${GAME_TYPE}-LIVE/patch; fi
            for FILE in ${CLIENT_PATCH_FILENAME_LISTS}; do
                FILE_CHECK=$(
                    cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/
                    if [ -f "${FILE}" ]; then echo 1; else echo 0; fi
                )
                if [ "${FILE_CHECK}" -eq 0 ]; then
                    cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/
                    echo "default=https://${CLIENT_PATCH_DOMAIN_NAME}/NEWSYSTEM.${DIRECTORY_NEWNUM}/" > ${FILE}
                fi
            done

            if test -z ${DIRECTORY_OLDNUM}; then
                cd ~/www/CDN/${GAME_TYPE}-LIVE/
                ln -s NEWSYSTEM.${DIRECTORY_NEWNUM} NEWSYSTEM
            else
                cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/
                sed -i -r "s|NEWSYSTEM.${DIRECTORY_OLDNUM}|NEWSYSTEM.${DIRECTORY_NEWNUM}|" ${GAME_TYPE,,}_${COUNTRY_CODE,,}*.txt
                cd ~/www/CDN/${GAME_TYPE}-LIVE/patch/
                sed -i -r "s|NEWSYSTEM.${DIRECTORY_OLDNUM}|NEWSYSTEM.${DIRECTORY_NEWNUM}|" ${GAME_TYPE,,}${COUNTRY_CODE,,}*.txt
                cd ~/www/CDN/${GAME_TYPE}-LIVE/
                unlink NEWSYSTEM
                ln -s NEWSYSTEM.${DIRECTORY_NEWNUM} NEWSYSTEM
            fi
        fi

        ssh TEST "cat $HOME/patch/flush_all.txt > ~/patch/tmp1_new"
        ssh TEST "cd $HOME/patch; php ~/patch/flush.php ~/patch/tmp1_new"
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "Client ${C_PART} 同步完成" minute 10       
    fi
}

H5_CDN_prepatch_sync () { # Maintenance -> sync h5 data to prepatch directory and flush CDN
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    CDN_DIFF_FILE="$HOME/patch/h5_diff_new.txt.$DATETIME"
    CDN_DIFF_FILE_TOTAL_COUNT_FILE="$HOME/patch/h5_diff_count_new.$DATETIME"
    RSYNC_ERROR_LOG="/tmp/rsync_h5_prepatch_sync_monitor.log"
    MACHINE_HOSTNAME="$(echo $HOST_NAME)"

    [ -f "${RSYNC_ERROR_LOG}" ] && rm -rf ${RSYNC_ERROR_LOG}

    PROCEDURE_NAME="h5_cdn_sync"
    C_PART="H5 主程式"

    if [ "$MACHINE_HOSTNAME" == "TEST" ]; then
        ssh CTRL "if [ ! -d "~/www/H5_CDN/H5-LIVE/" ]; then mkdir -p ~/www/H5_CDN/H5-LIVE/; fi"
        ssh CTRL "if [ ! -d "~/www/H5_CDN/H5-LIVE_previous_version/" ]; then mkdir -p ~/www/H5_CDN/H5-LIVE_previous_version/; fi"
    
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步開始" minute 10   

        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ CTRL:~/www/H5_CDN/H5-LIVE/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE://g' > $CDN_DIFF_FILE
        [ "$(wc -l < $CDN_DIFF_FILE)" -eq "0" ] && exec echo "ERROR: No h5 file to flush or cannot compare with prepatch directory, please try again."

        if [ "$ARG2" == "nobackup" ]; then
            echo "INFO: No Backup h5 prepatch" | colorize red black
        else
            ssh CTRL "cd ~/www/H5_CDN/; rsync -av --timeout=60 --delete --progress H5-LIVE/ H5-LIVE_previous_version/"
        fi

        rsync -av --timeout=60 --delete --progress ~/www/H5-TEST/ CTRL:~/www/H5_CDN/H5-LIVE/ 2> ${RSYNC_ERROR_LOG}
        if [[ -s "${RSYNC_ERROR_LOG}" ]]; then
            automatic_send_messages_by_thread_tag ERROR rsync_cdn_prepatch_sync "${C_PART} 同步異常" "${PROCEDURE_NAME}" minute 10
        else
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步正常" minute 10
        fi

        cat $HOME/patch/flush_all.txt > $HOME/patch/tmp1_h5_new
        php $HOME/patch/flush_h5.php $HOME/patch/tmp1_h5_new
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步完成" minute 10

    elif [ "$MACHINE_HOSTNAME" == "CTRL" ]; then
        if [ ! -d "~/www/H5_CDN/H5-LIVE/" ]; then mkdir -p ~/www/H5_CDN/H5-LIVE/; fi
        if [ ! -d "~/www/H5_CDN/H5-LIVE_previous_version/" ]; then mkdir -p ~/www/H5_CDN/H5-LIVE_previous_version/; fi
    
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步開始" minute 10   

        ssh TEST "rsync -i -avn --out-format=\"FILE:%n\" ~/www/H5-TEST/ CTRL:~/www/H5_CDN/H5-LIVE/ | grep -a \"^FILE:\" | grep -a -v \"/$\" | sed 's/^FILE://g' > $CDN_DIFF_FILE"
        ssh TEST "wc -l < $CDN_DIFF_FILE > $CDN_DIFF_FILE_TOTAL_COUNT_FILE"
        CDN_DIFF_FILE_TOTAL_COUNT=$(ssh TEST "cat $CDN_DIFF_FILE_TOTAL_COUNT_FILE")
        [ "$CDN_DIFF_FILE_TOTAL_COUNT" -eq "0" ] && exec echo "ERROR: No h5 file to flush or cannot compare with prepatch directory, please try again."

        if [ "$ARG2" == "nobackup" ]; then
            echo "INFO: No Backup h5 prepatch" | colorize red black
        else
            ssh CTRL "cd ~/www/H5_CDN/; rsync -av --timeout=60 --delete --progress H5-LIVE/ H5-LIVE_previous_version/"
        fi

        rsync -av --timeout=60 --delete --progress TEST:~/www/H5-TEST/ ~/www/H5_CDN/H5-LIVE/ 2> ${RSYNC_ERROR_LOG}
        if [[ -s "${RSYNC_ERROR_LOG}" ]]; then
            automatic_send_messages_by_thread_tag ERROR rsync_cdn_prepatch_sync "${C_PART} 同步異常" "${PROCEDURE_NAME}" minute 10
        else
            automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步正常" minute 10
        fi

        ssh TEST "cat $HOME/patch/flush_all.txt > $HOME/patch/tmp1_h5_new"
        ssh TEST "cd $HOME/patch; php $HOME/patch/flush_h5.php $HOME/patch/tmp1_h5_new"
        automatic_send_chatbot_text_only_by_thread_tag "${PROCEDURE_NAME}" "${C_PART} 同步完成" minute 10      
    fi
}

### Game Server Status ###
android_status () { # Submit -> Check Status of GOOGLE-SUBMIT all servers
    ssh GOOGLE-SUBMIT "pl"
}

ios_status () { # Submit -> Check Status of APPLE-SUBMIT all servers
    ssh APPLE-SUBMIT "pl"
}

submit_status () { # Submit -> Check Status SUBMIT all servers
    ssh SUBMIT "pl"
}

data_status () { # Data -> Check Status DATA all servers
    ssh DATA "pl"
}

time1_status () { # Time1 -> Check Status TIME1 all servers
    ssh TIME1 "pl"
}

old_test_status () { # OldTest -> Check Status OLD_TEST all servers
    ssh OLD_TEST "pl"
}

media_status () { # Media -> Check Status MEDIA all servers
    ssh MEDIA "pl"
}

mapping_status () { # Mapping -> Check Status MAPPING all servers
    ssh MAPPING "pl"
}

### Game Server Start ###
android_start () { # Submit -> Start GOOGLE-SUBMIT all servers
    ssh GOOGLE-SUBMIT "SKServer start all"
}

ios_start () { # Submit -> Start APPLE-SUBMIT all servers
    ssh APPLE-SUBMIT "SKServer start all"
}

submit_start () { # Submit -> Start SUBMIT all servers
    ssh SUBMIT "SKServer start all"
}

data_start () { # Data -> Start DATA all servers
    ssh DATA "SKServer start all"
}

time1_start () { # Time1 -> Start TIME1 all servers
    ssh TIME1 "SKServer start all"
}

old_test_start () { # OldTest -> Start OLD_TEST all servers
    ssh OLD_TEST "SKServer start all"
}

media_start () { # Media -> Start MEDIA all servers
    ssh MEDIA "SKServer start all"
}

mapping_start () { # Mapping -> Start MAPPING all servers
    ssh MAPPING "SKServer start all"
}

### Game Server Stop ###
android_stop () { # Submit -> Stop GOOGLE-SUBMIT all servers
    ssh GOOGLE-SUBMIT "SKServer stop all"
}

ios_stop () { # Submit -> Stop APPLE-SUBMIT all servers
    ssh APPLE-SUBMIT "SKServer stop all"
}

submit_stop () { # Submit -> Stop SUBMIT all servers
    ssh SUBMIT "SKServer stop all"
}

data_stop () { # Data -> Stop DATA all servers
    ssh DATA "SKServer stop all"
}

time1_stop () { # Time1 -> Stop TIME1 all servers
    ssh TIME1 "SKServer stop all"
}

old_test_stop () { # OldTest -> Stop OLD_TEST all servers
    ssh OLD_TEST "SKServer stop all"
}

media_stop () { # Media -> Stop MEDIA all servers
    ssh MEDIA "SKServer stop all"
}

mapping_stop () { # Mapping -> Stop MAPPING all servers
    ssh MAPPING "SKServer stop all"
}

### Game Server ReStart ###
android_restart () { # Submit -> ReStart GOOGLE-SUBMIT all servers
    ssh GOOGLE-SUBMIT "SKServer stop all; SKServer start all"
}

ios_restart () { # Submit -> ReStart APPLE-SUBMIT all servers
    ssh APPLE-SUBMIT "SKServer stop all; SKServer start all"
}

submit_restart () { # Submit -> ReStart SUBMIT all servers
    ssh SUBMIT "SKServer stop all; SKServer start all"
}

data_restart () { # Data -> ReStart DATA all servers
    ssh DATA "SKServer stop all; SKServer start all"
}

time1_restart () { # Time1 -> ReStart TIME1 all servers
    ssh TIME1 "SKServer stop all; SKServer start all"
}

old_test_restart () { # OldTest -> ReStart OLD_TEST all servers
    ssh OLD_TEST "SKServer stop all; SKServer start all"
}

media_restart () { # Media -> ReStart MEDIA all servers
    ssh MEDIA "SKServer stop all; SKServer start all"
}

mapping_restart () { # Mapping -> ReStart MAPPING all servers
    ssh MAPPING "SKServer stop all; SKServer start all"
}

### Game Server DBbackup ###
android_dbbackup () { # Submit -> Backup GOOGLE-SUBMIT Database
    ssh GOOGLE-SUBMIT "TestCtrl dbbackup"
}

ios_dbbackup () { # Submit -> Backup APPLE-SUBMIT Database
    ssh APPLE-SUBMIT "TestCtrl dbbackup"
}

submit_dbbackup () { # Submit -> Backup SUBMIT Database
    ssh SUBMIT "TestCtrl dbbackup"
}

data_dbbackup () { # Data -> Backup DATA Database
    ssh DATA "TestCtrl dbbackup"
    #ssh DATA "DBbackup ${GAME_DB_NAME}${CROSS_ROUTER_SID_TEST}"
    #if [ "$ENABLE_SOCIETY" == "1" ]; then
    #    ssh DATA "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-TEST/db/db_society_alter"
    #    ssh DATA "cd common-TEST/db;perl db_society_alter :${GAME_TYPE}Society"
    #fi
}

time1_dbbackup () { # Time1 -> Backup TIME1 Database
    ssh TIME1 "TestCtrl dbbackup"
}

old_test_dbbackup () { # OldTest -> Backup OLD_TEST Database
    ssh OLD_TEST "TestCtrl dbbackup"
}

media_dbbackup () { # Media -> Backup MEDIA Database
    ssh MEDIA "TestCtrl dbbackup"
}

mapping_dbbackup () { # Mapping -> Backup MAPPING Database
    ssh MAPPING "TestCtrl dbbackup"
    #ssh MAPPING "DBbackup ${GAME_DB_NAME}${CROSS_ROUTER_SID_TEST}"
    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh MAPPING "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-TEST/db/db_society_alter"
        ssh MAPPING "cd common-TEST/db;perl db_society_alter :${GAME_TYPE}Society"
    fi
}

### Game Server Sync ###
android_sync () { # Submit -> Sync test to GOOGLE-SUBMIT (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/android" ] && mkdir -p $HOME/submit_sync/android
        cd $HOME/submit_sync/android/
        SERVER_DIFF_FILE="$HOME/submit_sync/android/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ GOOGLE-SUBMIT:~/common-GOOGLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to GOOGLE-SUBMIT"
        ssh GOOGLE-SUBMIT "rsync -av --progress ~/common-GOOGLE-SUBMIT/ ~/common-GOOGLE-SUBMIT_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. GOOGLE-SUBMIT:~/common-GOOGLE-SUBMIT/
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/android" ] && mkdir -p $HOME/submit_sync/android
        cd $HOME/submit_sync/android/
        CLIENT_DIFF_FILE="$HOME/submit_sync/android/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ GOOGLE-SUBMIT:~/www/${GAME_TYPE}-GOOGLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to GOOGLE-SUBMIT"
        ssh GOOGLE-SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-GOOGLE-SUBMIT/ ~/www/${GAME_TYPE}-GOOGLE-SUBMIT_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ GOOGLE-SUBMIT:~/www/${GAME_TYPE}-GOOGLE-SUBMIT/
    # Both Server and Client
    else
        [ ! -d "$HOME/submit_sync/android" ] && mkdir -p $HOME/submit_sync/android
        cd $HOME/submit_sync/android/
        SERVER_DIFF_FILE="$HOME/submit_sync/android/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ GOOGLE-SUBMIT:~/common-GOOGLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to GOOGLE-SUBMIT"
        else
            ssh GOOGLE-SUBMIT "rsync -av --progress ~/common-GOOGLE-SUBMIT/ ~/common-GOOGLE-SUBMIT_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. GOOGLE-SUBMIT:~/common-GOOGLE-SUBMIT/
        fi

        cd $HOME/submit_sync/android/
        CLIENT_DIFF_FILE="$HOME/submit_sync/android/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ GOOGLE-SUBMIT:~/www/${GAME_TYPE}-GOOGLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to GOOGLE-SUBMIT"
        else
            ssh GOOGLE-SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-GOOGLE-SUBMIT/ ~/www/${GAME_TYPE}-GOOGLE-SUBMIT_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ GOOGLE-SUBMIT:~/www/${GAME_TYPE}-GOOGLE-SUBMIT/
        fi
    fi
}

ios_sync () { # Submit -> Sync test to APPLE-SUBMIT (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/ios" ] && mkdir -p $HOME/submit_sync/ios
        cd $HOME/submit_sync/ios/
        SERVER_DIFF_FILE="$HOME/submit_sync/ios/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ APPLE-SUBMIT:~/common-APPLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to APPLE-SUBMIT"
        ssh APPLE-SUBMIT "rsync -av --progress ~/common-APPLE-SUBMIT/ ~/common-APPLE-SUBMIT_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. APPLE-SUBMIT:~/common-APPLE-SUBMIT/
    # Client only
    elif grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/ios" ] && mkdir -p $HOME/submit_sync/ios
        cd $HOME/submit_sync/ios/
        CLIENT_DIFF_FILE="$HOME/submit_sync/ios/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ APPLE-SUBMIT:~/www/${GAME_TYPE}-APPLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to APPLE-SUBMIT"
        ssh APPLE-SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-APPLE-SUBMIT/ ~/www/${GAME_TYPE}-APPLE-SUBMIT_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ APPLE-SUBMIT:~/www/${GAME_TYPE}-APPLE-SUBMIT/
    else
        # Both Server and Client
        [ ! -d "$HOME/submit_sync/ios" ] && mkdir -p $HOME/submit_sync/ios
        cd $HOME/submit_sync/ios/
        SERVER_DIFF_FILE="$HOME/submit_sync/ios/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ APPLE-SUBMIT:~/common-APPLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to APPLE-SUBMIT"
        else
            ssh APPLE-SUBMIT "rsync -av --progress ~/common-APPLE-SUBMIT/ ~/common-APPLE-SUBMIT_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. APPLE-SUBMIT:~/common-APPLE-SUBMIT/
        fi

        cd $HOME/submit_sync/ios/
        CLIENT_DIFF_FILE="$HOME/submit_sync/ios/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ APPLE-SUBMIT:~/www/${GAME_TYPE}-APPLE-SUBMIT/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to APPLE-SUBMIT"
        else
            ssh APPLE-SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-APPLE-SUBMIT/ ~/www/${GAME_TYPE}-APPLE-SUBMIT_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ APPLE-SUBMIT:~/www/${GAME_TYPE}-APPLE-SUBMIT/
        fi
    fi
}

submit_sync () { # Submit -> Sync test to SUBMIT (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/submit" ] && mkdir -p $HOME/submit_sync/submit
        cd $HOME/submit_sync/submit/
        SERVER_DIFF_FILE="$HOME/submit_sync/submit/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ SUBMIT:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to SUBMIT"
        ssh SUBMIT "rsync -av --progress ~/common-TEST/ ~/common-SUBMIT_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. SUBMIT:~/common-TEST/
        ssh SUBMIT "sed -i 's/AllGM=1/AllGM=0/' ~/common-TEST/bin/config.ini"
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/submit" ] && mkdir -p $HOME/submit_sync/submit
        cd $HOME/submit_sync/submit/
        CLIENT_DIFF_FILE="$HOME/submit_sync/submit/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ SUBMIT:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to SUBMIT"
        ssh SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-SUBMIT_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ SUBMIT:~/www/${GAME_TYPE}-TEST/
    # H5 only
    elif grep -a -qi "h5" <<< "$ALLARGS"; then
        [ ! -d "$HOME/submit_sync/submit" ] && mkdir -p $HOME/submit_sync/submit
        cd $HOME/submit_sync/submit/
        H5_DIFF_FILE="$HOME/submit_sync/submit/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ SUBMIT:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        [ "$(wc -l < $H5_DIFF_FILE)" == "0" ] && exec echo "ERROR: No h5 file need to sync to SUBMIT"
        ssh SUBMIT "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-SUBMIT_previous/"
        rsync -av --progress ~/www/H5-TEST/ SUBMIT:~/www/H5-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/submit_sync/submit" ] && mkdir -p $HOME/submit_sync/submit
        cd $HOME/submit_sync/submit/
        SERVER_DIFF_FILE="$HOME/submit_sync/submit/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ SUBMIT:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to SUBMIT"
        else
            ssh SUBMIT "rsync -av --progress ~/common-TEST/ ~/common-SUBMIT_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. SUBMIT:~/common-TEST/
            ssh SUBMIT "sed -i 's/AllGM=1/AllGM=0/' ~/common-TEST/bin/config.ini"
        fi

        cd $HOME/submit_sync/submit/
        CLIENT_DIFF_FILE="$HOME/submit_sync/submit/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ SUBMIT:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to SUBMIT"
        else
            ssh SUBMIT "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-SUBMIT_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ SUBMIT:~/www/${GAME_TYPE}-TEST/
        fi

        cd $HOME/submit_sync/submit/
        H5_DIFF_FILE="$HOME/submit_sync/submit/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ SUBMIT:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        if [ "$(wc -l < $H5_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No h5 file need to sync to SUBMIT"
        else
            ssh SUBMIT "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-SUBMIT_previous/"
            rsync -av --progress ~/www/H5-TEST/ SUBMIT:~/www/H5-TEST/
        fi
    fi
}

merge_sync () { # Merge -> Sync test to MERGE (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/merge_sync/merge" ] && mkdir -p $HOME/merge_sync/merge
        cd $HOME/merge_sync/merge/
        SERVER_DIFF_FILE="$HOME/merge_sync/merge/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ ASIA-MERGE:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to MERGE"
        ssh ASIA-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. ASIA-MERGE:~/common-TEST/
        ssh US-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. US-MERGE:~/common-TEST/
        ssh EUROPE-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. EUROPE-MERGE:~/common-TEST/
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/merge_sync/merge" ] && mkdir -p $HOME/merge_sync/merge
        cd $HOME/merge_sync/merge/
        CLIENT_DIFF_FILE="$HOME/merge_sync/merge/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ ASIA-MERGE:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to MERGE"
        ssh ASIA-MERGE "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-TEST_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ ASIA-MERGE:~/www/${GAME_TYPE}-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/merge_sync/merge" ] && mkdir -p $HOME/merge_sync/merge
        cd $HOME/merge_sync/merge/
        SERVER_DIFF_FILE="$HOME/merge_sync/merge/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ ASIA-MERGE:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to MERGE"
        else
            ssh ASIA-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. ASIA-MERGE:~/common-TEST/
            ssh US-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. US-MERGE:~/common-TEST/
            ssh EUROPE-MERGE "rsync -av --progress ~/common-TEST/ ~/common-TEST_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. EUROPE-MERGE:~/common-TEST/
        fi

        cd $HOME/merge_sync/merge/
        CLIENT_DIFF_FILE="$HOME/merge_sync/merge/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ ASIA-MERGE:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to MERGE"
        else
            ssh ASIA-MERGE "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-TEST_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ ASIA-MERGE:~/www/${GAME_TYPE}-TEST/
        fi
    fi
}

data_sync () { # Data -> Sync test to DATA (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/data_sync/data" ] && mkdir -p $HOME/data_sync/data
        cd $HOME/data_sync/data/
        SERVER_DIFF_FILE="$HOME/data_sync/data/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ DATA:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to DATA"
        ssh DATA "rsync -av --progress ~/common-TEST/ ~/common-DATA_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. DATA:~/common-TEST/
        #ssh DATA "sed -i 's/AllGM=1/AllGM=0/' ~/common-DATA/bin/config.ini"
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/data_sync/data" ] && mkdir -p $HOME/data_sync/data
        cd $HOME/data_sync/data/
        CLIENT_DIFF_FILE="$HOME/data_sync/data/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ DATA:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to DATA"
        ssh DATA "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-DATA_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ DATA:~/www/${GAME_TYPE}-TEST/
    # H5 only
    elif grep -a -qi "h5" <<< "$ALLARGS"; then
        [ ! -d "$HOME/data_sync/data" ] && mkdir -p $HOME/data_sync/data
        cd $HOME/data_sync/data/
        H5_DIFF_FILE="$HOME/data_sync/data/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ DATA:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        [ "$(wc -l < $H5_DIFF_FILE)" == "0" ] && exec echo "ERROR: No h5 file need to sync to DATA"
        ssh DATA "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-DATA_previous/"
        rsync -av --progress ~/www/H5-TEST/ DATA:~/www/H5-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/data_sync/data" ] && mkdir -p $HOME/data_sync/data
        cd $HOME/data_sync/data/
        SERVER_DIFF_FILE="$HOME/data_sync/data/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ DATA:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to DATA"
        else
            ssh DATA "rsync -av --progress ~/common-TEST/ ~/common-DATA_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. DATA:~/common-TEST/
            #ssh DATA "sed -i 's/AllGM=1/AllGM=0/' ~/common-TEST/bin/config.ini"
        fi

        cd $HOME/data_sync/data/
        CLIENT_DIFF_FILE="$HOME/data_sync/data/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ DATA:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to DATA"
        else
            ssh DATA "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-DATA_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ DATA:~/www/${GAME_TYPE}-TEST/
        fi

        cd $HOME/data_sync/data/
        H5_DIFF_FILE="$HOME/data_sync/data/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ DATA:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        if [ "$(wc -l < $H5_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No h5 file need to sync to DATA"
        else
            ssh DATA "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-DATA_previous/"
            rsync -av --progress ~/www/H5-TEST/ DATA:~/www/H5-TEST/
        fi
    fi
}

time1_sync () { # Time1 -> Sync test to TIME1 (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/time1_sync/time1" ] && mkdir -p $HOME/time1_sync/time1
        cd $HOME/time1_sync/time1/
        SERVER_DIFF_FILE="$HOME/time1_sync/time1/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ TIME1:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to TIME1"
        ssh TIME1 "rsync -av --progress ~/common-TEST/ ~/common-TIME1_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. TIME1:~/common-TEST/
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/time1_sync/time1" ] && mkdir -p $HOME/time1_sync/time1
        cd $HOME/time1_sync/time1/
        CLIENT_DIFF_FILE="$HOME/time1_sync/time1/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ TIME1:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to TIME1"
        ssh TIME1 "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-TIME1_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ TIME1:~/www/${GAME_TYPE}-TEST/
    # H5 only
    elif grep -a -qi "h5" <<< "$ALLARGS"; then
        [ ! -d "$HOME/time1_sync/time1" ] && mkdir -p $HOME/time1_sync/time1
        cd $HOME/time1_sync/time1/
        H5_DIFF_FILE="$HOME/time1_sync/time1/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ TIME1:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        [ "$(wc -l < $H5_DIFF_FILE)" == "0" ] && exec echo "ERROR: No h5 file need to sync to TIME1"
        ssh TIME1 "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-TIME1_previous/"
        rsync -av --progress ~/www/H5-TEST/ TIME1:~/www/H5-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/time1_sync/time1" ] && mkdir -p $HOME/time1_sync/time1
        cd $HOME/time1_sync/time1/
        SERVER_DIFF_FILE="$HOME/time1_sync/time1/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ TIME1:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to TIME1"
        else
            ssh TIME1 "rsync -av --progress ~/common-TEST/ ~/common-TIME1_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. TIME1:~/common-TEST/
        fi

        cd $HOME/time1_sync/time1/
        CLIENT_DIFF_FILE="$HOME/time1_sync/time1/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ TIME1:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to TIME1"
        else
            ssh TIME1 "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-TIME1_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ TIME1:~/www/${GAME_TYPE}-TEST/
        fi

        cd $HOME/time1_sync/time1/
        H5_DIFF_FILE="$HOME/time1_sync/time1/h5_diff.txt.$DATETIME"
        rsync -i -avn --out-format="FILE:%n" ~/www/H5-TEST/ TIME1:~/www/H5-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $H5_DIFF_FILE
        if [ "$(wc -l < $H5_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No h5 file need to sync to TIME1"
        else
            ssh TIME1 "rsync -av --progress ~/www/H5-TEST/ ~/www/H5-TIME1_previous/"
            rsync -av --progress ~/www/H5-TEST/ TIME1:~/www/H5-TEST/
        fi
    fi
}

old_test_sync () { # OldTest -> Sync test to OLD_TEST (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/old_test_sync/old_test" ] && mkdir -p $HOME/old_test_sync/old_test
        cd $HOME/old_test_sync/old_test/
        SERVER_DIFF_FILE="$HOME/old_test_sync/old_test/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ OLD_TEST:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to OLD_TEST"
        ssh OLD_TEST "rsync -av --progress ~/common-TEST/ ~/common-OLD_TEST_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. OLD_TEST:~/common-TEST/
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/old_test_sync/old_test" ] && mkdir -p $HOME/old_test_sync/old_test
        cd $HOME/old_test_sync/old_test/
        CLIENT_DIFF_FILE="$HOME/old_test_sync/old_test/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ OLD_TEST:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to OLD_TEST"
        ssh OLD_TEST "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-OLD_TEST_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ OLD_TEST:~/www/${GAME_TYPE}-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/old_test_sync/old_test" ] && mkdir -p $HOME/old_test_sync/old_test
        cd $HOME/old_test_sync/old_test/
        SERVER_DIFF_FILE="$HOME/old_test_sync/old_test/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ OLD_TEST:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to OLD_TEST"
        else
            ssh OLD_TEST "rsync -av --progress ~/common-TEST/ ~/common-OLD_TEST_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. OLD_TEST:~/common-TEST/
        fi

        cd $HOME/old_test_sync/old_test/
        CLIENT_DIFF_FILE="$HOME/old_test_sync/old_test/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ OLD_TEST:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to OLD_TEST"
        else
            ssh OLD_TEST "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-OLD_TEST_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ OLD_TEST:~/www/${GAME_TYPE}-TEST/
        fi
    fi
}

media_sync () { # Media -> Sync test to MEDIA (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/media_sync/media" ] && mkdir -p $HOME/media_sync/media
        cd $HOME/media_sync/media/
        SERVER_DIFF_FILE="$HOME/media_sync/media/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ MEDIA:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to MEDIA"
        ssh MEDIA "rsync -av --progress ~/common-TEST/ ~/common-MEDIA_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. MEDIA:~/common-TEST/
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/media_sync/media" ] && mkdir -p $HOME/media_sync/media
        cd $HOME/media_sync/media/
        CLIENT_DIFF_FILE="$HOME/media_sync/media/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ MEDIA:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to MEDIA"
        ssh MEDIA "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-MEDIA_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ MEDIA:~/www/${GAME_TYPE}-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/media_sync/media" ] && mkdir -p $HOME/media_sync/media
        cd $HOME/media_sync/media/
        SERVER_DIFF_FILE="$HOME/media_sync/media/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude --out-format="FILE:%n" ~/common-TEST/ MEDIA:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to MEDIA"
        else
            ssh MEDIA "rsync -av --progress ~/common-TEST/ ~/common-MEDIA_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude ~/common-TEST/. MEDIA:~/common-TEST/
        fi

        cd $HOME/media_sync/media/
        CLIENT_DIFF_FILE="$HOME/media_sync/media/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ MEDIA:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to MEDIA"
        else
            ssh MEDIA "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-MEDIA_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ MEDIA:~/www/${GAME_TYPE}-TEST/
        fi
    fi
}

mapping_sync () { # Mapping -> Sync test to MAPPING (argument: "server", "client")
    DATETIME="$(/bin/date +%Y%m%dT%H%M)"
    # Server only
    if grep -a -qi "server" <<< "$ALLARGS"; then
        [ ! -d "$HOME/mapping_sync/mapping" ] && mkdir -p $HOME/mapping_sync/mapping
        cd $HOME/mapping_sync/mapping/
        SERVER_DIFF_FILE="$HOME/mapping_sync/mapping/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ MAPPING:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ] && exec echo "ERROR: No server file need to sync to MAPPING"
        ssh MAPPING "rsync -av --progress ~/common-TEST/ ~/common-MAPPING_previous/"
        rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. MAPPING:~/common-TEST/
        #ssh MAPPING "sed -i 's/AllGM=1/AllGM=0/' ~/common-TEST/bin/config.ini"
    # Client only
    elif grep -a -qi "client" <<< "$ALLARGS"; then
        [ ! -d "$HOME/mapping_sync/mapping" ] && mkdir -p $HOME/mapping_sync/mapping
        cd $HOME/mapping_sync/mapping/
        CLIENT_DIFF_FILE="$HOME/mapping_sync/mapping/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ MAPPING:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ] && exec echo "ERROR: No client file need to sync to MAPPING"
        ssh MAPPING "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-MAPPING_previous/"
        rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ MAPPING:~/www/${GAME_TYPE}-TEST/
    else
        # Both Server and Client
        [ ! -d "$HOME/mapping_sync/mapping" ] && mkdir -p $HOME/mapping_sync/mapping
        cd $HOME/mapping_sync/mapping/
        SERVER_DIFF_FILE="$HOME/mapping_sync/mapping/server_diff.txt.$DATETIME"
        rsync -i -avn --exclude-from=$HOME/bin/rsync.exclude-submit --out-format="FILE:%n" ~/common-TEST/ MAPPING:~/common-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $SERVER_DIFF_FILE
        if [ "$(wc -l < $SERVER_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No server file need to sync to MAPPING"
        else
            ssh MAPPING "rsync -av --progress ~/common-TEST/ ~/common-MAPPING_previous/"
            rsync -av --progress --exclude-from=$HOME/bin/rsync.exclude-submit ~/common-TEST/. MAPPING:~/common-TEST/
            #ssh MAPPING "sed -i 's/AllGM=1/AllGM=0/' ~/common-TEST/bin/config.ini"
        fi

        cd $HOME/mapping_sync/mapping/
        CLIENT_DIFF_FILE="$HOME/mapping_sync/mapping/client_diff.txt.$DATETIME"
        rsync -i -avn --exclude="setup.txt" --out-format="FILE:%n" ~/www/${GAME_TYPE}-TEST/ MAPPING:~/www/${GAME_TYPE}-TEST/ | grep -a "^FILE:" | grep -a -v "/$" | sed 's/^FILE:/\//g' > $CLIENT_DIFF_FILE
        if [ "$(wc -l < $CLIENT_DIFF_FILE)" == "0" ]; then
            echo "ERROR: No client file need to sync to MAPPING"
        else
            ssh MAPPING "rsync -av --progress ~/www/${GAME_TYPE}-TEST/ ~/www/${GAME_TYPE}-MAPPING_previous/"
            rsync -av --progress --exclude="setup.txt" ~/www/${GAME_TYPE}-TEST/ MAPPING:~/www/${GAME_TYPE}-TEST/
        fi
    fi
}

### Sync Translate of Client ###
time1_sync_translate () { # Time1 -> Sync Translate to TIME1
    ALLARGS=$(echo $ALLARGS | sed 's/time1_sync_translate//;s/^ //')
    echo "ALLARGS => $ALLARGS" | colorize yellow black
    if [ -z "$ALLARGS" ]; then
        for multi_lang_directory in $(grep -E -a TRANSLATED_INI_UPLOAD_DIR_ ${HOME}/.gamerc | grep -a -v '#' | awk -F"=" '{print $2}'); do
            LCOUNTRY=$(echo ${multi_lang_directory} | sed 's/"//g' | awk -F"/" '{print $(NF-1)}' | awk -F"_" '{print $NF}')
            COUNTRY=$(echo ${LCOUNTRY} | tr '[:lower:]' '[:upper:]')

            TEST_TRANSLATE_DIRECTORY=$(echo ${multi_lang_directory} | sed 's/"//g')
            echo "LOOP MULTI => ${COUNTRY}" | colorize red green
            if [ -f "${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt" ]; then
                MD5_TEST_TRANSLATE_FILELIST=$(md5sum ${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt | awk -F" " '{print $1}')
                MD5_SYNCTOTIME1_TRANSLATE_FILELIST=$(ssh TIME1 "md5sum ~/www/${GAME_TYPE}-TEST/GameDataTranslateFileList_${LCOUNTRY}.txt" | awk -F" " '{print $1}')

                if [ "${MD5_TEST_TRANSLATE_FILELIST}" == "${MD5_SYNCTOTIME1_TRANSLATE_FILELIST}" ]; then
                    echo "ERROR: No ${COUNTRY} translate file to flush or cannot compare with synctolive directory, please try again." | colorize red black
                else
                    cd ${TEST_TRANSLATE_DIRECTORY}
                    rsync -avz GameDataTranslateFileList_${LCOUNTRY}.txt nfs TIME1:~/www/${GAME_TYPE}-TEST/.
                fi
            else
                echo "ERROR: No ${COUNTRY} translate file exists!" | colorize red black
            fi
        done
    else
        COUNTRY=$(echo $ALLARGS | sed 's/time1_sync_translate//;s/^ //')
        LCOUNTRY=$(echo ${COUNTRY} | tr '[:upper:]' '[:lower:]')

        TEST_TRANSLATE_DIRECTORY=$(grep -E -a TRANSLATED_INI_UPLOAD_DIR_${COUNTRY} $HOME/.gamerc | grep -a -v '#' | awk -F"=" '{print $2}' | sed 's/"//g')
        echo "SINGLE => ${COUNTRY}" | colorize red green
        MD5_TEST_TRANSLATE_FILELIST=$(md5sum ${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt | awk -F" " '{print $1}')
        MD5_SYNCTOTIME1_TRANSLATE_FILELIST=$(ssh TIME1 "md5sum ~/www/${GAME_TYPE}-TEST/GameDataTranslateFileList_${LCOUNTRY}.txt" | awk -F" " '{print $1}')

        if [ "${MD5_TEST_TRANSLATE_FILELIST}" == "${MD5_SYNCTOTIME1_TRANSLATE_FILELIST}" ]; then
            exec echo "ERROR: No ${COUNTRY} translate file to flush or cannot compare with synctolive directory, please try again." | colorize red black
        else
            cd ${TEST_TRANSLATE_DIRECTORY}
            rsync -avz GameDataTranslateFileList_${LCOUNTRY}.txt nfs TIME1:~/www/${GAME_TYPE}-TEST/.
        fi
    fi
}

media_sync_translate () { # Media -> Sync Translate to MEDIA
    ALLARGS=$(echo $ALLARGS | sed 's/media_sync_translate//;s/^ //')
    echo "ALLARGS => $ALLARGS" | colorize yellow black
    if [ -z "$ALLARGS" ]; then
        for multi_lang_directory in $(grep -E -a TRANSLATED_INI_UPLOAD_DIR_ ${HOME}/.gamerc | grep -a -v '#' | awk -F"=" '{print $2}'); do
            LCOUNTRY=$(echo ${multi_lang_directory} | sed 's/"//g' | awk -F"/" '{print $(NF-1)}' | awk -F"_" '{print $NF}')
            COUNTRY=$(echo ${LCOUNTRY} | tr '[:lower:]' '[:upper:]')

            TEST_TRANSLATE_DIRECTORY=$(echo ${multi_lang_directory} | sed 's/"//g')
            echo "LOOP MULTI => ${COUNTRY}" | colorize red green
            if [ -f "${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt" ]; then
                MD5_TEST_TRANSLATE_FILELIST=$(md5sum ${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt | awk -F" " '{print $1}')
                MD5_SYNCTOMEDIA_TRANSLATE_FILELIST=$(ssh MEDIA "md5sum ~/www/${GAME_TYPE}-TEST/GameDataTranslateFileList_${LCOUNTRY}.txt" | awk -F" " '{print $1}')

                if [ "${MD5_TEST_TRANSLATE_FILELIST}" == "${MD5_SYNCTOMEDIA_TRANSLATE_FILELIST}" ]; then
                    echo "ERROR: No ${COUNTRY} translate file to flush or cannot compare with synctolive directory, please try again." | colorize red black
                else
                    cd ${TEST_TRANSLATE_DIRECTORY}
                    rsync -avz GameDataTranslateFileList_${LCOUNTRY}.txt nfs MEDIA:~/www/${GAME_TYPE}-TEST/.
                fi
            else
                echo "ERROR: No ${COUNTRY} translate file exists!" | colorize red black
            fi
        done
    else
        COUNTRY=$(echo $ALLARGS | sed 's/media_sync_translate//;s/^ //')
        LCOUNTRY=$(echo ${COUNTRY} | tr '[:upper:]' '[:lower:]')

        TEST_TRANSLATE_DIRECTORY=$(grep -E -a TRANSLATED_INI_UPLOAD_DIR_${COUNTRY} $HOME/.gamerc | grep -a -v '#' | awk -F"=" '{print $2}' | sed 's/"//g')
        echo "SINGLE => ${COUNTRY}" | colorize red green
        MD5_TEST_TRANSLATE_FILELIST=$(md5sum ${TEST_TRANSLATE_DIRECTORY}/GameDataTranslateFileList_${LCOUNTRY}.txt | awk -F" " '{print $1}')
        MD5_SYNCTOMEDIA_TRANSLATE_FILELIST=$(ssh MEDIA "md5sum ~/www/${GAME_TYPE}-TEST/GameDataTranslateFileList_${LCOUNTRY}.txt" | awk -F" " '{print $1}')

        if [ "${MD5_TEST_TRANSLATE_FILELIST}" == "${MD5_SYNCTOMEDIA_TRANSLATE_FILELIST}" ]; then
            exec echo "ERROR: No ${COUNTRY} translate file to flush or cannot compare with synctolive directory, please try again." | colorize red black
        else
            cd ${TEST_TRANSLATE_DIRECTORY}
            rsync -avz GameDataTranslateFileList_${LCOUNTRY}.txt nfs MEDIA:~/www/${GAME_TYPE}-TEST/.
        fi
    fi
}

### Game Server DBPatch ###
android_dbpatch () { # Submit -> Patch the databases to GOOGLE-SUBMIT
    if ! [ "$DO_NOT_RUN_DBBACKUP_BEFORE_DBPATCH" == "1" ]; then
        ssh GOOGLE-SUBMIT "DBbackup ${GAME_TYPE}Member"
        ssh GOOGLE-SUBMIT "DBbackup ${GAME_TYPE}Account"
        ssh GOOGLE-SUBMIT "DBbackup ${GAME_TYPE}DB1"
    fi

    ssh GOOGLE-SUBMIT "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-GOOGLE-SUBMIT/db/dbalter"
    ssh GOOGLE-SUBMIT "cd common-GOOGLE-SUBMIT/db;perl dbalter :${GAME_TYPE}DB1"

    ssh GOOGLE-SUBMIT "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-GOOGLE-SUBMIT/db/db_account_alter"
    ssh GOOGLE-SUBMIT "cd common-GOOGLE-SUBMIT/db;perl db_account_alter :${GAME_TYPE}Account"

    if ! [ "$DO_NOT_RUN_DBVACUUM_AFTER_DBPATCH" == "1" ]; then
        ssh GOOGLE-SUBMIT "psql -U postgres <<< 'vacuum analyze;vacuum full;'"
    fi
}

ios_dbpatch () { # Submit -> Patch the databases to APPLE-SUBMIT
    if ! [ "$DO_NOT_RUN_DBBACKUP_BEFORE_DBPATCH" == "1" ]; then
        ssh APPLE-SUBMIT "DBbackup ${GAME_TYPE}Member"
        ssh APPLE-SUBMIT "DBbackup ${GAME_TYPE}Account"
        ssh APPLE-SUBMIT "DBbackup ${GAME_TYPE}DB1"
    fi

    ssh APPLE-SUBMIT "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-APPLE-SUBMIT/db/dbalter"
    ssh APPLE-SUBMIT "cd common-APPLE-SUBMIT/db;perl dbalter :${GAME_TYPE}DB1"

    ssh APPLE-SUBMIT "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-APPLE-SUBMIT/db/db_account_alter"
    ssh APPLE-SUBMIT "cd common-APPLE-SUBMIT/db;perl db_account_alter :${GAME_TYPE}Account"

    if ! [ "$DO_NOT_RUN_DBVACUUM_AFTER_DBPATCH" == "1" ]; then
        ssh APPLE-SUBMIT "psql -U postgres <<< 'vacuum analyze;vacuum full;'"
    fi
}

submit_dbpatch () { # Submit -> Patch the databases to SUBMIT
    ssh SUBMIT "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    ssh SUBMIT "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}10"
    ssh SUBMIT "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}20"
    ssh SUBMIT "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}30"

    ssh SUBMIT "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1001"
    ssh SUBMIT "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2001"
    ssh SUBMIT "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3001"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh SUBMIT "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}10"
        ssh SUBMIT "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}20"
        ssh SUBMIT "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}30"
    fi
}

data_dbpatch () { # Data -> Patch the databases to DATA
    ssh DATA "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    ssh DATA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}10"
    ssh DATA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}20"
    ssh DATA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}30"

    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1001"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1002"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1003"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2001"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2002"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2003"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3001"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3002"
    ssh DATA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3003"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh DATA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}10"
        ssh DATA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}20"
        ssh DATA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}30"
    fi
}

time1_dbpatch () { # Time1 -> Patch the databases to TIME1
    ssh TIME1 "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    ssh TIME1 "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}10"
    ssh TIME1 "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}20"
    ssh TIME1 "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}30"

    ssh TIME1 "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1001"
    ssh TIME1 "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2001"
    ssh TIME1 "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3001"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh TIME1 "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}10"
        ssh TIME1 "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}20"
        ssh TIME1 "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}30"
    fi
}

old_test_dbpatch () { # OldTest -> Patch the databases to OLD_TEST
    ssh OLD_TEST "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    ssh OLD_TEST "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}10"
    ssh OLD_TEST "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}20"
    ssh OLD_TEST "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}30"

    ssh OLD_TEST "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1001"
    ssh OLD_TEST "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2001"
    ssh OLD_TEST "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3001"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh OLD_TEST "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}10"
        ssh OLD_TEST "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}20"
        ssh OLD_TEST "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}30"
    fi
}

media_dbpatch () { # Media -> Patch the databases to MEDIA
    ssh MEDIA "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    ssh MEDIA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}10"
    ssh MEDIA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}20"
    ssh MEDIA "cd common-TEST/db;perl db_game_alter :${GAME_DB_NAME}30"

    ssh MEDIA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}1001"
    ssh MEDIA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}2001"
    ssh MEDIA "cd common-TEST/db;perl db_world_alter :${WORLD_DB_NAME}3001"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh MEDIA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}10"
        ssh MEDIA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}20"
        ssh MEDIA "cd common-TEST/db;perl db_society_alter :${SOCIETY_DB}30"
    fi
}

mapping_dbpatch () { # Mapping -> Patch the databases to MAPPING
    if ! [ "$DO_NOT_RUN_DBBACKUP_BEFORE_DBPATCH" == "1" ]; then
        ssh MAPPING "DBbackup ${MEMBER_DB_NAME}"
        ssh MAPPING "DBbackup ${ACCOUNT_DB_NAME}"
        if [ "$ENABLE_SOCIETY" == "1" ]; then
            ssh MAPPING "DBbackup ${GAME_TYPE}Society"
        fi
        ssh MAPPING "DBbackup ${GAME_DB_NAME}1"
        ssh MAPPING "DBbackup ${GAME_DB_NAME}2"
        ssh MAPPING "DBbackup ${GAME_DB_NAME}${CROSS_ROUTER_SID_TEST}"
    fi

    ssh MAPPING "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-TEST/db/dbalter"
    ssh MAPPING "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-TEST/db/db_account_alter"
    ssh MAPPING "cd common-TEST/db;perl db_account_alter :${GAME_TYPE}Account"
    ssh MAPPING "cd common-TEST/db;perl db_account_alter :${ACCOUNT_DB_NAME}"

    if [ "$ENABLE_SOCIETY" == "1" ]; then
        ssh MAPPING "sed -i -e 's/system (\"pg_dump/#system (\"pg_dump/g;s/^\(.*vacuum.*\)$/#\1/g' common-TEST/db/db_society_alter"
        ssh MAPPING "cd common-TEST/db;perl db_society_alter :${GAME_TYPE}Society"
    fi

    if ! [ "$DO_NOT_RUN_DBVACUUM_AFTER_DBPATCH" == "1" ]; then
        ssh MAPPING "psql -U postgres <<< 'vacuum analyze;vacuum full;'"
    fi
}

### Game Server Itemmall ###
android_itemmall () { # Submit -> Update Promotion Files/Tables from TEST Server to GOOGLE-SUBMIT (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on GOOGLE-SUBMIT)
        echo "Mode 2: File(on TEST)  -->  Table(on GOOGLE-SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on GOOGLE-SUBMIT):" | colorize yellow
            ssh $TEST_SERVER_USER@GOOGLE-SUBMIT "cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh GOOGLE-SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on GOOGLE-SUBMIT)  -->  Table(on GOOGLE-SUBMIT)
        echo "Mode 3: File(on GOOGLE-SUBMIT)  -->  Table(on GOOGLE-SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on GOOGLE-SUBMIT)  -->  Table(on GOOGLE-SUBMIT):" | colorize yellow
            ssh GOOGLE-SUBMIT "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh GOOGLE-SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on GOOGLE-SUBMIT)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on GOOGLE-SUBMIT)
            echo "Syncing table $TABLE(on TEST) -->  Table(on GOOGLE-SUBMIT):" | colorize yellow black
            ssh $TEST_SERVER_USER@TEST pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh GOOGLE-SUBMIT "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

ios_itemmall () { # Submit -> Update Promotion Files/Tables from TEST Server to APPLE-SUBMIT (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on APPLE-SUBMIT)
        echo "Mode 2: File(on TEST)  -->  Table(on APPLE-SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on APPLE-SUBMIT):" | colorize yellow
            ssh $TEST_SERVER_USER@APPLE-SUBMIT "cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh APPLE-SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on APPLE-SUBMIT)  -->  Table(on APPLE-SUBMIT)
        echo "Mode 3: File(on APPLE-SUBMIT)  -->  Table(on APPLE-SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on APPLE-SUBMIT)  -->  Table(on APPLE-SUBMIT):" | colorize yellow
            ssh APPLE-SUBMIT "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh APPLE-SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on APPLE-SUBMIT)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on APPLE-SUBMIT)
            echo "Syncing table $TABLE(on TEST) -->  Table(on APPLE-SUBMIT):" | colorize yellow black
            ssh $TEST_SERVER_USER@TEST pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh APPLE-SUBMIT "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

submit_itemmall () { # Submit -> Update Promotion Files/Tables from TEST Server to SUBMIT (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on SUBMIT)
        echo "Mode 2: File(on TEST)  -->  Table(on SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on SUBMIT):" | colorize yellow
            ssh $TEST_SERVER_USER@SUBMIT "cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on SUBMIT)  -->  Table(on SUBMIT)
        echo "Mode 3: File(on SUBMIT)  -->  Table(on SUBMIT)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on SUBMIT)  -->  Table(on SUBMIT):" | colorize yellow
            ssh SUBMIT "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh SUBMIT "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on SUBMIT)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on SUBMIT)
            echo "Syncing table $TABLE(on TEST) -->  Table(on SUBMIT):" | colorize yellow black
            ssh $TEST_SERVER_USER@TEST pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh SUBMIT "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

data_itemmall () { # Data -> Update Promotion Files/Tables from TEST Server to DATA (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on DATA)
        echo "Mode 2: File(on TEST)  -->  Table(on DATA)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on DATA):" | colorize yellow
            ssh $TEST_SERVER_USER@DATA "cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh DATA "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on DATA)  -->  Table(on DATA)
        echo "Mode 3: File(on DATA)  -->  Table(on DATA)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on DATA)  -->  Table(on DATA):" | colorize yellow
            ssh DATA "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh DATA "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on DATA)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on DATA)
            echo "Syncing table $TABLE(on TEST) -->  Table(on DATA):" | colorize yellow black
            ssh $TEST_SERVER_USER@TEST pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh DATA "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

time1_itemmall () { # Time1 -> Update Promotion Files/Tables from TEST Server to TIME1 (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on TIME1)
        echo "Mode 2: File(on TEST)  -->  Table(on TIME1)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on TIME1):" | colorize yellow
            cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh TIME1 "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on TIME1)  -->  Table(on TIME1)
        echo "Mode 3: File(on TIME1)  -->  Table(on TIME1)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TIME1)  -->  Table(on TIME1):" | colorize yellow
            ssh TIME1 "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh TIME1 "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on TIME1)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on TIME1)
            echo "Syncing table $TABLE(on TEST) -->  Table(on TIME1):" | colorize yellow black
            pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh TIME1 "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    $HOME/bin/send_fastcgi_time1_n1 reload_activity_db
    $HOME/bin/send_fastcgi_time1_n1 reload_itemmall_db
    $HOME/bin/send_fastcgi_time1_n1 reload_cheatdetection_db
    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

old_test_itemmall () { # OldTest -> Update Promotion Files/Tables from TEST Server to OLD_TEST (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on OLD_TEST)
        echo "Mode 2: File(on TEST)  -->  Table(on OLD_TEST)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on OLD_TEST):" | colorize yellow
            cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh OLD_TEST "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on OLD_TEST)  -->  Table(on OLD_TEST)
        echo "Mode 3: File(on OLD_TEST)  -->  Table(on OLD_TEST)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on OLD_TEST)  -->  Table(on OLD_TEST):" | colorize yellow
            ssh OLD_TEST "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh OLD_TEST "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on OLD_TEST)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on OLD_TEST)
            echo "Syncing table $TABLE(on TEST) -->  Table(on OLD_TEST):" | colorize yellow black
            pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh OLD_TEST "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

media_itemmall () { # Media -> Update Promotion Files/Tables from TEST Server to MEDIA (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on MEDIA)
        echo "Mode 2: File(on TEST)  -->  Table(on MEDIA)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on MEDIA):" | colorize yellow
            cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh MEDIA "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on MEDIA)  -->  Table(on MEDIA)
        echo "Mode 3: File(on MEDIA)  -->  Table(on MEDIA)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on MEDIA)  -->  Table(on MEDIA):" | colorize yellow
            ssh MEDIA "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh MEDIA "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on MEDIA)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on MEDIA)
            echo "Syncing table $TABLE(on TEST) -->  Table(on MEDIA):" | colorize yellow black
            pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh MEDIA "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

mapping_itemmall () { # Mapping -> Update Promotion Files/Tables from TEST Server to MAPPING (argument: table names)

    TABLES_TO_APPLY="$ARG2 $ARG3 $ARG4 $ARG5 $ARG6 $ARG7"
    grep -a -q "[A-Za-z]" <<< "$TABLES_TO_APPLY" && PROMOTION_TABLES_APPLY_TO_LIVE="$TABLES_TO_APPLY"

    if [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "2" ]; then # 2 = File(on TEST)  -->  Table(on MAPPING)
        echo "Mode 2: File(on TEST)  -->  Table(on MAPPING)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on TEST)  -->  Table(on MAPPING):" | colorize yellow
            ssh $TEST_SERVER_USER@MAPPING "cat ~/common-$SOURCE_OF_SYNC_TO_LIVE/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh MAPPING "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    elif [ "$PROMOTION_DATA_APPLY_TO_LIVE_MODE" == "3" ]; then # 3 = File(on MAPPING)  -->  Table(on MAPPING)
        echo "Mode 3: File(on MAPPING)  -->  Table(on MAPPING)" | colorize green
        for SQL_FILE in $PROMOTION_FILES_APPLY_TO_LIVE; do
            echo "File $SQL_FILE(on MAPPING)  -->  Table(on MAPPING):" | colorize yellow
            ssh MAPPING "cat ~/servers1/$SQL_FILE" | grep -a -v "GRANT ALL" | sed 's/PUBLIC/PUBLIC\;/g' | ssh MAPPING "psql $ACCOUNT_DB_NAME" 2>&1 | uniq -c
        done

    else
        echo "Mode 1: Table(on TEST) -->  Table(on MAPPING)" | colorize green
        for TABLE in $PROMOTION_TABLES_APPLY_TO_LIVE; do # 1 = Table(on TEST) -->  Table(on MAPPING)
            echo "Syncing table $TABLE(on TEST) -->  Table(on MAPPING):" | colorize yellow black
            ssh $TEST_SERVER_USER@TEST pg_dump --clean --attribute-inserts -t $TABLE $ACCOUNT_DB_NAME | grep -a -v "SET lock_timeout" | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | ssh MAPPING "psql $ACCOUNT_DB_NAME" | uniq -c &&
                echo "Table $TABLE done." | colorize green ||
                echo "Table $TABLE failed." | colorize red
        done
    fi

    echo "
Remember, if you are updating the Promotion Files/Tables on running servers,
You will have to run these GM commands to apply in game:
1. /reload_itemmall_db
2. /rnba
3. /reload_daily_login_reward
4. /reload_playground_db
5. /reload_iap_db" | colorize green
}

online_reload_cgi () {
    local TABLE_NAME=$1
    if [[ -z "$TABLE_NAME" ]]; then
        echo "用法: online_reload_cgi <table_name>" >&2
        return 1
    fi

    # Tools DB 連線（env 可覆蓋；預設依該機器主要環境調整）
    local DB="${TOOLS_DB_NAME:-Tools}"
    local DBUSER="${TOOLS_DB_USER:-postgres}"
    local DBHOST="${TOOLS_DB_HOST:-127.0.0.1}"

    # Debug：顯示這次連哪個 DB
    echo "[online_reload_cgi] query ${DB}@${DBHOST} for table: ${TABLE_NAME}"

    # 查 web_table_mapping：
    #   - row 不存在           → 空字串
    #   - row 存在 cgi NULL/空 → "__NOCMD__"
    #   - row 存在 有 cgi      → cgi 內容
    local RESULT
    RESULT=$(psql -U "${DBUSER}" -h "${DBHOST}" -d "${DB}" -tAc \
        "SELECT COALESCE(NULLIF(cgi_cmd, ''), '__NOCMD__') FROM web_table_mapping WHERE table_name_db = '${TABLE_NAME}'" \
        2>/dev/null | xargs)

    if [[ -z "${RESULT}" ]]; then
        # 資料表未登錄 → 跳錯 + 通知管理員
        local MSG="❗ 資料表 ${TABLE_NAME} 未登錄於 web_table_mapping，請至 Tools 後台「資料表管理」新增"
        echo "$MSG"
        $HOME/bin/send_chatbot_text_only_by_thread_tag "itemmall" "$MSG" minute 10
        return 1
    fi

    if [[ "${RESULT}" == "__NOCMD__" ]]; then
        # 有登錄但沒對應 CGI，只發同步完成通知
        $HOME/bin/send_chatbot_text_only_by_thread_tag "itemmall" "資料表 ${TABLE_NAME} 同步完成" minute 10
        return 0
    fi

    # 正常情況：有 CGI
    local CGI_CMD="${RESULT}"
    server_online_check
    if [ $? -eq 1 ]; then
        $HOME/bin/send_fastcgi_all_n1 ${CGI_CMD}
        $HOME/bin/send_chatbot_text_only_by_thread_tag "itemmall" "資料表 ${TABLE_NAME} 同步完成\nCGI Command: ${CGI_CMD} 也已經執行!" minute 10
    else
        $HOME/bin/send_chatbot_text_only_by_thread_tag "itemmall" "資料表 ${TABLE_NAME} 同步完成" minute 10
    fi
}

online_reload_cgi_test () {
    TABLE_NAME=$1

    case ${TABLE_NAME} in
        activity_accruebuy_*)
            CGI_CMD="reload_activity_accruebuy_db"
            ;;
        activity_alchemy_wheel|activity_alchemy_wheel_*)
            CGI_CMD="reload_activity_alchemywheel_db"
            ;;
        activity_battle_pass|activity_battle_pass_*)
            CGI_CMD="reload_activity_battlepass_db"
            ;;
        activity_bingo_*)
            CGI_CMD="reload_activity_bingo_db"
            ;;
        activity_consume|activity_consume_*)
            CGI_CMD="reload_activity_consume_db"
            ;;
        activity_dailylogin_*)
            CGI_CMD="reload_activity_dailylogin_db"
            ;;
        activity_days_mission_store_*)
            CGI_CMD="reload_activity_daysmissionstore_db"
            ;;
        activity_donation_*)
            CGI_CMD="reload_activity_donation_db"
            ;;
        activity_gemwheel_*)
            CGI_CMD="reload_activity_gemwheel_db"
            ;;
        activity_guild_rank_event_*)
            CGI_CMD="reload_activity_guildrankevent_db"
            ;;
        activity_lottery_*)
            CGI_CMD="reload_activity_lottery_db"
            ;;
        activity_mergeparty_*)
            CGI_CMD="reload_activity_mergeparty_db"
            ;;
        activity_minigame_classify_reward)
            CGI_CMD="reload_activity_minigameclassification_db"
            ;;
        activity_minigame_pass_*|activity_minigame_wheel_*)
            CGI_CMD="reload_activity_minigamewheel_db"
            ;;
        activity_mission_battle_pass_*)
            CGI_CMD="reload_activity_missionbattlepass_db"
            ;;
        activity_mission_store_*)
            CGI_CMD="reload_activity_missionstore_db"
            ;;
        activity_rank_event_*)
            CGI_CMD="reload_activity_rankevent_db"
            ;;
        activity_specialfortunebag_*)
            CGI_CMD="reload_activity_specialfortunebag_db"
            ;;
        activity_wheel2_*)
            CGI_CMD="reload_activity_wheel2_db"
            ;;
        activity_wheel_*)
            CGI_CMD="reload_activity_wheel_db"
            ;;
        cheat_detection_rankstage)
            CGI_CMD="reload_cheatdetection_db"
            ;;
        fortune_bag|itemmall_item|store_*|suggestbuy)
            CGI_CMD="reload_itemmall_db"
            ;;
        *)
            echo "Unknown CGI Command for ${TABLE_NAME}!"
            ;;
    esac

    if ! test -z ${CGI_CMD}; then
        server_online_check
        if [ $? -eq 1 ]; then
            $HOME/bin/send_fastcgi_test_n1 ${CGI_CMD}
            $HOME/bin/automatic_send_chatbot_text_only_by_thread_tag "itemmall" "資料表 ${TABLE_NAME} 同步完成\nCGI Command: ${CGI_CMD} 也已經執行!" minute 10
        else
            $HOME/bin/automatic_send_chatbot_text_only_by_thread_tag "itemmall"  "資料表 ${TABLE_NAME} 同步完成" minute 10
        fi
    fi
}
