diff --git a/background.js b/background.js index 530ce8c..e557d32 100644 --- a/background.js +++ b/background.js @@ -1,34 +1,71 @@ const playSound = () => { - if (typeof (audio) != "undefined" && audio) { - audio.pause(); - document.body.removeChild(audio); - audio = null; - } - audio = document.createElement('audio'); - document.body.appendChild(audio); - audio.autoplay = true; - audio.src = chrome.extension.getURL('tada.mp3'); - audio.play(); + if (typeof (audio) != "undefined" && audio) { + audio.pause(); + document.body.removeChild(audio); + audio = null; + } + audio = document.createElement('audio'); + document.body.appendChild(audio); + audio.autoplay = true; + audio.src = chrome.runtime.getURL('tada.mp3'); + audio.play(); }; const sendTelegramMessage = () => { - const botToken = localStorage.getItem('KTX_MACRO::bot-token'); - const chatId = localStorage.getItem('KTX_MACRO::chat-id'); + chrome.storage.local.get( + ['ktx-macro-bot-token', 'ktx-macro-chat-id'], + function (result) { + const msg = encodeURI('예약을 시도하였습니다. 예약을 확인해주세요.'); + const url = `https://api.telegram.org/bot${result['ktx-macro-bot-token']}/sendmessage?chat_id=${result['ktx-macro-chat-id']}&text=${msg}`; - if (!botToken || !chatId) { - return; - } + fetch(url); + } + ); +} - const msg = encodeURI('예약을 시도하였습니다. 예약을 확인해주세요.'); - const url = `https://api.telegram.org/bot${botToken}/sendmessage?chat_id=${chatId}&text=${msg}`; +const removeMacroTab = (tabid) => { + chrome.storage.local.get(["ktx-macro-tabs"], + function (result) { + let tabs = result["ktx-macro-tabs"]; + console.log('remove tab tabs: ' + tabs + ', tabid: ' + tabid); + if (typeof(tabs) != "object" || !Array.isArray(tabs)) + tabs = []; - fetch(url); + var index = tabs.indexOf(tabid); + if (index != -1) { + tabs.splice(index, 1); + chrome.storage.local.set({"ktx-macro-tabs": tabs}); + } + } + ); } -chrome.extension.onMessage.addListener((message, sender, sendResponse) => { - if (message && message.type == 'successTicketing') { - playSound(); - sendTelegramMessage(); - sendResponse(true); - } +const checkMacroTabs = () => { + var tabid; + for (tabid of tabs) { + chrome.tabs.get(tabid, function (tab) { + if (chrome.runtime.lastError) { + console.log(chrome.runtime.lastError); + } + if (!tab) { + removeTab(tabid); + } + }); + } +}; + +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + //console.log('message: ' + message); + if (message && message.type == 'successTicketing') { + //playSound(); + sendTelegramMessage(); + sendResponse(true); + } + else if (message && message.type == 'tabId') { + sendResponse(sender.tab.id); + } }); + +chrome.tabs.onRemoved.addListener(function (tabid, removed) { + removeMacroTab(tabid); +}); \ No newline at end of file diff --git a/content.css b/content.css index 4974556..f72acd3 100644 --- a/content.css +++ b/content.css @@ -1,13 +1,28 @@ .ktx-macro-button { - width: 175px; - height: 38px; - line-height: 38px; - text-align: center; - background: #f46b45; - background: -webkit-linear-gradient(to bottom, #eea849, #f46b45); - background: linear-gradient(to bottom, #eea849, #f46b45); - color: #ffffff; - font-size: 13px; - border: 1px solid #f76707; - cursor: pointer; + width: 175px; + height: 38px; + line-height: 38px; + text-align: center; + background: #f46b45; + background: -webkit-linear-gradient(to bottom, #eea849, #f46b45); + background: linear-gradient(to bottom, #eea849, #f46b45); + color: #ffffff; + font-size: 13px; + border: 1px solid #f76707; + cursor: pointer; +} + +.check-all-button { + padding-left: 10px; + padding-right: 10px; + height: 38px; + line-height: 38px; + text-align: center; + background: #f46b45; + background: -webkit-linear-gradient(to bottom, #eea849, #f46b45); + background: linear-gradient(to bottom, #eea849, #f46b45); + color: #ffffff; + font-size: 13px; + border: 1px solid #f76707; + cursor: pointer; } \ No newline at end of file diff --git a/content.js b/content.js index d261bcc..94fb889 100644 --- a/content.js +++ b/content.js @@ -1,222 +1,480 @@ -let uid = 1; -const MAIN_URI = "https://www.letskorail.com/ebizprd/EbizPrdTicketPr21111_i1.do"; -const LOGIN_PAGE_URI = "https://www.letskorail.com/korail/com/login.do"; +let CHECKBOX_COLUMN = [5, 6, 10]; +const MAIN_PAGE = 0; +const FAMILY_PAGE = 1; +let RESERVE_BUTTON = {}; +let PAGE = MAIN_PAGE; +let checkboxLastClickPos = {"row": -1, "column": -1}; + +const getTableResult = () => { + return document.querySelectorAll("#divResult > .tbl_h > tbody > tr"); +}; -const createCheckbox = () => { - const $rows = document.querySelectorAll("#tableResult > tbody > tr"); +const getTableResultColumn = (row, column) => { + return getTableResult()[row].querySelector(`td:nth-child(${column})`); +}; + +const getTableResultCheckbox = (objRow, column) => { + return objRow.querySelector(`td:nth-child(${column}) .ktx-macro-checkbox`); +}; + +const createHeaderCheckbox = () => { + const row = document.querySelector("#divResult > .tbl_h > thead > tr"); + var child; + + for (var col of CHECKBOX_COLUMN) { + child = row.querySelector(`th:nth-child(${col})`); + child.insertAdjacentHTML("beforeend", + ` +
+ +
+ ` + ); + } + +}; - if (!$rows.length) { - return; - } +const setHeaderCheckboxEvent = () => { + const header = document.querySelector("#divResult > .tbl_h > thead > tr"); - $rows.forEach($row => { - $row - .querySelector("td:nth-child(5)") - .insertAdjacentHTML("beforeend", getCheckboxTemplate(uid++)); - $row - .querySelector("td:nth-child(6)") - .insertAdjacentHTML("beforeend", getCheckboxTemplate(uid++)); - $row - .querySelector("td:nth-child(10)") - .insertAdjacentHTML("beforeend", getCheckboxTemplate(uid++)); - }); + for (var col of CHECKBOX_COLUMN) { + header.querySelector(`th:nth-child(${col}) .ktx-macro-header-checkbox`) + .addEventListener('change', changeHeaderCheckbox); + } +}; + +const changeHeaderCheckbox = (event) => { + const rows = document.querySelectorAll("#divResult > .tbl_h > tbody > tr"); + const child_num = event.target.dataset.column; + + if (!rows || !rows.length) { + return; + } + + rows.forEach((row) => { + row.querySelector(`td:nth-child(${child_num}) .ktx-macro-checkbox`) + .checked = event.target.checked; + }); + saveCheckboxState(); +}; + +const createCheckbox = () => { + const rows = document.querySelectorAll("#divResult > .tbl_h > tbody > tr"); + + if (!rows.length) { + return; + } + + rows.forEach((o, row) => { + for (var col of CHECKBOX_COLUMN) { + o.querySelector(`td:nth-child(${col})`) + .insertAdjacentHTML("beforeend", + getCheckboxTemplate(uid++, row, col)); + } + }); }; const isChecked = uid => { - const checkedItemsStr = localStorage.getItem("checkedItems"); - const checkedItems = checkedItemsStr ? checkedItemsStr.split(",") : []; + const checkedItemsStr = getTabStorageItem("checkedItems"); + const checkedItems = checkedItemsStr ? checkedItemsStr.split(",") : []; - if (!checkedItems.length) { - return false; - } + if (!checkedItems.length) { + return false; + } - return checkedItems.includes(String(uid)); + return checkedItems.includes(String(uid)); }; const isLogin = () => !!document.querySelectorAll(".gnb_list > .log_nm").length; -const getCheckboxTemplate = uid => { - if (!uid) { - return; - } - - return ` -
- -
- `; +const getCheckboxTemplate = (uid, row, column) => { + if (!uid) { + return; + } + + return ` +
+ +
+ `; }; const setCheckboxEvent = () => { - const $checkboxes = document.querySelectorAll(".ktx-macro-checkbox"); + const $checkboxes = document.querySelectorAll(".ktx-macro-checkbox"); - for (let i = 0; i < $checkboxes.length; i++) { - $checkboxes[i].addEventListener("click", () => { - saveCheckboxState(); - }); - } + for (let i = 0; i < $checkboxes.length; i++) { + $checkboxes[i].addEventListener("click", clickCheckbox); + } }; const setEscapeEvent = () => { - window.addEventListener("keydown", e => { - if (e.key === "Escape") { - macroStop(); - } - }); + window.addEventListener("keydown", e => { + if (e.key === "Escape") { + macroStop(); + } + }); }; const macroStart = () => { - if (!isLogin()) { - if (confirm("로그인이 필요합니다.\n로그인 페이지로 이동하시겠습니까?")) { - location.href = LOGIN_PAGE_URI; - } - return; - } + if (!isLogin()) { + if (confirm("로그인이 필요합니다.\n로그인 페이지로 이동하시겠습니까?")) { + location.href = LOGIN_PAGE_URI; + } + return; + } + + if (!getTabStorageItem("checkedItems")) { + alert("선택 된 항목이 없습니다.\n1개 이상 선택해주세요."); + return; + } + + alert( + "자동 예매를 시작합니다.\n" + + "예매 성공 후 20분내에 결제하지 않을 경우 자동으로 예매가 취소됩니다.\n" + + "자동 예매 종료는 '자동 예매 정지' 혹은 esc키를 눌러주세요." + ); + + setTabStorageItem("macro", "on"); + + reload(); +}; - if (!localStorage.getItem("checkedItems")) { - alert("선택 된 항목이 없습니다.\n1개 이상 선택해주세요."); - return; - } +const macroStop = () => { + alert("자동 예매를 종료합니다."); + removeTabStorageItem("macro"); + removeTabStorageItem("checkedItems"); - alert( - "자동 예매를 시작합니다.\n" + - "예매 성공 후 20분내에 결제하지 않을 경우 자동으로 예매가 취소됩니다.\n" + - "자동 예매 종료는 '자동 예매 정지' 혹은 esc키를 눌러주세요." - ); + reload(); +}; - localStorage.setItem("macro", "on"); +const macro = () => { + let uid = 0; + let $row; + const $rows = document.querySelectorAll("#divResult > .tbl_h > tbody > tr"); + const len = $rows.length; + let succeeded = false; + let $td, $a; + + if (!len) { + return; + } + + for (let i = 0; i < len && !succeeded; i++) { + $row = $rows[i]; + for (let col of CHECKBOX_COLUMN) { + if (!isChecked(++uid)) { + continue; + } + $td = $row.querySelector(`td:nth-child(${col})`); + $td.style.backgroundColor = "#f03e3e"; + $a = $td.querySelector(`a:nth-child(1)`); + let $button; + for (let img of RESERVE_BUTTON[col]) { + //console.log(img); + //src starts with img + $button = $td.querySelector('[src^="' + img + '"]'); + if ($button) { + break; + } + } + + if ($a) { + new Audio(chrome.runtime.getURL("tada.mp3")).play(); + removeTabStorageItem("macro"); + chrome.runtime.sendMessage({ type: "successTicketing" }); + //inject_click($button.closest("a")); + inject_click($a); + succeeded = true; + break; + } + } + if (succeeded) { + break; + } + } + + if (!succeeded) + setTimeout(reload, 1200); +}; - reload(); +const reload = () => { + inject_click(document.querySelector(".btn_inq > a")); }; -const macroStop = () => { - alert("자동 예매를 종료합니다."); - localStorage.removeItem("macro"); - localStorage.removeItem("checkedItems"); +const inject_click = (obj) => { + console.log('inject_click: ' + obj); + var s = document.createElement('script'); + obj.id = 'ktx-macro-click'; - reload(); + s.src = chrome.runtime.getURL('inject_click.js'); + s.onload = function () { + this.remove(); + }; + (document.head || document.documentElement).appendChild(s); }; -const macro = () => { - let uid = 0; - let $row; - const $rows = document.querySelectorAll("#tableResult > tbody > tr"); - const len = $rows.length; - - if (!len) { - return; - } - - for (let i = 0; i < len; i++) { - $row = $rows[i]; - - if (isChecked(++uid)) { - $row.querySelector("td:nth-child(5)").style.backgroundColor = "#f03e3e"; - const $button = - $row - .querySelector("td:nth-child(5)") - .querySelector('[src="/docs/2007/img/common/icon_apm_bl.gif"]') || - $row - .querySelector("td:nth-child(5)") - .querySelector('[src="/docs/2007/img/common/icon_apm_rd.gif"]'); - - if ($button) { - $button.closest("a").click(); - localStorage.removeItem("macro"); - chrome.extension.sendMessage({ type: "successTicketing" }); - break; - } - } - - if (isChecked(++uid)) { - $row.querySelector("td:nth-child(6)").style.backgroundColor = "#f03e3e"; - const $button = - $row - .querySelector("td:nth-child(6)") - .querySelector('[src="/docs/2007/img/common/icon_apm_bl.gif"]') || - $row - .querySelector("td:nth-child(6)") - .querySelector('[src="/docs/2007/img/common/icon_apm_rd.gif"]'); - - if ($button) { - $button.closest("a").click(); - localStorage.removeItem("macro"); - chrome.extension.sendMessage({ type: "successTicketing" }); - break; - } - } - - if (isChecked(++uid)) { - $row.querySelector("td:nth-child(10)").style.backgroundColor = "#f03e3e"; - const $button = $row.querySelector("td:nth-child(10)") - .querySelector('[src="/docs/2007/img/common/icon_wait.gif"]'); - - if ($button) { - $button.closest("a").click(); - localStorage.removeItem("macro"); - chrome.extension.sendMessage({ type: "successTicketing" }); - break; - } - } - } - - setTimeout(reload, 1000); +//nonstop 팝업 자동 닫기 +const closeNonstopPopup = () => { + + if (!document.querySelector(".btn_blue_ang")) + return; + + var s = document.createElement('script'); + s.innerHTML = ` + var btn_blue_ang = document.querySelector('.btn_blue_ang'); + if (btn_blue_ang.text.indexOf('예매 계속 진행하기') != -1) { + console.log('close popup'); + setTimeout(f_close, 1000); + }; + `; + document.body.appendChild(s); }; -const reload = () => { - document.querySelector(".btn_inq > a").click(); +//nonstop 팝업 무시 +const ignoreNonstopPopup = () => { + var s = document.createElement('script'); + s.innerHTML = ` + if (typeof(Nopeople2) == 'function') { + console.log('disable Nopeople2'); + const originNopeople2 = Nopeople2; + Nopeople2 = function (intPsrm, intIdxNo, iAddInfo4, callback) { + console.log('remove h_nonstop_msg. ' + train[intIdxNo].h_nonstop_msg); + train[intIdxNo].h_nonstop_msg = ''; + return originNopeople2(intPsrm, intIdxNo, iAddInfo4, callback); + } + } + `; + document.body.appendChild(s); +} + +//인원 확인 컨펌 무시 +const ignoreConfirmPeople = () => { + var s = document.createElement('script'); + s.innerHTML = ` + const origin_confirm = confirm; + confirm = function (message) { + console.log('confirm: ' + message); + if (message.indexOf('맞습니까') != -1) { + return true; + } + return origin_confirm(message); + } + `; + document.body.appendChild(s); +} + +//일일 팝업 무시 +const ignoreDailyPopup = () => { + var s = document.createElement('script'); + s.innerHTML = ` + if (typeof(openGwangjuShuttleDialog) == 'function') { + console.log('disable openGwangjuShuttleDialog'); + openGwangjuShuttleDialog = function () {}; + } + `; + document.body.appendChild(s); +} + +const clickCheckbox = (event) => { + var multi_check = false; + const curr_row = Number(event.target.dataset.row); + const curr_col = Number(event.target.dataset.column); + const prev_row = Number(checkboxLastClickPos.row); + const prev_col = Number(checkboxLastClickPos.column); + //console.log('checkbox row=' + event.target.dataset.row + ' column=' + event.target.dataset.column); + do { + if (!event.shiftKey || event.ctrlKey || event.altKey) + break; + if (prev_row == -1 || prev_col == -1) + break; + if (curr_col != prev_col) + break; + if (curr_row == prev_row) + break; + + const objRows = getTableResult(); + var objCol; + var start, end; + multi_check = true; + + if (curr_row > prev_row) { + start = prev_row; + end = curr_row - 1; + } + else { + start = curr_row + 1; + end = prev_row; + } + + for (var i = start; i <= end; i++) { + //console.log('row=' + i + ', column=' + event.target.dataset.column); + objCol = getTableResultCheckbox(objRows[i], curr_col); + objCol.checked = event.target.checked; + } + } + while (0); + + if (!multi_check) { + checkboxLastClickPos.row = curr_row; + checkboxLastClickPos.column = curr_col; + if (prev_row != -1 && prev_col != -1) + getTableResultColumn(prev_row, prev_col).style.backgroundColor = ""; + getTableResultColumn(curr_row, curr_col).style.backgroundColor = "#ccccff"; + } + saveCheckboxState(); }; const saveCheckboxState = () => { - let checkedItems = []; - const $checkboxes = document.querySelectorAll(".ktx-macro-checkbox"); + let checkedItems = []; + const $checkboxes = document.querySelectorAll(".ktx-macro-checkbox"); + + for (let i = 0; i < $checkboxes.length; i++) { + if ($checkboxes[i].checked) { + checkedItems.push($checkboxes[i].value); + } + } + + if (checkedItems.length) { + setTabStorageItem("checkedItems", checkedItems.join(",")); + } else { + removeTabStorageItem("checkedItems"); + } +}; + +const checkAllCheckbox = () => { + var i; + var list = document.querySelectorAll(".ktx-macro-checkbox"); + for (i = 0; i < list.length; i++) { + list[i].checked = true; + } + saveCheckboxState(); +}; + +const inject = () => { + var s= document.createElement('script'); + s.src = chrome.runtime.getURL('inject.js'); + s.setAttribute('value', 'passed?'); + s.onload = function () { + console.log('inject onload'); + this.remove(); + }; + (document.head || document.documentElement).appendChild(s); +}; + +const inject_nonstop_popup = () => { + var s= document.createElement('script'); + s.src = chrome.runtime.getURL('inject_nonstop_popup.js'); + s.onload = function () { + console.log('inject_nonstop_popup onload'); + this.remove(); + }; + (document.head || document.documentElement).appendChild(s); +}; - for (let i = 0; i < $checkboxes.length; i++) { - if ($checkboxes[i].checked) { - checkedItems.push($checkboxes[i].value); - } - } - if (checkedItems.length) { - localStorage.setItem("checkedItems", checkedItems.join(",")); - } else { - localStorage.removeItem("checkedItems"); - } +const initialize = () => { + console.log("tabId: " + tabId); + + const isStarted = getTabStorageItem("macro") == "on"; + + if (isStarted) { + if (reloadTimeoutID) { + console.log('stop reload timer ' + reloadTimeoutID); + window.clearTimeout(reloadTimeoutID); + reloadTimeoutID = null; + } + macro(); + setEscapeEvent(); + } else { + removeTabStorageItem("checkedItems"); + } + + document.querySelector(".btn_inq").insertAdjacentHTML( + "beforeend", + ` + + + ` + ); + + document + .querySelector(".ktx-macro-button") + .addEventListener("click", isStarted ? macroStop : macroStart); + + document + .querySelector(".check-all-button") + .addEventListener("click", checkAllCheckbox); + + createHeaderCheckbox(); + createCheckbox(); + setHeaderCheckboxEvent(); + setCheckboxEvent(); + //ignoreNonstopPopup(); + //ignoreConfirmPeople(); + //ignoreDailyPopup(); + inject(); }; (() => { - if ( - !document.querySelector(".btn_inq") || - !location.href.startsWith(MAIN_URI) - ) { - return; - } - - const isStarted = localStorage.getItem("macro") === "on"; - - if (isStarted) { - macro(); - setEscapeEvent(); - } else { - localStorage.removeItem("checkedItems"); - } - - document.querySelector(".btn_inq").insertAdjacentHTML( - "beforeend", - ` - - ` - ); - - document - .querySelector(".ktx-macro-button") - .addEventListener("click", isStarted ? macroStop : macroStart); - - createCheckbox(); - setCheckboxEvent(); + disableEventListners(); + + if (location.href.startsWith(POPUP_URI)) { + inject_nonstop_popup(); + return; + } + else if (!document.querySelector(".btn_inq")) { + return; + } + + if (location.href.startsWith(MAIN_URI)) { + PAGE = MAIN_PAGE; + CHECKBOX_COLUMN = [5, 6, 10]; + RESERVE_BUTTON[5] = [ + "/docs/2007/img/common/icon_apm_bl.gif", + "/docs/2007/img/common/icon_apm_rd.gif" + ]; + RESERVE_BUTTON[6] = [ + "/docs/2007/img/common/icon_apm_bl.gif", + "/docs/2007/img/common/icon_apm_rd.gif" + ]; + RESERVE_BUTTON[10] = [ + "/docs/2007/img/common/icon_wait.gif" + ]; + } + else if (location.href.startsWith(FAMILY_URI)) { + PAGE = FAMILY_PAGE; + CHECKBOX_COLUMN = [5]; + RESERVE_BUTTON[5] = [ + "/docs/2007/img/persent/btn" + ]; + } + else { + return; + } + + chrome.runtime.sendMessage( + {type: 'tabId'}, + function (result) { + tabId = result; + addMacroTab(tabId); + initialize(); + } + ); })(); diff --git a/content_header.js b/content_header.js new file mode 100644 index 0000000..096b39f --- /dev/null +++ b/content_header.js @@ -0,0 +1,101 @@ +let tabId = 0; +let uid = 1; +let reloadTimeoutID = null; + +const MAIN_URI = "https://www.letskorail.com/ebizprd/EbizPrdTicketPr21111_i1.do"; +const FAMILY_URI = "https://www.letskorail.com/ebizprd/EbizPrdTicketPr21151_i1.do"; +const LOGIN_PAGE_URI = "https://www.letskorail.com/korail/com/login.do"; +const POPUP_URI = "https://www.letskorail.com/docs/pz/pz_msg_pop1.jsp"; +const PAGE_TIMEOUT = 15000; + +const getTabStorageKey = (key) => { + return String(key) + String(tabId); +}; + +const getTabIdFromTabStorageKey = (key) => { + for (var i = 0; i < key.length; i++) { + if (!isNaN(key[i])) + return Number(key.substring(i)); + } + return 0; +}; + +const removeUnusedTabStorage = (tabs) => { + var tabid; + var key; + console.log('tabs: ' + tabs); + + for (key in localStorage) { + if (!key.startsWith('macro') && !key.startsWith('checkedItems')) + continue; + + tabid = getTabIdFromTabStorageKey(key); + + console.log( + 'key: ' + key + ', ' + + 'tabid: ' + tabid + ', ' + + 'indexOf: ' + tabs.indexOf(tabid)); + + if (tabs.indexOf(tabid) === -1) { + console.log('removeItem: ' + key); + localStorage.removeItem(key); + } + } +}; + +const getTabStorageItem = (key) => { + return localStorage.getItem(getTabStorageKey(key)); +}; + +const setTabStorageItem = (key, value) => { + localStorage.setItem(getTabStorageKey(key), value); +}; + +const removeTabStorageItem = (key) => { + localStorage.removeItem(getTabStorageKey(key)); +}; + +const addMacroTab = (tabid) => { + chrome.storage.local.get(["ktx-macro-tabs"], + function (result) { + let tabs = result["ktx-macro-tabs"]; + if (typeof(tabs) != "object" || !Array.isArray(tabs)) + tabs = []; + if (tabs.indexOf(tabid) === -1) { + tabs.push(tabid); + console.log("tabs: " + tabs); + chrome.storage.local.set({"ktx-macro-tabs": tabs}); + } + } + ); +}; + +const disableEventListners = () => { + //const events = ["selectstart", "mousedown", "contextmenu", "copy", "keydown"]; + const events = ["selectstart", "mousedown", "mousemove", "contextmenu", "copy"]; + events.forEach(function(item) { + window.addEventListener(item, stopEventPropagation, true); + }); + window.addEventListener("keydown", stopKeydownPropogation, true); + +}; + +const stopEventPropagation = (event) => { + event.stopPropagation(); +}; + +const stopKeydownPropogation = (event) => { + if (event.keyCode == 17 || event.ctrlKey) + event.stopPropagation(); +}; + +(() => { + //console.log("content_header"); + chrome.storage.local.get(["ktx-macro-tabs"], + function (result) { + let tabs = result["ktx-macro-tabs"]; + console.log("tabs: " + tabs); + removeUnusedTabStorage(tabs); + } + ); +})(); \ No newline at end of file diff --git a/inject.js b/inject.js index e69de29..b2d8527 100644 --- a/inject.js +++ b/inject.js @@ -0,0 +1,39 @@ +console.log('inject.js'); +console.log('value: ' + document.currentScript.getAttribute('value')); + +//nonstop 팝업 무시 +function ignoreNonstopPopup() { + if (typeof(Nopeople2) == 'function') { + console.log('disable Nopeople2'); + const originNopeople2 = Nopeople2; + Nopeople2 = function (intPsrm, intIdxNo, iAddInfo4, callback) { + console.log('remove h_nonstop_msg. ' + train[intIdxNo].h_nonstop_msg); + train[intIdxNo].h_nonstop_msg = ''; + return originNopeople2(intPsrm, intIdxNo, iAddInfo4, callback); + } + } +} + +//인원 확인 컨펌 무시 +function ignoreConfirmPeople() { + const origin_confirm = confirm; + confirm = function (message) { + console.log('confirm: ' + message); + if (message.indexOf('맞습니까') != -1) { + return true; + } + return origin; + } +} + +//일일 팝업 무시 +function ignoreDailyPopup() { + if (typeof(openGwangjuShuttleDialog) == 'function') { + console.log('disable openGwangjuShuttleDialog'); + openGwangjuShuttleDialog = function () {}; + } +} + +ignoreNonstopPopup(); +ignoreConfirmPeople(); +ignoreDailyPopup(); \ No newline at end of file diff --git a/inject_click.js b/inject_click.js new file mode 100644 index 0000000..5bef37b --- /dev/null +++ b/inject_click.js @@ -0,0 +1,9 @@ +console.log('inject_click.js'); + +var obj = document.getElementById('ktx-macro-click'); +//if (obj.href.includes('inqSchedule')) +// obj.click(); +if (obj) { + obj.click(); + obj.removeAttribute('id'); +} \ No newline at end of file diff --git a/inject_nonstop_popup.js b/inject_nonstop_popup.js new file mode 100644 index 0000000..00d8d00 --- /dev/null +++ b/inject_nonstop_popup.js @@ -0,0 +1,10 @@ +//nonstop 팝업 자동 닫기 +function closeNonstopPopup() { + var btn_blue_ang = document.querySelector('.btn_blue_ang'); + if (btn_blue_ang.text.indexOf('예매 계속 진행하기') != -1) { + console.log('close popup'); + setTimeout(f_close, 1000); + }; +} + +closeNonstopPopup(); \ No newline at end of file diff --git a/manifest.json b/manifest.json index b5f3c2e..1723eff 100644 --- a/manifest.json +++ b/manifest.json @@ -1,27 +1,42 @@ { - "manifest_version": 2, - "name": "KTX Macro", - "description": "KTX 매진 좌석 예약 도구", - "version": "1.4.0", - "permissions": ["https://www.letskorail.com/"], - "icons": { - "96": "icon96.png" - }, - "content_scripts": [ - { - "all_frames": true, - "js": ["content.js"], - "css": ["content.css"], - "matches": ["https://www.letskorail.com/*"], - "run_at": "document_end" - } - ], - "background": { - "page": "background.html" - }, - "web_accessible_resources": ["inject.js", "assets/tada.mp3"], - "browser_action": { - "default_title": "telegram", - "default_popup": "popup.html" - } + "manifest_version": 3, + "name": "KTX Macro", + "description": "KTX 매진 좌석 예약 도구", + "version": "1.4.0", + "permissions": ["scripting", "storage"], + "host_permissions": ["https://www.letskorail.com/"], + "icons": { + "96": "icon96.png" + }, + "content_scripts": [ + { + "all_frames": true, + "js": ["content_header.js", "reload.js"], + "matches": ["https://www.letskorail.com/*"], + "run_at": "document_start" + }, + { + "all_frames": true, + "js": ["content.js"], + "css": ["content.css"], + "matches": ["https://www.letskorail.com/*"], + "run_at": "document_end" + } + ], + "background": { + "service_worker": "background.js" + }, + "web_accessible_resources": [{ + "resources": [ + "inject.js", + "inject_click.js", + "inject_nonstop_popup.js", + "tada.mp3" + ], + "matches": ["https://www.letskorail.com/*"] + }], + "action": { + "default_title": "telegram", + "default_popup": "popup.html" + } } diff --git a/popup.js b/popup.js index 9b2ec08..bf87ed7 100644 --- a/popup.js +++ b/popup.js @@ -1,47 +1,61 @@ (() => { - const MESSAGE_RESET = '초기화 되었습니다.'; - const MESSAGE_CONNECTION_SUCCESS = '연동되었습니다.'; - const MESSAGE_CONNECTION_FAIL = '연동에 실패하였습니다.
입력하신 정보를 다시 확인해주세요.'; - - const init = () => { - document.getElementById('bot-token').value = localStorage.getItem('KTX_MACRO::bot-token'); - document.getElementById('chat-id').value = localStorage.getItem('KTX_MACRO::chat-id'); - } - - const save = () => { - const botToken = document.getElementById('bot-token').value; - const chatId = document.getElementById('chat-id').value; - - const msg = encodeURI('KTX Macro: 예약 알림이 연동되었습니다.'); - const url = `https://api.telegram.org/bot${botToken}/sendMessage?chat_id=${chatId}&text=${msg}`; - - fetch(url).then(response => { - if (response.status === 200) { - localStorage.setItem('KTX_MACRO::bot-token', botToken); - localStorage.setItem('KTX_MACRO::chat-id', chatId); - setMessage(MESSAGE_CONNECTION_SUCCESS); - } else { - setMessage(MESSAGE_CONNECTION_FAIL); - } - }).catch(err => { - setMessage(MESSAGE_CONNECTION_FAIL); - console.error(err) - }); - } - - const reset = () => { - document.getElementById('bot-token').value = ''; - document.getElementById('chat-id').value = ''; - localStorage.removeItem('KTX_MACRO::bot-token'); - localStorage.removeItem('KTX_MACRO::chat-id'); - setMessage(MESSAGE_RESET); - } - - const setMessage = message => { - document.getElementById('message').innerHTML = message; - } - - init(); - document.getElementById('button-save').addEventListener('click', save); - document.getElementById('button-reset').addEventListener('click', reset); + const MESSAGE_RESET = '초기화 되었습니다.'; + const MESSAGE_CONNECTION_SUCCESS = '연동되었습니다.'; + const MESSAGE_CONNECTION_FAIL = '연동에 실패하였습니다.
입력하신 정보를 다시 확인해주세요.'; + + const init = () => { + chrome.storage.local.get( + ['ktx-macro-bot-token', 'ktx-macro-chat-id'], + function (result) { + if (result['ktx-macro-bot-token'] && result['ktx-macro-chat-id']) { + document.getElementById('bot-token').value = result['ktx-macro-bot-token']; + document.getElementById('chat-id').value = result['ktx-macro-chat-id']; + } + } + ); + } + + const save = () => { + const botToken = document.getElementById('bot-token').value; + const chatId = document.getElementById('chat-id').value; + + const msg = encodeURI('KTX Macro: 예약 알림이 연동되었습니다.'); + const url = `https://api.telegram.org/bot${botToken}/sendMessage?chat_id=${chatId}&text=${msg}`; + + fetch(url).then(response => { + if (response.status === 200) { + chrome.storage.local.set( + { + 'ktx-macro-bot-token': botToken, + 'ktx-macro-chat-id': chatId + }, + function() { + setMessage(MESSAGE_CONNECTION_SUCCESS); + } + ); + + } else { + setMessage(MESSAGE_CONNECTION_FAIL); + } + }).catch(err => { + setMessage(MESSAGE_CONNECTION_FAIL); + console.error(err) + }); + } + + const reset = () => { + document.getElementById('bot-token').value = ''; + document.getElementById('chat-id').value = ''; + chrome.storage.local.remove('ktx-macro-bot-token'); + chrome.storage.local.remove('ktx-macro-chat-id'); + setMessage(MESSAGE_RESET); + } + + const setMessage = message => { + document.getElementById('message').innerHTML = message; + } + + init(); + document.getElementById('button-save').addEventListener('click', save); + document.getElementById('button-reset').addEventListener('click', reset); })(); \ No newline at end of file diff --git a/reload.js b/reload.js new file mode 100644 index 0000000..d24d619 --- /dev/null +++ b/reload.js @@ -0,0 +1,26 @@ +const initialize_reload = () => { + const isStarted = getTabStorageItem("macro") === "on"; + if (isStarted) { + console.log('reload in ' + (PAGE_TIMEOUT / 1000) + ' seconds'); + reloadTimeoutID = window.setTimeout( + function () { + console.log('force reload'); + location.reload(); + }, + PAGE_TIMEOUT + ); + } +}; + +(() => { + if (!location.href.startsWith(MAIN_URI) && !location.href.startsWith(FAMILY_URI)) + return; + + chrome.runtime.sendMessage( + {type: 'tabId'}, + function (result) { + tabId = result; + initialize_reload(); + } + ); +})(); \ No newline at end of file