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