(() => {
const getStoveCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
return parts.length === 2 ? parts.pop().split(";").shift() : null;
};
const formatCurrency = (amount) => {
const numStr = String(amount);
const units = ["원", "천원", "만원", "십만원", "백만원", "천만원", "억원", "십억원", "백억원", "천억원"];
if (numStr.length <= 3) {
return numStr + units[0];
}
let result = "";
let remainder = amount;
if (numStr.length > 8) {
const billions = Math.floor(remainder / 100000000);
if (billions > 0) {
result += billions + "억 ";
remainder = remainder % 100000000;
}
}
if (numStr.length > 4) {
const millions = Math.floor(remainder / 10000);
if (millions > 0) {
result += millions + "만 ";
remainder = remainder % 10000;
}
}
if (remainder > 0) {
const thousands = Math.floor(remainder / 1000);
if (thousands > 0) {
result += thousands + "천 ";
remainder = remainder % 1000;
}
}
if (remainder > 0) {
result += remainder + " ";
}
return result + "원";
};
const loginUserToken = getStoveCookie("SUAT");
fetch("https://api.onstove.com/game/v2.0/member/logs", {
method: "GET",
headers: {
Authorization: `Bearer ${loginUserToken}`,
"Content-Type": "application/json",
},
})
.then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("로그인 정보가 없습니다.");
}
})
.then((data) => {
const lostArkGame = data.value.find((game) => game.game_name === "LOST ARK");
const playTimeMinutes = lostArkGame.play_time;
const totalHours = Math.floor(playTimeMinutes / 60);
const remainingMinutes = playTimeMinutes % 60;
const totalDays = Math.floor(totalHours / 24);
const remainingHours = totalHours % 24;
const totalMonths = Math.floor(totalDays / 30);
const totalYears = Math.floor(totalMonths / 12);
const remainingMonths = totalMonths % 12;
let lastNum = 1;
let sum = 0;
let regexp = /B(?=(d{3})+(?!d))/g;
let chargeDateList = [];
let chargeWayList = [];
let cashList = [];
let paymentMethods = {};
let paymentCount = 0;
let text = "";
let years = [2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026];
function getCashData(year, page) {
return new Promise((resolve, reject) => {
$.ajax({
url: "/Cash/GetChargeList",
type: "GET",
data: { Page: page, StartDate: year + ".01.01", EndDate: year + ".12.31" },
dataType: "html",
success: resolve,
error: reject,
});
});
}
function getPageCount(year) {
return new Promise((resolve, reject) => {
$.ajax({
url: "/Cash/GetChargeList",
type: "GET",
data: { Page: 1, StartDate: year + ".01.01", EndDate: year + ".12.31" },
dataType: "html",
success: resolve,
error: reject,
});
});
}
async function processAllYears() {
for (let j = 0; j < years.length; j++) {
try {
const year = years[j];
const pageData = await getPageCount(year);
const pageNumElement = $(pageData).find(".pagination__last")[0];
if (pageNumElement && pageNumElement.getAttribute("onClick")) {
lastNum = pageNumElement.getAttribute("onClick").replace(/[^0-9]/g, "");
} else {
lastNum = 1;
}
for (let i = 1; i <= lastNum; i++) {
const data = await getCashData(year, i);
$(data)
.find("td.list__price")
.each(function () {
cashList.push(
$(this)
.text()
.replace(/[^0-9]/g, "")
);
paymentCount++;
});
$(data)
.find("td.list__date")
.each(function () {
chargeDateList.push($(this).text());
});
$(data)
.find("td.list__way")
.each(function () {
const method = $(this).text();
chargeWayList.push(method);
if (!paymentMethods[method]) {
paymentMethods[method] = 0;
}
const index = chargeWayList.length - 1;
if (index < cashList.length) {
paymentMethods[method] += Number(cashList[index]);
}
});
}
} catch (error) {
console.error(`Error processing year ${years[j]}:`, error);
}
}
cashList.forEach(function (cash) {
sum += Number(cash);
});
const formattedSum = formatCurrency(sum);
let paymentMethodsAnalysis =
"<h3 style='color: #333; margin: 20px 0 12px 0; font-size: 18px; font-weight: 600;'>결제 방법별 분석</h3><ul style='list-style-type: none; padding: 0; margin: 8px 0;'>";
for (const [method, amount] of Object.entries(paymentMethods)) {
if (amount > 0) {
paymentMethodsAnalysis += "<li><strong>" + method + ":</strong> " + formatCurrency(amount) + "</li>";
}
}
paymentMethodsAnalysis += "</ul>";
const messageHTML = `
<div style="margin-bottom: 20px;">
<h3 style="color: #333; margin: 0 0 12px 0; font-size: 18px; font-weight: 600;">로스트아크 플레이 시간</h3>
<p style="margin: 8px 0; font-size: 16px;">총 플레이 시간: ${totalHours}시간 ${remainingMinutes}분</p>
<p style="margin: 8px 0; font-size: 16px;">총 일 수: ${totalDays}일 ${remainingHours}시간</p>
<p style="margin: 8px 0; font-size: 16px;">총 개월 수: ${totalMonths}개월</p>
<p style="margin: 8px 0; font-size: 16px;">총 년 수: ${totalYears}년 ${remainingMonths}개월</p>
</div>
<div>
<h3 style="color: #333; margin: 0 0 12px 0; font-size: 18px; font-weight: 600;">로스트아크 결제 정보</h3>
<p style="margin: 8px 0; font-size: 16px; font-weight: 500;">총 결제 금액: ${formattedSum}</p>
<p style="margin: 8px 0; font-size: 16px;">총 결제 횟수: ${paymentCount}회</p>
${paymentMethodsAnalysis}
</div>
`;
const message =
`로스트아크 플레이 시간:
총 플레이 시간: ${totalHours}시간 ${remainingMinutes}분
총 일 수: ${totalDays}일 ${remainingHours}시간
총 개월 수: ${totalMonths}개월
총 년 수: ${totalYears}년 ${remainingMonths}개월
로스트아크 결제 정보:
총 결제 금액: ${formattedSum}
총 결제 횟수: ${paymentCount}회
결제 방법별 분석:
` +
Object.entries(paymentMethods)
.filter(([_, amount]) => amount > 0)
.map(([method, amount]) => method + ": " + formatCurrency(amount))
.join("n");
const tempTextArea = document.createElement("textarea");
tempTextArea.value = message;
tempTextArea.style.position = "fixed";
tempTextArea.style.left = "0";
tempTextArea.style.top = "0";
tempTextArea.style.opacity = "0";
document.body.appendChild(tempTextArea);
tempTextArea.select();
document.execCommand("copy");
document.body.removeChild(tempTextArea);
const modal = document.createElement("div");
modal.style.position = "fixed";
modal.style.left = "0";
modal.style.top = "0";
modal.style.width = "100%";
modal.style.height = "100%";
modal.style.backgroundColor = "rgba(0,0,0,0.7)";
modal.style.zIndex = "10000";
modal.style.display = "flex";
modal.style.justifyContent = "center";
modal.style.alignItems = "center";
const modalContent = document.createElement("div");
modalContent.style.backgroundColor = "white";
modalContent.style.padding = "25px";
modalContent.style.borderRadius = "12px";
modalContent.style.width = "550px";
modalContent.style.maxWidth = "85%";
modalContent.style.maxHeight = "85%";
modalContent.style.overflowY = "auto";
modalContent.style.fontFamily = "맑은 고딕, 돋움, sans-serif";
modalContent.style.fontSize = "16px";
modalContent.style.lineHeight = "1.5";
modalContent.style.color = "#333";
modalContent.style.boxShadow = "0 5px 20px rgba(0,0,0,0.2)";
const modalTitle = document.createElement("h2");
modalTitle.textContent = "로스트아크 통계";
modalTitle.style.borderBottom = "1px solid #eee";
modalTitle.style.paddingBottom = "15px";
modalTitle.style.marginTop = "0";
modalTitle.style.marginBottom = "20px";
modalTitle.style.fontSize = "22px";
modalTitle.style.fontWeight = "600";
modalTitle.style.color = "#222";
modalTitle.style.textAlign = "center";
const modalBody = document.createElement("div");
modalBody.innerHTML = messageHTML;
modalBody.style.margin = "0";
modalBody.style.lineHeight = "1.6";
const closeButton = document.createElement("button");
closeButton.textContent = "닫기";
closeButton.style.padding = "10px 24px";
closeButton.style.backgroundColor = "#4CAF50";
closeButton.style.color = "white";
closeButton.style.border = "none";
closeButton.style.borderRadius = "6px";
closeButton.style.cursor = "pointer";
closeButton.style.float = "right";
closeButton.style.marginTop = "20px";
closeButton.style.fontSize = "16px";
closeButton.style.fontWeight = "500";
closeButton.style.transition = "background-color 0.2s";
closeButton.onmouseover = function () {
this.style.backgroundColor = "#3e8e41";
};
closeButton.onmouseout = function () {
this.style.backgroundColor = "#4CAF50";
};
closeButton.onclick = function () {
document.body.removeChild(modal);
};
modalContent.appendChild(modalTitle);
modalContent.appendChild(modalBody);
modalContent.appendChild(closeButton);
modal.appendChild(modalContent);
document.body.appendChild(modal);
console.log("통계가 복사되었습니다. 필요시 붙여넣기 하시면 됩니다.");
}
processAllYears();
})
.catch((error) => {
console.error(error);
alert("에러가 발생했습니다: " + error.message);
});
})();