不要保存重要内容!不要保存重要内容!不要保存重要内容!不要保存重要内容!不要保存重要内容!
微件:GGLScratchGame:修订间差异
创建页面,内容为“<!-- 初始隐藏 --> <div id="ggl-final-display" style="display: none;"> <div class="content-table"> <table class="infobox" style="border-color:#99F8FF;background-color:#f0f8ff;"> <tbody> <tr> <td class="icon-cell" rowspan="3" style="width:40px;"> <div style="width:50px;"><span typeof="mw:File"><span><img src="https://wm.gaoice.run/images/5/57/Icon-info.png" decoding="async" width="50" height="50" c…” 标签:(旧)WikiEditor |
无编辑摘要 标签:(旧)WikiEditor |
||
| 第51行: | 第51行: | ||
<div class="ggl-ticket"> | <div class="ggl-ticket"> | ||
<img class="ggl-bg" src=" | <img class="ggl-bg" src="/images/b/b6/图片1.png"> | ||
<div class="ggl-scratch-area"> | <div class="ggl-scratch-area"> | ||
| 第198行: | 第198行: | ||
.ggl-cover { | .ggl-cover { | ||
background: url(" | background: url("/images/5/5a/刮开前.png") center/cover; | ||
cursor: pointer | cursor: pointer | ||
} | } | ||
| 第456行: | 第456行: | ||
const redeem = document.getElementById('ggl-redeem-hit'); | const redeem = document.getElementById('ggl-redeem-hit'); | ||
const OPEN = ' | const OPEN = '/images/5/5a/刮开后.png'; | ||
let idx = 0; | let idx = 0; | ||
2026年7月1日 (三) 23:21的版本
<button class="ggl-start-btn">来一张彩票…
…不,三张吧</button>
刮开奖券 · 在整张刮完后交由bot扫描
刮出数字即能获得对应额度的data
当|平|安|喜|乐|四个字连成一条线时,可再获得一张彩票
看不懂也没关系!bot会告诉你结果!
剩余彩票:— 张 可提现 DATA:—
<img class="ggl-bg" src="/images/b/b6/图片1.png">
<button class="ggl-redeem-hit" id="ggl-redeem-hit"></button>
<button id="ggl-scan">扫描结果</button>
<style>
.ggl-root {
width: 375px;
margin: auto;
font-family: sans-serif;
position: relative;
border: 5px solid #ff00aa;
padding: 7px;
background: repeating-linear-gradient(90deg,
transparent 0,
transparent 1px,
rgba(0, 0, 0, 0.08) 1px,
rgba(0, 0, 0, 0.08) 2px);
}
.ggl-mask {
position: absolute;
inset: 0;
background: #000d;
z-index: 99;
display: flex;
align-items: center;
justify-content: center;
min-height: 100%;
}
.ggl-start-btn {
padding: 12px 20px;
font-size: 16px
}
.ggl-top {
text-align: center;
font-size: 14px;
margin-bottom: 6px
}
.ggl-frame {
padding: 10px;
border: 3px solid #ff00aa;
box-shadow: 0 0 12px #ff00aa88
}
.ggl-ticket {
position: relative;
aspect-ratio: 1075/1911
}
.ggl-bg {
width: 100%;
display: block
}
.ggl-frame {
padding: 0;
background: linear-gradient(to bottom, #ffbb37, #ff8f34);
}
.ggl-top {
margin: 0;
padding: 8px 10px;
text-align: center;
font-size: 14px;
color: #fff
}
.ggl-top .ggl-rule {
font-size: 12px;
opacity: 0.95
}
.ggl-ticket {
margin: 0
}
.ggl-bg {
display: block;
width: 100%;
height: auto
}
.ggl-rule-box {
margin: 0 0 5px 0;
padding: 8px;
border: 2px solid #ff00aa;
background: linear-gradient(to bottom, #ffda74, #ffbb37);
border-radius: 0;
}
.ggl-rule-box .ggl-rule {
color: #222;
font-size: 13px;
line-height: 1.35;
}
.ggl-scratch-area {
position: absolute;
left: 10%;
top: 35%;
width: 80%;
height: 53%
}
.ggl-grid {
display: grid;
width: 100%;
height: 100%;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(6, 1fr);
gap: 6px
}
.ggl-cell {
position: relative;
overflow: hidden
}
.ggl-cell img,
.ggl-cover {
position: absolute;
inset: 0;
width: 100%;
height: 100%
}
.ggl-cover {
background: url("/images/5/5a/刮开前.png") center/cover;
cursor: pointer
}
.ggl-reward {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
pointer-events: none;
color: #ff2b2b;
-webkit-text-stroke: 1px #7a0000;
/* Chrome/Safari 描边 */
text-shadow: -1px -1px 0 #7a0000, 1px -1px 0 #7a0000, -1px 1px 0 #7a0000, 1px 1px 0 #7a0000;
}
.ggl-flash {
animation: ggl-flash 500ms steps(1) infinite;
}
@keyframes ggl-flash {
0% {
filter: invert(0);
}
50% {
filter: invert(1);
}
100% {
filter: invert(0);
}
}
.ggl-info-box {
position: relative;
margin: 0;
margin-top: 5px;
padding: 8px;
border: 2px solid #ff00aa;
background: linear-gradient(to bottom, #d62109, #b10117);
display: grid;
grid-template-columns: auto 1fr 25%;
grid-template-rows: auto auto;
gap: 8px;
height: auto;
}
.ggl-mascot {
position: relative;
padding: 6px;
background: #ffdd84;
line-height: 1;
white-space: nowrap;
grid-column: 1;
grid-row: 2;
margin: -8px -8px -8px -8px;
padding: 6px;
display: none;
}
.ggl-mascot:not(:empty) {
display: block;
}
.ggl-bubble {
position: relative;
padding: 6px;
font-size: 13px;
overflow-wrap: break-word;
word-wrap: break-word;
grid-column: 1 / 3;
grid-row: 1;
color: #fff;
}
.ggl-controls {
position: relative;
padding: 2px;
grid-column: 3;
grid-row: 1 / 3;
align-self: stretch;
}
#ggl-scan {
opacity: .3;
background: #ffdd84;
border: 2px solid #ff00aa;
padding: 6px 12px;
font-size: 12px;
cursor: pointer;
font-weight: bold;
display: block;
width: 100%;
height: 100%;
}
#ggl-scan.active {
opacity: 1
}
#ggl-scan:disabled {
opacity: .15;
cursor: not-allowed
}
.ggl-redeem-hit {
position: absolute;
bottom: 1%;
left: 2%;
width: 48%;
height: 10%;
background: transparent;
border: none;
cursor: pointer;
}
#ggl-final-display {
max-width: 800px;
margin: 18px auto;
padding: 12px;
background: #fff;
border: none;
box-shadow: none;
font-family: inherit;
line-height: 1.5;
}
#ggl-ending-container {
max-width: 800px;
margin: 18px auto;
padding: 12px;
background: #fff;
font-family: inherit;
line-height: 1.5;
}
.mw-collapsible {
overflow: hidden
}
.wikitable {
border-collapse: collapse;
width: 100%
}
.wikitable th,
.wikitable td {
border: 1px solid #aaa;
padding: 6px
}
.mw-collapsible-toggle-link {
color: #0645ad;
text-decoration: none;
cursor: pointer;
font-size: 0.85em;
}
.mw-collapsible-toggle-link:hover {
text-decoration: underline;
}
/* 隐藏MediaWiki默认的伪元素展开按钮,因为我们使用自定义的展开按钮 */
.mw-made-collapsible.mw-collapsed::before,
.mw-made-collapsible.mw-collapsed::after,
table.mw-made-collapsible.mw-collapsed th::before,
table.mw-made-collapsible.mw-collapsed th::after,
table.mw-made-collapsible.mw-collapsed td::before,
table.mw-made-collapsible.mw-collapsed td::after {
content: none !important;
display: none !important;
}
.poem {
white-space: pre-wrap;
font-family: serif;
background: #f8f8f8;
padding: 8px;
border-left: 3px solid #ddd
}
.ggl-tooltip {
background: rgba(0, 0, 0, 0.85);
color: #fff;
padding: 6px 8px;
border-radius: 6px;
font-size: 12px;
z-index: 1200;
transition: opacity .18s ease;
position: absolute;
white-space: nowrap;
opacity: 0;
pointer-events: none
}
/* 方括号文本样式:在文本中出现 [文本] 时应用此样式 */
.ggl-bracket {
font-size: 11px;
color: #888;
margin-left: 4px
}
.content-table {
width: 100%;
}
.infobox {
display: table;
width: 100%;
box-sizing: border-box;
border-collapse: collapse;
}
/* 屏幕红黑闪烁覆盖层(用于特殊票面进入时的短暂效果) */
@keyframes ggl-screen-flash {
0% {
background: rgba(255, 0, 0, 0.95);
}
40% {
background: rgba(0, 0, 0, 0.95);
}
80% {
background: rgba(255, 0, 0, 0.95);
}
100% {
background: transparent;
}
}
.ggl-screen-flash {
position: fixed;
inset: 0;
z-index: 2000;
pointer-events: none;
animation: ggl-screen-flash 900ms ease-in-out forwards;
}
</style>
<script>
(function () {
const root = document.querySelector('.ggl-root');
const grid = document.querySelector('.ggl-grid');
const bubble = document.querySelector('.ggl-bubble');
const mascot = document.querySelector('.ggl-mascot');
const scan = document.getElementById('ggl-scan');
const leftEl = document.getElementById('ggl-left');
const dataEl = document.getElementById('ggl-data');
const mask = document.getElementById('ggl-mask');
const redeem = document.getElementById('ggl-redeem-hit');
const OPEN = '/images/5/5a/刮开后.png';
let idx = 0; let revealed = 0; let scanned = false; let finalized = false; let alertTimer = null; let redeemLocked = false;
/* ===== Tooltip for 第八张彩票(索引7) ===== */
function showCellTooltip(cell, text) {
const prev = document.querySelector('.ggl-tooltip');
if (prev) prev.remove();
const tip = document.createElement('div');
tip.className = 'ggl-tooltip';
tip.innerHTML = applyBracketHtml(String(text ?? ));
document.body.appendChild(tip);
// 计算位置并居中到格子顶部
const rect = cell.getBoundingClientRect();
const tipRect = tip.getBoundingClientRect();
const left = rect.left + window.scrollX + rect.width / 2 - tipRect.width / 2;
const top = rect.top + window.scrollY - tipRect.height - 6;
tip.style.left = left + 'px';
tip.style.top = top + 'px';
requestAnimationFrame(() => { tip.style.opacity = '1'; });
setTimeout(() => { tip.style.opacity = '0'; setTimeout(() => tip.remove(), 260); }, 500);
}
/* 将字符串中的方括号内容转换为带样式的 HTML(例如 [注释] -> 注释) 注意:此函数基于对已有 HTML 的简单文本替换,适用于页面中使用 innerHTML 直接插入的受控字符串。 */ function applyBracketHtml(s) { if (s == null) return ; let str = String(s); // 将 转换为普通空格 str = str.replace(/ /g, ' '); // 保持原有的换行
等,直接替换方括号内容为带样式的 span return str.replace(/\[([^\]]+)\]/g, function (_, inner) { return '' + inner + ''; }); }
/* ===== 彩票数组 ===== */
const lotteryList = [
/* 1 */
{
left: 2,
data: 0,
mascot: '|ω`)',
bubble: '你好呀,俺是负责播报结果的。刮奖阶段不用在意我。',
onScan: '哇!中了25MB耶,回本了回本了。',
onRedeem: '不不不,损坏了这里就没法兑奖了(挡住)',
rewards: {
0: '畅', 1: '舒', 2: '遂', 3: '顺', 4: '达', 5: '欢', 6: '5', 7: '欣', 8: '怡', 9: '和',
10: '睦', 11: '融', 12: '洽', 13: '美', 14: '善', 15: '吉', 16: '昌', 17: '20',
18: '兴', 19: '平', 20: '安', 21: '喜', 22: '乐', 23: '平', 24: '安',
25: '盛', 26: '喜', 27: '乐', 28: '悦', 29: '睦'
}
},
/* 2 */
{
left: 1,
data: 25,
mascot: '|∀`)ノ',
bubble: '虽然好像彩票上下都没标,但是中奖金额的单位默认是MB哦~',
onScan: '1MB,然后是……bingo!不对,"平安喜乐"!第二行,横着和斜着,两组!两张彩票,这就去给你兑换!',
onRedeem: '我发现你好奇心很强耶,可惜使不得。',
rewards: {
0: '遂', 1: '舒', 2: '达', 3: '顺', 4: '畅', 5: '平', 6: '安', 7: '喜', 8: '乐', 9: '和',
10: '睦', 11: '安', 12: '1', 13: '美', 14: '善', 15: '吉', 16: '昌', 17: '喜',
18: '盛', 19: '兴', 20: '欢', 21: '平', 22: '悦', 23: '乐', 24: '欣',
25: '怡', 26: '洽', 27: '融', 28: '欢', 29: '怡'
}
},
/* 3 */
{
left: 2,
data: 26,
mascot: '|o`)',
bubble: '耶咦耶咦耶咦耶奥🎶我们又能多相处一会儿了!',
onScan: '让我看看,36MB,外加一张彩票!
[这么好中,真的假的?都不用我……]',
onRedeem: '(*拒绝了你的尝试请求*)',
rewards: {
0: '舒', 1: '平', 2: '场', 3: '遂', 4: '15', 5: '欢', 6: '安', 7: '悦', 8: '欣', 9: '怡',
10: '和', 11: '喜', 12: '睦', 13: '融', 14: '20', 15: '洽', 16: '美', 17: '乐',
18: '善', 19: '吉', 20: '昌', 21: '盛', 22: '兴', 23: '16',
24: '顺', 25: '平', 26: '安', 27: '喜', 28: '乐', 29: '达'
}
},
/* 4 */
{
left: 2,
data: 62,
mascot: '|▽`)',
bubble: '*紧急寻找说明书中*',
onScan: '唔……嘿!
好,现在有一行能连上喽
可别抖出去哦,我们悄悄的……',
onRedeem: '不要老点这里嘛!你再点我也不会说什么了',
rewards: {
0: '欣', 1: '平', 2: '怡', 3: '畅', 4: '舒', 5: '安', 6: '遂', 7: '盛', 8: '顺', 9: '达',
10: '和', 11: '睦', 12: '融', 13: '喜', 14: '洽', 15: '美', 16: '善', 17: '吉',
18: '昌', 19: '乐', 20: '兴', 21: '欢', 22: '平', 23: '安', 24: '悦',
25: '喜', 26: '乐', 27: '融', 28: '洽', 29: '兴'
}
},
/* 5 */
{
left: 2,
data: 62,
mascot: '|_・)',
bubble: '什么都没有
[我该干点什么,还是说些什么?
那边的运气不会一直好下去,死脑子,快想啊呜呜……]',
onScan: '哦哦,扫描完成!10MB!
[完了完了,这下剩一张了,我得再……]',
onRedeem: '【不允许的区域】',
rewards: {
0: '欣', 1: '平', 2: '怡', 3: '1', 4: '舒', 5: '安', 6: '遂', 7: '喜', 8: '顺', 9: '2',
10: '和', 11: '1', 12: '融', 13: '乐', 14: '洽', 15: '美', 16: '善', 17: '吉',
18: '5', 19: '昌', 20: '盛', 21: '兴', 22: '欢', 23: '悦', 24: '1',
25: '平', 26: '乐', 27: '畅', 28: '达', 29: '喜'
}
},
/* 6 */
{
left: 1,
data: 72,
mascot: '|??)',
bubble: '不不不,我不是通过修改多添了一张票吗?为什么还是结束了?
我这是……我在……
不……不要……不要!!!',
onScan: 'A̜̤̓b̦̅́ǒ̮̚r̛̰̪t̗̗͂:̵̂̚ ů̡̘̪̿̎ñ̸̯̻͈̤͊r͍̥̜̾̂̃̀è̡̧̖̬̲̏s͏̴̮̬̬̳͋o̶̡̬̖̖͌̈l̵̴̪̻̄̚͏v̤̭͉̋̂̽̑a̧̩̫͈̦̔̅b̢̮̘̼̥̐̏l̢̟̳̈́͊̊̀ȩ̧͎̩͌̕ s̱̭̙i̥̘͆t̡̥̔ũ̞̠̗a̸̡̺̕t̫i̝̠̾o̺͉͂ǹ̲̎。',
onRedeem: '【不允许的区域】',
rewards: {
0: '6', 1: '顺', 2: '6', 3: '遂', 4: '6', 5: '6', 6: '6', 7: '6', 8: '6', 9: '6',
10: '平', 11: '6', 12: '6', 13: '6', 14: '和', 15: '平', 16: '6', 17: '6',
18: '6', 19: '和', 20: '安', 21: '6', 22: '6', 23: '6', 24: '睦',
25: '安', 26: '6', 27: '6', 28: '6', 29: '睦'
}
},
/* 7 */
{
left: 0,
data: '▒▓',
mascot: '|V̵̨̄I̤)',
bubble: '
.̨̝̮̮͉̖̃̿̈́ͅ.̢̦̫͆͌͆͏̨̩͉.͏̤̫̣̎̆̃̾́ͅ.̧̖̻̥͈̥̈̂̌̒.̲̹́̋̄̐̈́ͅͅ͏.̡͇͈̣̓͌͌͌̂̓.̖̩͈̻̱̌͋͆̊̚.̮̦̝̼̤̮͈͂̆̑.̵̧̘̲̞̉͋̇͂̕.̢̨͌̿͏̖̳͌̓̎.̙̤̫͉̔͋̊̄̐ͅ.͏̶̺̦̲̝̍̈́͌̚.̳̜̼̼̻̹̐̃̈̑.̨̠͎̝̟̼͇̞̩̃.͎̟͉̠̫͉̜̿̈́̓.̴͎̰̼̾͆̃̍̃̃.̛̼͉̝̃̔̆̆̽̚.̷̡̮̠̥̳̬̇̓̃.̞͎̗̀͂̌͊̂̈ͅ.̵̴̱̫̟̒̓̅͊̍.̮̺̠̯͉̊̅̓̀̓.̴̧̨̬̳̬́͋́̂.̤̠̲̍̓ͅ͏̶̾͏
',
onScan: '扫描完成:无数据。',
onRedeem: '【不允许的区域】',
rewards: {
0: '和', 1: '睦', 2: '融', 3: '洽', 4: '美', 5: '善', 6: '吉', 7: '昌', 8: '盛', 9: '兴',
10: '欢', 11: '平', 12: '悦', 13: '顺', 14: '欣', 15: '怡', 16: '安', 17: '畅',
18: '乐', 19: '舒', 20: '遂', 21: '喜', 22: '达', 23: '平', 24: '安',
25: '喜', 26: '乐', 27: '欢', 28: '悦', 29: '欣'
}
},
/* 8 */
{
left: 0,
data: '在此输入数字',
mascot: '|̡̔̿̆∀̯̠̥̒◕̪͇̻̈́)̤͆̾͊',
bubble: '没素质啊,干嘛挠人痒痒肉',
onScan: '就你还想使唤我?不会自己算?(叉腰)',
onRedeem: 'OH BABY, YOU LOOK SO SWEET♂(*喘息*)',
rewards: {
0: '美', 1: '善', 2: '吉', 3: '昌', 4: '盛', 5: '兴', 6: '平', 7: '欢', 8: '悦', 9: '欣',
10: '平', 11: '安', 12: '喜', 13: '乐', 14: '89', 15: '畅', 16: '喜', 17: '32',
18: '遂', 19: '顺', 20: '达', 21: '乐', 22: '睦', 23: '融', 24: '怡',
25: '安', 26: '和', 27: '舒', 28: '200', 29: '洽'
}
,
tooltips: [
'嗯', '哼', '呣', '唔', '噷',
'啊', '哦', '嗬', '欸', '啧',
'嘶', '嗐', '呃', '嚯', '哎',
'呀', '唵', '哦', '咝', '唷',
'蛤', '豁', '嘎', '哼', '嗤',
'哟', '吓', '喂', '呔', '嘘'
]
},
/* 9 */
{
left: 1,
data: '—',
mascot: '|?̷̊̇?̶̨̦)',
bubble: '恭恭恭恭喜喜喜喜中中中中奖奖奖奖',
onScan: '3̘͉̌9̥͂̊3̒̂́4̖̜̾1̻̋̉8̿̊́1̼̓̅3̼̏̋8͍͍̍3̴͍̏5̸̆́3̴̠̉3̂̽̆ +̷̰ͅ 7̺͉̒9̢̰̔3̬̆̓4̶̦̬1̧̧̧6̛͍̘…͉̥̄…̜̱̕',
onRedeem: '文文文文本本本本占占占占位位位位 9999',
rewards: {
0: '17 Byte', 1: '89 KB', 2: '1023 MB', 3: '457 GB', 4: '781 bit',
5: '902 TB', 6: '314 Byte', 7: '567 KB', 8: '890 MB', 9: '10 GB',
10: '21 bit', 11: '144 TB', 12: '169 Byte', 13: '196 KB', 14: '225 MB',
15: '256 GB', 16: '289 bit', 17: '3 Byte', 18: '361 KB', 19: '400 TB',
20: '41 MB', 21: '484 GB', 22: '529 bit', 23: '576 Byte', 24: '625 KB',
25: '676 TB', 26: '729 MB', 27: '84 GB', 28: '841 bit', 29: '900 Byte'
}
},
/* 10 */
{
left: 0,
data: 'ERROR!',
mascot: '|̴̢͌ω̗̦̐`͍̀̈́)̘̗̾',
bubble: 'Oh! Ý̦ȯ͇u̪͆ l̫̒o̙̘o̠͂k̮͂ s̩̹ö̧ f̧͈a̤͋m̮͏i̟̐l̂̀i̳͆a̯ȑ̉.̘̦.̵̨.̶ͅ W͎̑h̜̐o̢̯ å͋r̂̀ẹ̯ ỵ̽o̥̘u͎̿?̄̏ ̖͇
I̹ s̞e̋ęm̲ t͇o̪ k̯n̘o̢̯ŵ ̐y',
onScan: '警告:DATA 溢出。',
onRedeem: 'taskkill /im false touch prevention.exe /f',
rewards: {
0: 'D̸A̍T̴A̵', 1: 'D͊ẠT̿A̘', 2: 'D̐A̬T̰A̢', 3: 'D̶ÃT̚À', 4: 'D̜ǍT̘A͆', 5: 'D̝͏A̸̛T̞̩A͇̒', 6: 'D̵́A̵̗T̈̀Ȃ̐', 7: 'D̢̫A̬̾Ţ̏Ą̘', 8: 'D͇̉A̓̔T̜̿A̷̯', 9: 'D̦̽̂À͈͌T͍̟̋Å̟͇', 10: 'D̢͍ͅA̶̹̝Ṱ̑̏A̵̯̱', 11: 'D̠̖͆Â̛̲T̸̿̃Å̝̖', 12: 'Ḏ̨͍À̆̅T̫͂̐Ȧ̷̺', 13: 'D̮̱̽͆Ǎ̡̯̦Ț̡̓́À̝̹͋', 14: 'D̮̤̣͌Á̷̃́T̟̀̀͂Ả̷̺̂', 15: 'D̼̪̜̈A̷̮͍͆T̵̢̹̏A̩̪̹̦', 16: 'D̶̰̠̅́A͂̎̇̉̔T̨̡͈̃̅A̰͌͋̈́̑', 17: 'D̨̯̝̑̋A̫̱̋̐̅T̞̎͊̅̄A̦̳̣̿̚', 18: 'D̨̨̞̙̆À̟̻̌̓Ṱ̥̉̄ͅA̧̼̣̫͂', 19: 'D̖͏̯̃̽̃A̷͉̎̿̾̿T̊̀͏̺̩̘Á̟̲̦̿̔', 20: 'Ḑ̫̞̿̈̈́A̶̛̬͇̿͂T̨̬̦̺̀̉Á̗̠̋͂̃', 21: 'D̡̧̛̫̼̓A̛̅̂̊̑̽T̸̛̞͎̓̂Ȧ̠̟̪̑̀', 22: 'D̡̻͉̹̽̇͌Á͈̥̥́̈́̌T̪̮̍̒̏̎̚A̷̦͇̩̰͆͆', 23: 'D̸͇̠͍͍̓̈A͎̭̹̮͆͌́T̤̱̖̉̉̉̀A̪̮̞̪̰͋͆', 24: 'D̶̬̱̥̠̊̆A̴̪̙̜̽̆͊T̤͏̖̪̈́͌̃A̪̮̞̪̰͋͆', 25: 'D̴̢̼̗̝̊̋A̸̸̟͎̅̓̃T͇͈̗͇̱̓̐Ȁ̸̎̎̉̇́', 26: 'D̷̴̸̛̳̦͆Ǎ̷̳̤̱̯̄Ṫ̶̢̼͋̌̾A̡̢͍̮̓̆̚', 27: 'D̸̴̛̘̭̖̓A̵̡̢͉̫̒̓T̨̼̼̑̓͊̒Ä̦̪́̒̆̀̕', 28: 'Ḏ̸̨͊̍̍̎̍À̧͉̠̺̻͍̐T̷̡̤̳͊̃̓͆Â̢̟̤̹̯̅ͅ', 29: 'D̮̲̪̲̅́̊͌̾̎Ạ̧̤̩̥̦̒̂͊͏T̼̳̲̭̖̺̆́̀͏Â̴̢͎͍͈̥̾̾̀'
}
},
/* 11 */
{
left: '?̜̻̤̹́̂̈́̑̀?',
data: 'ÈRROR',
mascot: 'Ĕ̴̢̟̑ñ̡̬̑̽d̝̑͋',
bubble: '你知道的太多了。',
onScan: '你知道的太多了。',
onRedeem: '权限越界。
祝您平安喜乐。',
rewards: {
0: '平', 1: '安', 2: '安', 3: '平', 4: '喜', 5: '喜', 6: '乐', 7: '喜', 8: '安', 9: '平',
10: '安', 11: '平', 12: '安', 13: '喜', 14: '乐', 15: '乐', 16: '喜', 17: '平',
18: '安', 19: '安', 20: '喜', 21: '平', 22: '乐', 23: '乐', 24: '平',
25: '平', 26: '安', 27: '安', 28: '喜', 29: '乐'
}
}
];
const TICKETS = lotteryList;
function fadeOutCover(cover, done) {
const start = performance.now();
const duration = 450;
cover.style.pointerEvents = 'none';
function frame(now) {
const p = Math.min((now - start) / duration, 1);
cover.style.opacity = 1 - p;
if (p < 1) {
requestAnimationFrame(frame);
} else {
cover.style.display = 'none';
done && done();
}
}
requestAnimationFrame(frame);
}
/* ===== 构建票面格子 ===== */
function build() {
if (finalized) return;
const t = TICKETS[idx];
grid.innerHTML = ;
revealed = 0;
scanned = false;
if (idx === 10) {
try { document.body.style.filter = 'invert(1)'; } catch (e) { }
}
leftEl.textContent = t.left;
dataEl.textContent = t.data;
mascot.textContent = t.mascot || ;
setBubbleHtml(t.bubble || );
if (idx === 4) {
const prev = document.querySelector('.ggl-screen-flash');
if (prev) prev.remove();
const flash = document.createElement('div');
flash.className = 'ggl-screen-flash';
document.body.appendChild(flash);
setTimeout(() => { try { flash.remove(); } catch (e) { } }, 50);
}
scan.textContent = '扫描结果';
scan.classList.remove('active');
for (let i = 0; i < 30; i++) {
const c = document.createElement('div');
c.className = 'ggl-cell';
c.innerHTML = `
<img src="${OPEN}">
`;
// 插入奖项文本并应用方括号样式
const rewardEl = c.querySelector('.ggl-reward');
if (rewardEl) {
rewardEl.innerHTML = applyBracketHtml(t.rewards?.[i] || );
}
const cover = c.querySelector('.ggl-cover');
cover.onclick = () => {
if (c.dataset.done || finalized) return;
c.dataset.done = 1;
fadeOutCover(cover, () => {
if (++revealed === 30) {
scan.classList.add('active');
}
});
};
// 第八张彩票(索引7):为每个格子绑定 tooltip,允许单独自定义(优先使用 ticket.tooltips[i] 或 data-tooltip)
if (idx === 7) {
// 如果票面定义了 tooltips,则把自定义文本写入 data-tooltip,方便后续覆盖或调试
if (t.tooltips && t.tooltips[i] != null) {
c.dataset.tooltip = t.tooltips[i];
} else {
c.dataset.tooltip = t.rewards?.[i] || ;
}
c.addEventListener('click', () => {
// 优先使用 DOM 上的 data-tooltip(允许运行时覆盖),回退到 rewards
const txt = c.dataset.tooltip || t.rewards?.[i] || ;
showCellTooltip(c, txt);
});
}
grid.appendChild(c);
}
// 构建完成后调整表情位置,防止被气泡遮挡
updateMascotPosition();
}
function startInfiniteAlert() {
if (alertTimer) return;
const TEXT = '哎呀,崩溃啦!\n显示该词条时出现错误,要继续浏览,请尝试刷新并选择其他路径。\n如果您频繁遇到此问题,请尝试以上建议。';
(function loop() {
alert(TEXT);
alertTimer = setTimeout(loop, 200);
})();
}
function showRedeemModal() {
if (redeemLocked) return;
redeemLocked = true;
const overlay = document.createElement('div');
overlay.style.cssText = `
position:absolute;
inset:0;
background:rgba(0,0,0,.7);
z-index:999;
display:flex;
align-items:center;
justify-content:center;
`;
const box = document.createElement('div');
box.style.cssText = `
background:#fff;
padding:20px;
width:70%;
text-align:center;
font-size:14px;
`;
box.textContent = '检测到兑奖区损坏,该票作废';
overlay.appendChild(box);
document.querySelector('.ggl-ticket').appendChild(overlay);
setTimeout(() => {
box.innerHTML = `
`;
const btn = document.createElement('button');
btn.textContent = '确定';
btn.style.marginTop = '12px';
btn.onclick = () => {
overlay.remove();
redeemLocked = false;
idx = 10;
build();
};
box.appendChild(btn);
}, 2200);
}
function updateMascotPosition() {
return;
}
// 窗口改变时重新计算位置(防抖)
window.addEventListener('resize', () => {
clearTimeout(window.__ggl_resize_timeout);
window.__ggl_resize_timeout = setTimeout(updateMascotPosition, 80);
});
// 监听气泡内容变化,自动调整表情位置
try {
const bubbleEl = document.querySelector('.ggl-bubble');
if (bubbleEl) {
const bubbleObserver = new MutationObserver(() => {
updateMascotPosition();
});
bubbleObserver.observe(bubbleEl, { childList: true, subtree: true, characterData: true });
}
} catch (e) {/* ignore */ }
/* 将字符串设置为 bubble 的 HTML,尝试把常见被转义的
和换行恢复 */ function setBubbleHtml(raw) { if (raw == null) raw = ; let s = String(raw); // 将常见的实体化
恢复为真实换行 s = s.replace(/<br\s*\/>>/gi, '
'); s = s.replace(/<br\s*\/>/gi, '
'); s = s.replace(/<br>/gi, '
'); s = s.replace(/<br\s*\/>/gi, '
'); // 处理可能出现的双重转义 s = s.replace(/<br>/gi, '
'); // 把真实的换行符也转为
s = s.replace(/\r\n|\n|\r/g, '
'); // 最后把方括号转换为带样式的 HTML 后赋值为 innerHTML bubble.innerHTML = applyBracketHtml(s); updateMascotPosition(); }
/* ===== 内置 wiki 文本解析 ===== */ const INTERNAL_WIKITEXT = `
简介
于六世恶言事件期间出现的网页,最早被发现于一个早已停止维护的福利彩票发售网站,动机不明。666年过后,该页面无法访问,但相关模因、怪谈与个人改版仍在网络发酵,最终在统治局某支防异小队的刻意引导下,确立了稳定的触发媒介,并指向根据大众印象重建的“原版”网页。最终评级:一级。
触发流程
- 在主塔中保持对访问该网页的期望
- 使手边任意电子设备出现“平安喜乐”四字,且在同一直线上,连成直线的次数与稍后获得的刮刮卡数量相同
- 条件达成后,电子设备将强制进入该网页,并自动获得对应张数的彩票。
相关收藏品
| 【未读】您有一封新的邮件 |
|---|
|
收集时间:未知 |
| 网页截图3866720_6680120200242_1 |
|---|
|
收集时间:668/01/21 |
| 未命名邮件 |
|---|
|
收集时间:未知 |
`;
(function (global) {
'use strict';
function escapeHtml(s) {
// 转义常规字符,同时保留 实体以便在输出中作为不间断空格渲染
return String(s)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
// 将被转义的 恢复为实体
.replace(/ /g, ' ');
}
function applyBracketHtml(s) {
if (s == null) return ;
return String(s).replace(/\[([^\]]+)\]/g, function (_, inner) {
return '' + escapeHtml(inner) + '';
});
}
function encodeId(text) {
let out = ;
for (let i = 0; i < text.length; i++) {
const ch = text.charAt(i);
const code = text.charCodeAt(i);
if (code > 127) {
out += '%' + code.toString(16).toUpperCase().padStart(2, '0');
} else {
out += ch;
}
}
return out;
}
function parseParagraphLines(lines) {
const txt = lines.join('\n');
let html = escapeHtml(txt);
html = html.replace(/(.+?)/g, '$1');
html = applyBracketHtml(html);
html = html.replace(/<br\s*\/?>/g, '
');
return '
' + html + '
';
}
function parseOrderedList(lines) {
let html = '
- ';
for (let l of lines) {
const m = l.replace(/^#+/, ).trim();
html += '
- ' + applyBracketHtml(escapeHtml(m).replace(/(.+?)/g, '$1')) + ' '; } html += '
';
return html;
}
function parseDefinitionBlock(lines) {
let prevDepth = 0;
let html = ;
for (let raw of lines) {
const m = raw.match(/^(:+)(.*)$/);
if (!m) continue;
const depth = m[1].length;
const content = m[2].trim();
if (depth > prevDepth) {
for (let i = prevDepth; i < depth; i++) {
html += '
- '; } } else if (depth < prevDepth) { for (let i = depth; i < prevDepth; i++) { html += '
';
}
} else {
html += '
';
return html;
}
function parseWikiTable(block) {
const lines = block.split(/\r?\n/);
const first = lines[0] || ;
const isCollapsible = /mw-collapsible/.test(first);
let header = ;
let cellContent = [];
// 逐行解析:找到表头和单元格内容
for (let i = 1; i < lines.length; i++) {
const line = lines[i];
const trimmed = line.trim();
// 表头行:! 开头
if (trimmed.startsWith('!')) {
const afterExclaim = trimmed.slice(1);
// 处理 !colspan="1"| 这种格式:找 | 符号
const pipeIdx = afterExclaim.indexOf('|');
if (pipeIdx >= 0) {
header = afterExclaim.slice(pipeIdx + 1).trim();
} else {
header = afterExclaim.trim();
}
continue;
}
// 行分隔符
if (trimmed === '|-') {
continue;
}
// 表格结束
if (trimmed === '|}') {
break;
}
// 单元格内容行:| 开头
if (trimmed.startsWith('|')) {
const content = trimmed.slice(1).trim();
if (content) cellContent.push(content);
continue;
}
// 如果不以特殊符号开头但不为空,继续累积到上一个单元格
if (trimmed && !trimmed.startsWith('!')) {
if (cellContent.length > 0) {
cellContent[cellContent.length - 1] += '\n' + trimmed;
} else {
cellContent.push(trimmed);
}
}
}
// 构建单元格内容的 HTML
let cellHtml = ;
if (cellContent.length > 0) {
// 将所有行合并并处理格式
const fullText = cellContent.join('\n');
// 处理
标签(WikiText 中写的) let html = fullText; html = html.replace(/<br\s*\/?>/gi, '
');
// 转义 HTML
html = escapeHtml(html);
// 恢复
标签(已被转义,现在反转义) html = html.replace(/<br\s*\/?>/g, '
');
// 处理粗体
html = html.replace(/(.+?)/g, '$1');
// 处理方括号
html = applyBracketHtml(html);
cellHtml = '
' + html + '
';
}
if (isCollapsible) {
const tableId = 'tbl-' + Math.random().toString(36).slice(2);
const tbl = [];
tbl.push('
tbl.push('<tbody>');
tbl.push('');
tbl.push('');
tbl.push('');
tbl.push('');
tbl.push('</tbody>' + escapeHtml(header) + '<a href="javascript:void(0)" class="mw-collapsible-toggle-link" data-table="' + tableId + '">展开</a> |
|---|
');
return tbl.join('\n');
}
// fallback: simple table
let rowsHtml = [];
for (let content of cellContent) {
rowsHtml.push('' + applyBracketHtml(escapeHtml(content).replace(/(.+?)/g, '$1')) + '');
}
return '
\n<tbody>\n' + rowsHtml.join('\n') + '\n</tbody>';
}
function parseWikiToHtml(wikitext) {
const lines = String(wikitext).replace(/\r\n/g, '\n').split('\n');
let out = [];
let i = 0;
let sectionIndex = 1;
while (i < lines.length) {
const raw = lines[i];
const line = raw.trim();
if (line === ) { i++; continue; }
// h3
const h3 = line.match(/^===\s*(.+?)\s*===/);
if (h3) {
const title = h3[1];
const id = title;
const encoded = encodeId(title);
out.push('
' + escapeHtml(title) + '
');
sectionIndex++;
i++; continue;
}
// h2
const h2 = line.match(/^==\s*(.+?)\s*==$/);
if (h2) {
const title = h2[1];
const id = title;
const encoded = encodeId(title);
out.push('
' + escapeHtml(title) + '
');
sectionIndex++;
i++; continue;
}
// table
if (line.startsWith('{|')) {
let j = i;
const block = [];
while (j < lines.length) {
block.push(lines[j]);
if (lines[j].trim().startsWith('|}')) { j++; break; }
j++;
}
out.push(parseWikiTable(block.join('\n')));
i = j; continue;
}
// ordered list
if (line.startsWith('#')) {
const buf = [];
while (i < lines.length && lines[i].trim().startsWith('#')) { buf.push(lines[i]); i++; }
out.push(parseOrderedList(buf));
continue;
}
// definition list inline (outside table)
if (line.startsWith(':')) {
const buf = [];
while (i < lines.length && lines[i].trim().startsWith(':')) { buf.push(lines[i]); i++; }
out.push(parseDefinitionBlock(buf));
continue;
}
// paragraph(s)
const paraBuf = [];
while (i < lines.length) {
const cur = lines[i].trim();
if (cur === || cur.match(/^={2,}/) || cur.startsWith('{|') || cur.startsWith('#') || cur.startsWith(':')) break;
paraBuf.push(lines[i]); i++;
}
if (paraBuf.length) out.push(parseParagraphLines(paraBuf));
}
return out.join('\n');
}
// expose
global.parseWikiToHtml = parseWikiToHtml;
})(window);
/* ===== 终局:隐藏微件并插入解析后的 HTML ===== */
function triggerFinal() {
if (finalized) return;
finalized = true;
if (root) root.style.display = 'none';
// 显示最终内容展示区
const finalDisplay = document.getElementById('ggl-final-display');
if (finalDisplay) {
finalDisplay.style.display = 'block';
}
const html = parseWikiToHtml(INTERNAL_WIKITEXT);
const container = document.createElement('div');
container.id = 'ggl-ending-container';
// parseWikiToHtml 已经对方括号和换行等进行处理,直接使用解析后的 HTML
container.innerHTML = html;
if (root && root.parentNode) {
root.parentNode.insertBefore(container, root.nextSibling);
} else {
document.body.appendChild(container);
}
// 初始化可折叠表格展开按钮
initCollapsibleToggle(container);
}
/* ===== 可折叠表格展开/收起逻辑 ===== */
function initCollapsibleToggle(container) {
const toggleLinks = container.querySelectorAll('.mw-collapsible-toggle-link');
toggleLinks.forEach(link => {
link.addEventListener('click', function (e) {
e.preventDefault();
const tableId = this.getAttribute('data-table');
const table = document.getElementById(tableId);
if (!table) return;
const contentRow = table.querySelector('.mw-collapsible-content');
if (!contentRow) return;
// 切换显示/隐藏
if (contentRow.style.display === 'none') {
contentRow.style.display = 'table-row';
table.classList.remove('mw-collapsed');
this.textContent = '收起';
} else {
contentRow.style.display = 'none';
table.classList.add('mw-collapsed');
this.textContent = '展开';
}
});
});
}
/* ===== 交互逻辑:扫描按钮 ===== */
scan.onclick = () => {
if (!scan.classList.contains('active') || finalized) return;
if (idx === 9 && revealed === 30) {
startInfiniteAlert();
return;
}
if (idx === 10 && revealed === 30) {
scan.disabled = true; // 禁用"再来一张"按钮
triggerFinal();
return;
}
if (!scanned) {
if (idx === 3) {
scanned = true;
setBubbleHtml('扫描完成:null。终于正常了嘛……
嘿嘿,果然还需要我来帮一把!');
updateMascotPosition();
const targetIndex = 7;
const cell = grid.children[targetIndex];
const rewardEl = cell ? cell.querySelector('.ggl-reward') : null;
scan.disabled = true;
if (rewardEl) {
rewardEl.classList.add('ggl-flash');
}
setTimeout(() => {
if (rewardEl) {
rewardEl.classList.remove('ggl-flash');
rewardEl.innerHTML = applyBracketHtml('安');
if (TICKETS[idx] && TICKETS[idx].rewards) TICKETS[idx].rewards[targetIndex] = '安';
}
setBubbleHtml(TICKETS[idx].onScan || );
scan.textContent = '再来一张';
scan.disabled = false;
updateMascotPosition();
}, 3000);
return;
}
scanned = true;
// onScan 可能包含简单 HTML(如
),使用 setBubbleHtml 处理被转义的换行
setBubbleHtml(TICKETS[idx].onScan || );
scan.textContent = '再来一张';
updateMascotPosition();
return;
}
idx++;
build();
};
redeem.onclick = () => {
if (finalized) return;
const t = TICKETS[idx];
if (!t) return;
setBubbleHtml(t.onRedeem || t.onScan || );
if (idx === 9 && revealed === 30) {
showRedeemModal();
}
};
mask.onclick = () => {
mask.remove();
build();
};
function updateMaskHeight() {
if (!mask) return;
const rootHeight = root.scrollHeight;
mask.style.height = rootHeight + 'px';
}
requestAnimationFrame(updateMaskHeight);
window.addEventListener('resize', updateMaskHeight);
document.addEventListener('keydown', e => {
if (finalized) return;
if (e.shiftKey && e.key.toLowerCase() === 'd') {
grid.querySelectorAll('.ggl-cover').forEach(c => {
c.style.display = 'none';
});
revealed = 30;
scan.classList.add('active');
}
});
if (!mask) {
build();
}
})();
</script>
