|
const DCCon = (() => { |
|
const MAX_RETRY_ATTEMPT = 10; |
|
const domParser = new DOMParser(); |
|
function sleep(ms) { |
|
return new Promise(resolve => setTimeout(resolve, ms)); |
|
}; |
|
function doAjax(data, url, type = 'POST') { |
|
return new Promise((success, error) => { |
|
$.ajax({ data: { ci_t: get_cookie('ci_c'), ...data }, type, url, cache: false, success, error }); |
|
}); |
|
} |
|
async function getDetail(package_idx) { |
|
try { |
|
return await doAjax({ package_idx, code: '' }, '/index/package_detail'); |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
async function getID(name) { |
|
const searchHTML = await doAjax(undefined, '/hot/1/title/' + encodeURIComponent(name), 'GET'); |
|
const doc = domParser.parseFromString(searchHTML, "text/html"); |
|
for (let li of doc.querySelectorAll('li.div_package')) { |
|
let package_idx = li.getAttribute('package_idx'); |
|
let title = li.getElementsByClassName('dcon_name')[0]?.textContent; |
|
if (!name.startsWith(title)) continue; |
|
const detail = await getDetail(package_idx); |
|
if (!detail) continue; |
|
const parsed = JSON.parse(detail); |
|
if (parsed?.info?.title === name) { |
|
return parsed.info.package_idx; |
|
} |
|
} |
|
return null; |
|
} |
|
async function addByID(package_idx) { |
|
let attempt = MAX_RETRY_ATTEMPT; |
|
let lastError; |
|
while (attempt--) { |
|
try { |
|
return await doAjax({ package_idx }, '/index/buy'); |
|
} catch (e) { |
|
lastError = e; |
|
await sleep(1000); |
|
} |
|
} |
|
console.error(lastError); |
|
throw new Error("디시콘을 구매할 수 없습니다.") |
|
} |
|
function setOrder(arr_idx) { |
|
return doAjax({ arr_idx, 'list_opt': 'use' }, '/my/save_setting'); |
|
} |
|
async function buyBulkByName(order) { |
|
const arr_idx = []; |
|
const promises = order.map(async (name, i) => { |
|
var package_idx = await getID(name); |
|
if (!package_idx) throw new Error(`디시콘을 찾을 수 없습니다.`); |
|
arr_idx[i] = package_idx; |
|
await addByID(package_idx); |
|
console.log(name + " 구매 완료"); |
|
}) |
|
const op = await Promise.allSettled(promises); |
|
for (let i = 0, l = op.length; i < l; i++) { |
|
if (op[i].status === "rejected") { |
|
console.error(order[i] + " " + op[i].reason); |
|
} |
|
} |
|
return arr_idx; |
|
} |
|
|
|
async function buyAndSortBulkByName(order) { |
|
const arr_idx = await buyBulkByName(order); |
|
const sortApiResponse = await setOrder(arr_idx); |
|
if (sortApiResponse !== 'ok') { |
|
console.error(sortApiResponse); |
|
} |
|
} |
|
function wrap(fn) { |
|
return async function(...args) { |
|
let now = performance.now(); |
|
await fn(...args); |
|
console.log("완료, " + (performance.now() -now) + "ms 소요됨"); |
|
} |
|
} |
|
return { |
|
buyAndSort: wrap(buyAndSortBulkByName), |
|
buy: wrap(buyBulkByName) |
|
} |
|
})(); |