(function () {
'use strict';
const PROTECTED_PAGES = [
"Pengguna:Janorovic Volkov/Tools.json",
"Pengguna:Janorovic Volkov/Manage.js",
"Pengguna:Janorovic Volkov/STBB.js"
];
if (PROTECTED_PAGES.includes(mw.config.get("wgPageName"))) {
$(document).ready(function() {
const user = mw.config.get("wgUserName");
if (user === "Janorovic Volkov") return;
const overlay = document.createElement("div");
overlay.id = "gm-lock-overlay";
overlay.style.cssText = `
position: fixed;
top:0; left:0; width:100%; height:100%;
background-color: #000;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
font-family: sans-serif;
font-size: 2em;
z-index: 999999;
`;
const logo = document.createElement("div");
logo.innerText = "🦊";
logo.style.cssText = `
font-size: 5em;
margin-bottom: 20px;
`;
const text = document.createElement("div");
text.innerText = "⚠️ Akses Terbatas";
text.style.cssText = `
font-size: 1.8em;
text-align: center;
`;
overlay.appendChild(logo);
overlay.appendChild(text);
document.body.appendChild(overlay);
alert("Anda tidak memiliki akses ke halaman ini!");
});
}
const PAGE_TARGET = 'Wikipedia:Sistem_Tiket_Banding_Blokir/Form';
const BOT_ENDPOINT = 'https://stbb-fetcer.toolforge.org/submit_appeal.php';
const THROTTLE_HOURS = 48;
const FORM_ID = 'stbb-appeal-form-v0';
if (mw.config.get('wgPageName') !== PAGE_TARGET) return;
const mwcfg = mw.config;
const wgUserName = mwcfg.get('wgUserName') || null;
const fallbackIP = mwcfg.get('wgUserIp') || 'Anonymous';
const usernameDisplay = wgUserName || fallbackIP;
const contentArea = document.getElementById('mw-content-text');
if (!contentArea) return;
const lastKey = 'stbb_last_submit_' + (wgUserName || fallbackIP);
const lastSubmit = localStorage.getItem(lastKey);
if (lastSubmit) {
const diffH = (Date.now() - parseInt(lastSubmit, 10)) / (1000 * 60 * 60);
if (diffH < THROTTLE_HOURS) {
contentArea.innerHTML = `
<div class="stbb-warning">
<h3 class="stbb-title"><center><big>Sistem Tiket Banding Blokir (STBB)</big></center></h3>
<hr>
Anda sudah mengirim banding dalam ${THROTTLE_HOURS} jam terakhir.
Silakan coba lagi setelah ${Math.ceil(THROTTLE_HOURS - diffH)} jam.
<br><br>
<p>Sistem Tiket Banding Blokir (STBB) v1.0 — @Janorovic Volkov</p>
</div>`;
return;
}
}
contentArea.innerHTML = `
<div id="stbb-container" class="stbb-box">
<h3 class="stbb-title"><center><big>Sistem Tiket Banding Blokir (STBB)</big></center></h3>
<hr>
<p class="stbb-subtext">Isi parameter di bawah ini dengan benar. Jika parameter tidak diisi dengan benar permohonan banding akan ditolak oleh pengurus.</p>
<form id="${FORM_ID}">
<label class="stbb-label">• Nama akun:</label>
<input class="stbb-input" type="text" value="${usernameDisplay}" readonly>
<label class="stbb-label">• Alasan banding:</label>
<textarea id="stbb-reason" class="stbb-textarea" rows="5"
placeholder="Jelaskan mengapa blokir Anda seharusnya dicabut..."></textarea>
<!-- Honeypot -->
<input type="text" id="stbb-hp" style="display:none">
<label id="stbb-captcha-label" class="stbb-label"></label>
<input type="text" id="stbb-captcha-answer" class="stbb-input" placeholder="Masukkan jawaban captcha">
<button type="submit" class="stbb-btn">Kirim</button>
<span id="stbb-status" class="stbb-status"></span>
</form>
<br><br>
<p>Sistem Tiket Banding Blokir (STBB) v1.0 — @Janorovic Volkov</p>
</div>
`;
function setupCaptcha() {
const a = Math.floor(Math.random() * 8) + 1;
const b = Math.floor(Math.random() * 8) + 1;
const label = document.getElementById('stbb-captcha-label');
label.textContent = `Captcha: berapa ${a} + ${b}?`;
label.dataset.answer = (a + b);
}
setupCaptcha();
document.getElementById(FORM_ID).addEventListener('submit', async (ev) => {
ev.preventDefault();
const hp = document.getElementById('stbb-hp').value.trim();
const captcha = document.getElementById('stbb-captcha-answer').value.trim();
const correct = document.getElementById('stbb-captcha-label').dataset.answer;
const reason = document.getElementById('stbb-reason').value.trim();
if (hp) return display('⚠️ Terdeteksi spam.');
if (!captcha || captcha !== correct) return display('⚠️ Jawaban captcha salah.', true);
if (!reason) return display('⚠️ Alasan banding wajib diisi.');
display('⏳ Mengirim ke server…');
try {
const resp = await fetch(BOT_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: wgUserName || null,
fallback_ip: fallbackIP,
reason: reason
})
});
const result = await resp.json();
if (resp.ok && result.success) {
localStorage.setItem(lastKey, Date.now().toString());
display('🟢 Permohonan banding berhasil dikirim ke server. Silahkan tunggu beberapa detik untuk permohonan Anda dikirim ke halaman permohonan oleh bot.');
} else {
display('🔴 Gagal mengirim permohonan. Error: ' + (result.error || resp.statusText));
}
} catch (e) {
display('⚠️ Gagal menghubungi server STBB.');
console.error(e);
}
});
function display(msg, resetCaptcha = false) {
document.getElementById('stbb-status').textContent = msg;
if (resetCaptcha) setupCaptcha();
}
})();
mw.loader.using( 'mediawiki.util' ).then(() => {
mw.util.addCSS(`
.stbb-box {
max-width:700px;
margin:1.5em auto;
padding:1.5em;
background:#ffffff;
border:1px solid #d8dee2;
border-radius:8px;
box-shadow:0 2px 6px rgba(0,0,0,0.05);
}
.stbb-title { margin:0 0 8px; font-size:1.4em; }
.stbb-subtext { color:#555; margin-bottom:1em; }
.stbb-label { font-weight:600; display:block; margin-top:1em; }
.stbb-input, .stbb-textarea {
width:100%; box-sizing:border-box;
padding:8px 10px;
border:1px solid #c8ccd1;
border-radius:4px;
font-size:0.95em;
}
.stbb-input:focus, .stbb-textarea:focus { outline:none; border-color:#36c; box-shadow:0 0 0 2px rgba(51,102,204,0.2); }
.stbb-btn {
margin-top:1.2em; padding:8px 16px;
background:#36c; color:white;
border:none; border-radius:4px;
cursor:pointer; font-weight:600;
}
.stbb-btn:hover { background:#2a4b8d; }
.stbb-status { margin-left:1em; font-weight:bold; }
.stbb-warning { padding:1em; background:#fff6e5; border:1px solid #f0c070; }
`);
} );