const authorizedDomains = [
'dropshop.gamestores.app',
'droprust.shop'
];
const currentDomain = window.location.hostname;
const isAuthorizedDomain = authorizedDomains.includes(currentDomain);
if (!isAuthorizedDomain) {
console.error('Доступ запрещен: неавторизованный домен');
throw new Error('Доступ запрещен: неавторизованный домен');
}
const event = new CustomEvent("setCustomConfig")
window.productsGrid = 4;
window.currency = '₽'
window.defaultPaymentAmount = 10
window.zeroToFree = true
window.oldDesignDropdownProduct = true
window.sidebarStoreToRight = true
window.sidebarProfileToRight = true
window.dispatchEvent(event);
window.apperance_snow = "false";
window.telegram_link = "https://t.me/droprusttg";
window.discord_link = "https://discord.gg/VKg7NZpHth";
window.widget_discord_link = "KFYzZpTVMR";
window.server_connect_1 = "37.230.137.162:20560";
window.server_connect_2 = "2.timerust.ru";
window.promo_copy_site = "SITE";
window.promo_copy_site_enable = false
window.monitoring = { id: "39772" };
window.dispatchEvent(event);
function main() {
if (!isAuthorizedDomain) {
console.error('Доступ запрещен: неавторизованный домен');
return;
}
window.dispatchEvent(new CustomEvent("initState"));
window.dispatchEvent(new CustomEvent("initComponentsManager"));
window.dispatchEvent(new CustomEvent("initToastManager"));
window.componentsManager.addListener('HEADER', 'DID_MOUNT', () => {
const button = `
Поддержка
`;
const header = document.querySelector('.HeaderNav-module__wrapper.Header-module__nav');
header.insertAdjacentHTML('afterbegin', button);
const { player } = window.getState().player;
const social = `
`;
if (!player) {
const buttonAuth = `
`;
const headerAuth = document.querySelector('.PlayerMenu-module__loginLink');
document.querySelector('.PlayerMenu-module__loginLink').innerHTML = "Авторизация";
headerAuth.insertAdjacentHTML('beforeend', buttonAuth);
headerAuth.insertAdjacentHTML('beforebegin', social);
}
else {
const buttonProfile = ` ${player.username}
`;
const profile = document.querySelector('.PlayerMenu-module__profileLink');
const headerProfile = document.querySelector('.PlayerMenu-module__balance');
profile.insertAdjacentHTML('beforebegin', buttonProfile);
const balance = document.querySelector('.PlayerBalance-module__btn');
document.querySelector('.PlayerBalance-module__btn span').remove();
balance.insertAdjacentHTML('beforeend', `${player.balance} ${window.currency}`);
balance.insertAdjacentHTML('beforeend', ``);
balance.insertAdjacentHTML('afterend', ``);
headerProfile.insertAdjacentHTML('beforebegin', social);
console.log(player.avatar);
}
const footerDiv = ``;
const footer = document.querySelector('body');
footer.insertAdjacentHTML('beforeend', footerDiv);
footer.insertAdjacentHTML('beforeend', ``);
});
window.componentsManager.addListener('SHOP_PAGE', 'DID_MOUNT', () => {
const observer = new MutationObserver(() => {
const modals = document.querySelectorAll("[data-modalproductid]");
modals.forEach(modal => {
const footer = modal.querySelector(".ItemContent-module__footer.boxFooter");
if (!footer) return;
if (footer.querySelector(".add-to-cart-button")) return;
const btn = document.createElement("button");
btn.innerText = "В корзину";
btn.className = "add-to-cart-button";
btn.style.cssText = "padding: 8px 10px; background: #31b112; font-weight: 400; border-radius: 8px; color: white; border: none; cursor: pointer; margin-left: 5px;";
btn.onclick = () => {
const title = modal.querySelector(".ProductModal-module__header")?.textContent?.trim();
const priceInput = modal.querySelector("#totalAmount");
const price = parseFloat(priceInput?.value || '0');
const productId = parseInt(modal.dataset.modalproductid);
const image = modal.querySelector(".productModalImg")?.src;
const productCard = document.querySelector(`[data-productid="${productId}"]`);
const discountElem = productCard?.querySelector(".Product-module__discount");
const discount = discountElem ? discountElem.textContent.trim() : '0%';
const serverElem = document.querySelector(".Servers-module__server.Servers-module__active");
const serverId = parseInt(39772);
const quantity = parseInt(modal.querySelector("#buyCount")?.value || '1') || 1;
if (!title || price <= 0 || !productId || !serverId || !image) {
window.addToast(true, `Не удалось получить данные товара.`);
return;
}
addToCart(title, price, productId, serverId, image, discount, quantity);
};
footer.appendChild(btn);
});
});
observer.observe(document.body, { childList: true, subtree: true });
});
window.buy_cart = function () {
const { player } = window.getState().player;
const cart = JSON.parse(localStorage.getItem("cart")) || [];
let totalCost = 0;
cart.forEach(item => {
totalCost += item.price * (item.quantity / item.buyCount);
});
console.log(player.balance);
if (!player) {
window.addToast(true, "Вы не авторизованы!");
} else if (player.balance >= totalCost) {
processPurchase();
} else {
window.addToast(true, "Недостаточно средств на балансе!");
}
};
async function processPurchase() {
const cart = JSON.parse(localStorage.getItem("cart")) || [];
if (cart.length === 0) {
window.addToast(true, "Корзина пуста!");
return;
}
const state = window.getState ? window.getState() : {};
const token = state.player?.token || null;
try {
const purchases = cart.map(item => ({
productId: item.productId,
amount: item.quantity,
serverId: item.serverId
}));
let allSuccessful = true;
for (const purchase of purchases) {
const response = await fetch(`https://${window.location.host}/api/v1/products.purchase`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(token && { 'Authorization': `Bearer ${token}` })
},
body: JSON.stringify(purchase),
credentials: 'include'
});
const result = await response.json();
if (result.result !== "success") {
allSuccessful = false;
window.addToast(true, `Ошибка при покупке товара ID: ${purchase.productId}. ${result.message || "Попробуйте снова."}`);
}
}
if (allSuccessful) {
localStorage.removeItem("cart");
updateCart();
updateCartCounter();
window.addToast(false, "Все товары успешно куплены!");
}
} catch (error) {
window.addToast(true, "Ошибка сервера или сети.");
}
}
window.componentsManager.load();
}
if(window.isAppReady) {
main();
} else {
window.addEventListener('appReady', () => {
main();
});
}
function addToCart(name, price, productId, serverId, image, discount, quantity) {
const cart = JSON.parse(localStorage.getItem("cart")) || [];
const state = window.getState ? window.getState() : {};
const player = state.player?.player;
if (!player) {
window.addToast(true, `Вы не авторизованы!`);
return;
}
const existing = cart.find(item => item.productId === productId && item.serverId === serverId);
if (existing) {
existing.quantity += quantity;
} else {
const newItem = {
name,
price,
productId,
serverId,
image,
discount,
quantity,
buyCount: quantity
};
cart.push(newItem);
}
localStorage.setItem("cart", JSON.stringify(cart));
window.addToast(false, `Товар "${name}" добавлен!`);
updateCartCounter();
}
function updateCart() {
const cartItems = JSON.parse(localStorage.getItem("cart")) || [];
let cartModal = document.querySelector("#cartModal");
const wasActive = cartModal && cartModal.classList.contains("active");
if (!cartModal || !cartModal.querySelector("#cartItemsContainer")) {
cartModal = loadCartModal();
if (!cartModal) {
window.addToast(true, "Не удалось загрузить корзину");
return;
}
}
const itemsContainer = cartModal.querySelector("#cartItemsContainer");
const countElement = cartModal.querySelector("#CountCart");
let emptyMessage = cartModal.querySelector(".errordiv");
const checkoutContainer = cartModal.querySelector("#checkoutContainer");
const totalContainer = cartModal.querySelector("#cart__content__sum__count");
if (!itemsContainer || !countElement || !checkoutContainer || !totalContainer) {
window.addToast(true, "Не удалось загрузить корзину", 'error');
return;
}
if (!emptyMessage) {
emptyMessage = document.createElement("div");
emptyMessage.className = "errordiv";
emptyMessage.style.cssText = `display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-top: 20px; margin-bottom: 25px;`;
emptyMessage.innerHTML = `Корзина пуста. Самое время что-то купить!
`;
itemsContainer.appendChild(emptyMessage);
}
itemsContainer.innerHTML = '';
itemsContainer.appendChild(emptyMessage);
const totalItems = cartItems.length;
const totalPrice = cartItems.reduce((sum, item) => {return sum + item.price * (item.quantity / item.buyCount);}, 0).toFixed(2);
countElement.textContent = totalItems;
totalContainer.innerHTML = `Товаров: ${totalItems} поз.
Итого: ${totalPrice} руб.
`;
emptyMessage.style.display = totalItems === 0 ? 'flex' : 'none';
checkoutContainer.style.display = totalItems === 0 ? 'none' : 'block';
cartItems.forEach((item, index) => {
const itemBlock = document.createElement('div');
itemBlock.style.cssText = `display: flex; align-items: center; gap: 10px; padding: 10px; background: rgba(255, 255, 255, 0.02); border-radius: 8px; margin-bottom: 2px;`;
const itemImage = document.createElement('img');
itemImage.src = item.image || '';
itemImage.style.cssText = `width: 50px; height: 50px; object-fit: cover; border-radius: 4px;`;
const itemInfo = document.createElement('div');
itemInfo.style.flexGrow = '1';
itemInfo.innerHTML = `${item.name || "Неизвестный"}
Цена: ${item.price} руб. за ${item.buyCount} шт.
${item.discount && item.discount !== '0%' ? `Скидка: ${item.discount}
` : ''}`;
const quantityControls = document.createElement('div');
quantityControls.style.cssText = `display: flex; align-items: center; gap: 5px;`;
const minusBtn = document.createElement('button');
minusBtn.textContent = '-';
minusBtn.style.cssText = `padding: 5px 10px; background: rgba(255, 255, 255, 0.1); color: #fff; border: none; border-radius: 8px; cursor: pointer;`;
const quantityInput = document.createElement("input");
quantityInput.type = 'number';
quantityInput.min = item.buyCount || 1;
quantityInput.value = Math.floor(item.quantity / (item.buyCount || 1));
quantityInput.style.cssText = `width: 60px; padding: 5px; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; text-align: center;`;
const plusBtn = document.createElement('button');
plusBtn.textContent = '+';
plusBtn.style.cssText = `padding: 5px 10px; background: rgb(65 147 29); color: #fff; border: none; border-radius: 8px; cursor: pointer;`;
quantityInput.addEventListener("input", () => {
let newQuantity = parseInt(quantityInput.value) || 1;
if (newQuantity < 1) newQuantity = 1;
newQuantity *= item.buyCount;
quantityInput.value = newQuantity / item.buyCount;
item.quantity = newQuantity;
localStorage.setItem('cart', JSON.stringify(cartItems));
updateCart();
updateCartCounter();
});
minusBtn.addEventListener('click', () => {
changeQuantity(item.productId, item.serverId, -1);
});
plusBtn.addEventListener('click', () => {
changeQuantity(item.productId, item.serverId, 1);
});
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Удалить';
deleteBtn.style.cssText = `padding: 5px 10px; background: rgb(170 53 53); color: #fff; border: none; border-radius: 8px; cursor: pointer;`;
deleteBtn.addEventListener('click', () => {
cartItems.splice(index, 1);
localStorage.setItem("cart", JSON.stringify(cartItems));
window.addToast(false, `Товар "${item.name || "Неизвестный"}" удален!`);
updateCart();
updateCartCounter();
});
quantityControls.appendChild(minusBtn);
quantityControls.appendChild(quantityInput);
quantityControls.appendChild(plusBtn);
itemBlock.appendChild(itemImage);
itemBlock.appendChild(itemInfo);
itemBlock.appendChild(quantityControls);
itemBlock.appendChild(deleteBtn);
itemsContainer.appendChild(itemBlock);
});
if (wasActive) {
cartModal.classList.add("active");
}
}
function changeQuantity(productId, serverId, deltaPacks) {
const cart = JSON.parse(localStorage.getItem("cart")) || [];
const item = cart.find(p => p.productId === productId && p.serverId === serverId);
if (!item) return;
const packSize = item.buyCount || 1;
item.quantity += deltaPacks * packSize;
if (item.quantity <= 0) {
cart.splice(cart.indexOf(item), 1);
}
localStorage.setItem("cart", JSON.stringify(cart));
updateCart();
updateCartCounter();
}
function loadCartModal() {
let cartModal = document.querySelector("#cartModal");
if (!cartModal) {
cartModal = document.createElement("div");
cartModal.id = "cartModal";
cartModal.className = "customModalWrapper";
cartModal.innerHTML = `
Корзина пуста. Самое время что-то купить!
`;
document.body.appendChild(cartModal);
}
const elements = {
cartItemsContainer: cartModal.querySelector("#cartItemsContainer"),
countCart: cartModal.querySelector("#CountCart"),
errorDiv: cartModal.querySelector(".errordiv"),
checkoutContainer: cartModal.querySelector("#checkoutContainer"),
cartSumCount: cartModal.querySelector("#cart__content__sum__count")
};
const allElementsPresent = Object.values(elements).every(el => el);
if (!allElementsPresent) {
cartModal.remove();
window.addToast(true, "Не удалось загрузить корзину");
return null;
}
cartModal.querySelector(".product_kit_modal_close").addEventListener('click', () => {
cartModal.classList.remove("active");
});
return cartModal;
}
function openCart() {
const cartBtn = document.querySelector("#cartModal") || loadCartModal();
if (cartBtn) {
cartBtn.classList.add("active");
updateCart();
} else {
window.addToast(true, "Не удалось открыть корзину");
}
}
function updateCartCounter() {
const cartItems = JSON.parse(localStorage.getItem("cart")) || [];
const itemCount = cartItems.length;
const cartButton = document.querySelector(".cart-button");
if (cartButton) {
const existingCounter = cartButton.querySelector(".cart-counter");
if (existingCounter) {
existingCounter.remove();
}
if (itemCount > 0) {
const counter = document.createElement("span");
counter.className = "cart-counter";
counter.style.cssText = `position: absolute; top: -8px; right: -8px; background: #b63030; color: white; border-radius: 50%; width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; font-size: 12px;`;
counter.textContent = itemCount;
cartButton.appendChild(counter);
}
}
}
function update() {
if (document.readyState === "complete" || document.readyState === "interactive") {
updateCartCounter();
} else {
document.addEventListener("DOMContentLoaded", () => {
updateCartCounter();
});
}
window.addEventListener("storage", check => {
if (check.key === "cart") {
updateCart();
updateCartCounter();
}
});
}
window.onload = () => {
setTimeout(() => { update() }, 100);
};
function scrollTop() {
const scrollTopBtn = document.createElement("button");
scrollTopBtn.id = "scrollTopBtn";
scrollTopBtn.innerHTML = `Наверх`;
document.body.appendChild(scrollTopBtn);
function scrollToTop() {
window.scrollTo({ top: 0, behavior: "smooth" });
}
function toggleVisibility() {
if (window.scrollY > 100) {
scrollTopBtn.classList.add("visible");
} else {
scrollTopBtn.classList.remove("visible");
}
}
scrollTopBtn.addEventListener("click", scrollToTop);
window.addEventListener("scroll", toggleVisibility);
toggleVisibility();
}
if (window.isAppReady) {
scrollTop();
} else {
window.addEventListener('appReady', () => {
scrollTop();
});
}
function PayBonus() {
if (!isAuthorizedDomain) {
console.error('Доступ запрещен: неавторизованный домен');
return;
}
window.dispatchEvent(new CustomEvent("initState"));
window.dispatchEvent(new CustomEvent("initComponentsManager"));
function renderCustomModal() {
const originalModal = document.querySelector(
".ModalLayout-module__modal.PlayerBalance-module__modal"
);
if (!originalModal) return;
originalModal.outerHTML = `
Если вы наблюдаете проблемы с пополнением баланса — обратитесь через Discord к администратору
alone_sempaiили в Telegram
@ASSempai
Бонус к депозиту
500 ₽
1000 ₽
1500 ₽
2000 ₽
К зачислению
500.00 ₽
+75.00 ₽
`;
initPayFormHandlers();
}
const checkInterval = setInterval(() => {
const modal = document.querySelector(
".ModalLayout-module__modal.PlayerBalance-module__modal"
);
if (modal) {
renderCustomModal();
clearInterval(checkInterval);
}
}, 100);
window.componentsManager.addListener("BALANCE_MODAL", "DID_MOUNT", renderCustomModal);
window.componentsManager.load();
}
function initPayFormHandlers() {
const input = document.querySelector(".pay-fieldset input[type='number']");
const percentButtons = document.querySelectorAll(".pay-start__bonus-list--item");
const amountButtons = document.querySelectorAll(".pay-start__bonus-percents--item");
const sumElement = document.querySelector(".pay-start__bonus-finish--sum");
const bonusElement = document.querySelector(".pay-start__bonus-finish--bonus");
const payButton = document.querySelector(".pay-start__buttons-card");
if (!input || !percentButtons.length || !amountButtons.length || !sumElement || !bonusElement || !payButton) return;
const thresholds = [500, 1000, 1500, 2000];
function updateUI(amount) {
percentButtons.forEach(btn => btn.classList.remove("active"));
amountButtons.forEach(btn => btn.classList.remove("active"));
thresholds.forEach((limit, idx) => {
if (input.value == limit) {
percentButtons[idx]?.classList.add("active");
}
if (amount >= limit) {
amountButtons[idx]?.classList.add("active");
}
});
const percent = getBonusPercent(amount);
const bonus = amount * percent / 100;
sumElement.textContent = `${amount.toFixed(2)} ₽`;
bonusElement.textContent = `+${bonus.toFixed(2)} ₽`;
}
updateUI(parseFloat(input.value) || 0);
amountButtons.forEach((btn, idx) => {
btn.addEventListener("click", () => {
const value = thresholds[idx];
input.value = value;
updateUI(value);
});
});
percentButtons.forEach((btn, idx) => {
btn.addEventListener("click", () => {
const value = thresholds[idx];
input.value = value;
updateUI(value);
});
});
input.addEventListener("input", () => {
const amount = parseFloat(input.value) || 0;
updateUI(amount);
});
payButton.addEventListener("click", handlePayButtonClick);
}
function handlePayButtonClick() {
const input = document.querySelector(".pay-fieldset input[type='number']");
const amount = parseFloat(input.value) || 0;
if (amount < 10) return alert("Минимальная сумма для пополнения: 10 ₽");
const url = `https://${window.location.host}/api/v1/player.donate?amount=${amount.toFixed(2)}`;
try {
window.location.href = url;
} catch (err) {
console.error("PayBonus: ошибка перехода:", err);
alert("Не удалось перейти на страницу оплаты. Попробуйте позже.");
}
}
function getBonusPercent(amount) {
if (amount >= 2000) return 40;
if (amount >= 1500) return 30;
if (amount >= 1000) return 20;
if (amount >= 500) return 15;
return 0;
}
if (window.isAppReady) {
PayBonus();
} else {
window.addEventListener('appReady', () => {
PayBonus();
});
}
function TMMonitoring() {
if (!isAuthorizedDomain) {
console.error('Доступ запрещен: неавторизованный домен');
return;
}
window.dispatchEvent(new CustomEvent('initState'));
window.dispatchEvent(new CustomEvent('initComponentsManager'));
const previousPlayerCounts = {};
function updateMonitoringData() {
if (!window.monitoring || !window.monitoring.id) return;
const serverIds = window.monitoring.id.split(',').map(id => Number(id.trim()));
fetch(`https://${window.location.host}/api/v1/widgets.monitoring`)
.then(response => response.json())
.then(data => {
setTimeout(() => {
if (data.result === 'success' && data.data?.servers) {
let totalOnline = 0;
serverIds.forEach(serverId => {
const serverData = data.data.servers.find(server => server.id === serverId);
if (!serverData) return;
const players = serverData.players || 0;
const maxPlayers = serverData.playersMax || 0;
const joiningPlayers = serverData.playersJoining || 0;
totalOnline += players;
const serverElement = document.getElementById(`server-${serverId}`);
const progressElement = document.getElementById(`progress-${serverId}`);
if (serverElement) {
const prevPlayers = previousPlayerCounts[serverId] || 0;
let animationClass = '';
if (prevPlayers < players) {
animationClass = 'animate-up';
} else if (prevPlayers > players) {
animationClass = 'animate-down';
}
serverElement.innerHTML = `
${players} из
${maxPlayers} игроков
Подключаются - ${joiningPlayers}
`;
if (animationClass) {
setTimeout(() => {
const playerSpan = serverElement.querySelector('.server-players');
if (playerSpan) playerSpan.classList.remove(animationClass);
}, 300);
}
previousPlayerCounts[serverId] = players;
}
if (progressElement) {
const progressPercent = maxPlayers > 0 ? Math.min((players / maxPlayers) * 100, 100) : 0;
progressElement.style.width = `${progressPercent}%`;
}
});
const totalOnlineElement = document.getElementById('mon_online_players_total');
if (totalOnlineElement) {
const prevTotal = previousPlayerCounts.totalOnline || 0;
let totalAnimation = '';
if (prevTotal < totalOnline) {
totalAnimation = 'animate-up';
} else if (prevTotal > totalOnline) {
totalAnimation = 'animate-down';
}
totalOnlineElement.textContent = totalOnline;
totalOnlineElement.classList.add(totalAnimation);
if (totalAnimation) {
setTimeout(() => {
totalOnlineElement.classList.remove(totalAnimation);
}, 300);
}
previousPlayerCounts.totalOnline = totalOnline;
}
}
}, 100);
});
}
function tryInitMonitoring() {
if (!window.monitoring || !window.monitoring.id) return;
const serverIds = window.monitoring.id.split(',').map(id => Number(id.trim()));
const allElementsReady = serverIds.every(
id => document.getElementById(`server-${id}`) && document.getElementById(`progress-${id}`)
);
if (allElementsReady) {
updateMonitoringData();
setInterval(updateMonitoringData, 10000);
clearInterval(initialCheckInterval);
}
}
document.addEventListener('DOMContentLoaded', () => {
tryInitMonitoring();
});
const initialCheckInterval = setInterval(tryInitMonitoring, 100);
if (window.componentsManager) {
['SHOP_PAGE', 'SUPPORT_PAGE', 'CUSTOM_PAGE'].forEach(page => {
window.componentsManager.addListener(page, 'DID_MOUNT', () => {
updateMonitoringData();
setInterval(updateMonitoringData, 10000);
clearInterval(initialCheckInterval);
});
});
if (typeof window.componentsManager.load === 'function') {
window.componentsManager.load();
}
}
}
if (window.isAppReady) {
TMMonitoring();
} else {
window.addEventListener("appReady", () => {
TMMonitoring();
});
}
function copyConnect(buttonElement) {
const serverId = buttonElement.getAttribute("data");
const connectCommand = "connect " + window["server_" + serverId];
if (connectCommand && connectCommand !== "connect undefined") {
navigator.clipboard.writeText(connectCommand).then(() => {
window.dispatchEvent(new CustomEvent("initToastManager"));
window.addToast(false, "Коннект скопирован. Приятной игры!");
}).catch(error => {
console.error("Ошибка при копировании коннекта:", error);
});
} else {
console.error("Ошибка: не найден серверный адрес для", serverId);
}
}