Здесь делается вжух 🪄

test

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » test » Тестовый форум » лото


лото

Сообщений 1 страница 29 из 29

1

[html]<!-- Морской бой на базе Deff-лотереи -->
<div id="battleship"></div>
<script>
(function(){
  const topicId = 2;          // ID темы Rusff
  const gameMaster = 'admin'; // Автор поста
  const size = 10;
  const letters = 'ABCDEFGHIJ'.split('');
  const turnDelay = 2*60*1000; // 2 минуты

  const wrap = document.getElementById('battleship');
  wrap.innerHTML = `
    <style>
      #battleship table {border-collapse: collapse; margin:0 auto;}
      #battleship td {width:42px;height:42px;border:1px solid #444;text-align:center;vertical-align:middle;cursor:pointer;background:#b0d4ff;font-weight:bold;}
      #battleship td.hit {background:#f00 url(https://forumstatic.ru/files/0014/cc/0a/39265.png) no-repeat center/70%;}
      #battleship td.miss {background:#9bb;opacity:0.7;}
      #battleship th {background:#e0f0ff;padding:5px;}
      #reset-game {margin-top:10px;display:none;}
    </style>
    <h2>⚓ Морской бой</h2>
    <div id="battle-field"></div>
    <button id="reset-game">Сбросить поле</button>
    <p id="game-status" style="margin-top:10px;font-weight:bold;"></p>
  `;

  // ---------------- Создаем поле ----------------
  function createField(){
    let html = '<table><tr><th></th>';
    for(let i=1;i<=size;i++) html+='<th>'+i+'</th>';
    html+='</tr>';
    for(let r=0;r<size;r++){
      html+='<tr><th>'+letters[r]+'</th>';
      for(let c=1;c<=size;c++){
        html+='<td data-cell="'+letters[r]+c+'"></td>';
      }
      html+='</tr>';
    }
    html+='</table>';
    document.getElementById('battle-field').innerHTML = html;
  }

  // ---------------- Расставляем корабли случайно ----------------
  function placeShips(){
    const shipsLen = [4,3,3,2,2,2,1,1,1,1];
    const taken = new Set();
    function randomDir(){return Math.random()<0.5?'h':'v';}
    function canPlace(r,c,len,dir){
      for(let i=0;i<len;i++){
        let rr=r+(dir==='v'?i:0), cc=c+(dir==='h'?i:0);
        if(rr>=size||cc>=size) return false;
        const key=rr+'_'+cc;
        if(taken.has(key)) return false;
        for(let dr=-1;dr<=1;dr++)
          for(let dc=-1;dc<=1;dc++)
            if(taken.has((rr+dr)+'_'+(cc+dc))) return false;
      }
      return true;
    }
    const ships=[];
    shipsLen.forEach(len=>{
      let placed=false;
      while(!placed){
        let r=Math.floor(Math.random()*size);
        let c=Math.floor(Math.random()*size);
        let dir=randomDir();
        if(canPlace(r,c,len,dir)){
          for(let i=0;i<len;i++){
            let rr=r+(dir==='v'?i:0), cc=c+(dir==='h'?i:0);
            taken.add(rr+'_'+cc);
            ships.push(rr+'_'+cc);
          }
          placed=true;
        }
      }
    });
    return ships;
  }

  // ---------------- Состояние игры ----------------
  let state = {
    ships: [],   // клетки кораблей
    shots: {},   // все выстрелы
    lastShot:{}  // время последнего выстрела игроков
  };

  // ---------------- Конвертируем ячейку ----------------
  function convertCell(cell){
    const row = letters.indexOf(cell[0]);
    const col = parseInt(cell.slice(1))-1;
    return row+'_'+col;
  }

  // ---------------- Отправляем сообщение в тему ----------------
  function postToTopic(msg, hit){
    $.post('/misc.php?item=ajax_lottery', {
      a:'message',
      id: topicId,
      msg: ''+msg+'',
      color: hit?'red':'blue'
    });
    document.getElementById('game-status').textContent = msg;
  }

  // ---------------- Рендер ----------------
  function render(){
    document.querySelectorAll('#battleship td[data-cell]').forEach(td=>{
      const cell=td.dataset.cell;
      td.className='';
      if(state.shots[cell]==='miss') td.classList.add('miss');
      else if(state.shots[cell]==='hit') td.classList.add('hit');
    });
  }

  // ---------------- Обработка кликов ----------------
  function activate(){
    document.querySelectorAll('#battleship td[data-cell]').forEach(td=>{
      td.addEventListener('click', e=>{
        const user = FORUM.user.name;
        const now = Date.now();
        if(state.lastShot[user] && now - state.lastShot[user]<turnDelay){
          alert('Можно стрелять раз в 2 минуты.');
          return;
        }
        const cell = e.target.dataset.cell;
        if(state.shots[cell]) return;
        const hit = state.ships.includes(convertCell(cell));
        state.shots[cell] = hit ? 'hit':'miss';
        state.lastShot[user]=now;
        render();
        saveState();
        postToTopic('Игрок '+user+' выстрелил в '+cell+' — '+(hit?'Попал!':'Мимо.'), hit);
      });
    });

    if(FORUM.user.name===gameMaster){
      const btn=document.getElementById('reset-game');
      btn.style.display='inline-block';
      btn.onclick=function(){
        if(confirm('Сбросить поле и расставить корабли заново?')){
          state.ships=[]; state.shots={}; state.lastShot={};
          state.ships=placeShips();
          render(); saveState();
          postToTopic('⚓ Поле сброшено администратором!', false);
        }
      };
    }
  }

  // ---------------- Сохраняем и загружаем ----------------
  function saveState(){
    $.post('/misc.php?item=ajax_lottery', {
      a:'save',
      id: topicId,
      data: JSON.stringify(state)
    });
  }

  function loadState(cb){
    $.get('/misc.php?item=ajax_lottery&id='+topicId+'&action=get', function(res){
      try { state=JSON.parse(res); } catch(e){ state={ships:[],shots:{},lastShot:{}}; }
      if(!state.ships.length) state.ships=placeShips();
      if(cb) cb();
    });
  }

  // ---------------- Инициализация ----------------
  createField();
  loadState(function(){
    render();
    activate();
  });
})();
</script>[/html]

0

2

[html]
<div id="lotobox" style="font-family:monospace; margin:10px 0; padding:10px; border:1px solid #ccc; border-radius:8px; width:240px;">
  <button id="nextnum" style="width:100%; padding:6px;">🎲 Вытащить число</button>
  <div id="result" style="margin-top:8px; font-size:18px; font-weight:bold;"></div>
  <div id="usednums" style="margin-top:8px; font-size:13px; color:#444;"></div>
</div>

<script>
(function() {
  const all = Array.from({length:80}, (_,i)=>i+1);
  const used = [];
  const btn = document.getElementById('nextnum');
  const result = document.getElementById('result');
  const usedBox = document.getElementById('usednums');

  btn.onclick = function() {
    if (all.length === 0) {
      result.textContent = 'Все 80 чисел уже вытянуты!';
      btn.disabled = true;
      return;
    }
    const index = Math.floor(Math.random()*all.length);
    const num = all.splice(index,1)[0];
    used.push(num);
    result.textContent = 'Выпало число: ' + num;
    usedBox.textContent = 'Выпали: ' + used.sort((a,b)=>a-b).join(', ');
  };
})();
</script>
[/html]

0

3

[html]
<iframe src="https://your-loto-widget.example.com/?game=lotto80&host=Irina"
style="width:100%; max-width:500px; height:380px; border:1px solid #aaa; border-radius:8px;">
</iframe>
[/html]

0

4

[dohtml]
<div id="dice-result" style="font-family:monospace; background:#f8f8f8; border:1px solid #ccc; padding:10px; border-radius:8px;">
  <b>🎲 Бросок кубиков:</b>
  <div id="numbers" style="margin-top:6px;"></div>
  <small style="color:#777;">Результат зафиксирован. Повторить нельзя.</small>
</div>

<script>
/* --- НАСТРОЙКИ --- */
const total = 10; // сколько чисел вытянуть (от 1 до 80)
const maxNum = 80; // диапазон чисел

/* --- СЛУЖЕБНЫЕ --- */
function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

// Проверяем: если результат уже записан — выводим его
if (!document.getElementById("numbers").dataset.fixed) {
  // Генерируем результат один раз (для ведущего)
  let arr = Array.from({length: maxNum}, (_, i) => i + 1);
  arr = shuffle(arr).slice(0, total);
  const result = arr.join(", ");
  document.getElementById("numbers").textContent = result;
  document.getElementById("numbers").dataset.fixed = result;
} else {
  // Для игроков просто показываем готовый результат
  document.getElementById("numbers").textContent = document.getElementById("numbers").dataset.fixed;
}
</script>
[/dohtml]

0

5

протимс

0

6

[dice=1936-1:6:0:]

0

7

🎲 Выпавшие числа: 6, 18, 29, 31, 51, 58, 63, 66, 67, 76

0

8

123

0

9

[signed-dice data="eyJudW1zIjpbOCwyMiwzNSwzNiw0NCw2Myw3Niw3Nyw3OCw3OV0sInRzIjoxNzYwNTIxODMyOTgwLCJ1c2VyIjoiIn0" sig="gwBL3jNgpmyof28N1XKC-CXLEpXs1NU0Tf_uDbsV7lg"]

0

10

[signed-dice data="eyJudW1zIjpbNCwyMCwyMSwyNywzMCwzMSwzNyw1NCw1OSw3Nl0sInRzIjoxNzYwNTIyMDU2NDQ2LCJ1c2VyIjoiIn0" sig="VtbSzUP5PeuXzujt1nl3P9CcajIgOdAyPIIk8dpwLFw"]

0

11

[signed-dice data="eyJudW1zIjpbNSw4LDIyLDMxLDMzLDQxLDUwLDU0LDU3LDYwXSwidHMiOjE3NjA1MjIzNTEzMjYsInVzZXIiOiIifQ" sig="2xdoi8BXskUjOwCBPfWjv-7Hk9uCbKfrP4bIVmg_q00"]

0

12

[signed-dice data="eyJudW1zIjpbMSw1LDYsNyw4LDksMTAsMTIsMTUsMTYsMTgsMTksMjEsMjIsMjMsMjQsMjUsMjcsMjgsMjksMzAsMzEsMzMsMzQsMzUsMzYsMzgsMzksNDIsNDQsNDUsNDYsNDcsNDgsNDksNTQsNTUsNTYsNTcsNTgsNTksNjEsNjMsNjQsNjcsNzAsNzUsNzcsNzksODBdLCJ0cyI6MTc2MDUyMjQ5OTIxOSwidXNlciI6IiJ9" sig="e4Is0WBQxMx3gI0kytsotN9T5ky5dlu4TD7OcT2bl3A"]

0

13

[signed-dice data="eyJudW1zIjpbNDAsNjhdLCJ0cyI6MTc2MDUyMjU3MzgzMCwidXNlciI6IiJ9" sig="ENGR5_6bv51FWr7GL_IxlPNmYGtDihAfCZhf5dq90eE"]

0

14

[signed-dice data="eyJudW1zIjpbOSwyNiwyOSwzNSwzNyw0NCw1Miw1OSw2MCw3NV0sInRzIjoxNzYwNTIyODMxMTIxfQ" sig="kY7__ju69QosmjlDXY4CLwUm6xzLT-Ve7krB9a2e1mc"]

0

15

[signed-dice data="eyJudW1zIjpbNjcsMTcsNjAsNDIsMTAsMzEsMTUsNjEsMTYsMzksMTIsNTUsNzIsNDYsMzcsNTgsNzUsNjQsMjIsMTksNCwzNSw2Niw2MywyOCwzLDQ3LDcwLDczLDY4LDU5LDIzLDMwLDQ5LDQzLDUsMjQsODAsMzgsNTYsMSw4LDMzLDUyLDM0LDI5LDI1LDIxLDIsNzRdLCJ0cyI6MTc2MDUyMzA0NzI5Mn0" sig="UVnJP1CpCt98SAa4c5Ey205Y_wCuoW-eq3RqqdCIjy8"]

0

16

[signed-dice data="eyJudW1zIjpbOTEsNzUsNjAsMzEsMjAsOCw5MiwzOCwyM10sInRvdGFsIjoxMDAsInRzIjoxNzYwNTIzMzEzNTE2fQ" sig="vhatympqPi4XCxOA3CWfRnPFJb70gXyOp2-_Ixtn9mY"]

0

17

[signed-dice data="eyJudW1zIjpbMyw0LDE3LDEzLDVdLCJ0b3RhbCI6MjAsInRIjoxNzYwNTIzMzgxMDgyfQ" sig="sfaBqsAGxrjFUgbWR-j-iJ327KOxUSnJBTgnLudu9Tg"]

0

18

[dice=9680-1:6:0:]

0

19

[signed-dice data="eyJudW1zIjpbMTksMSw1NCw0MywxNywyLDUxLDI2LDEwLDM4LDY0LDMsMzMsNjAsNzMsOCwyNywzMSw1MCw2MSwxNCw3MCw3OCw3NCw1NiwxNSw0OCw3Niw1MiwxMywyMywzMCw2MywzNCwzNSw2NSw2Nyw3OSw1OCw0NCwxMiw1OSwyNCwzOSwyNSwxMSwyOCw0MCw2OCw0NSw2MiwzMiw1LDIwLDQ3LDQ5LDY2LDgwLDE2LDU1LDQxLDIxLDksMzcsNDYsMzYsMjIsNTcsNjksNyw3Nyw2LDI5LDcxLDc1LDUzLDQyLDQsMTgsNzJdLCJ0b3RhbCI6ODAsInRzIjoxNzYwNTI0MTA3NzE4fQ" sig="iIbZMbUthf_ZCYoQ_iZ36z8oAUVLFs7R9gmwlftw7Yk"]

0

20

[signed-dice data="eyJudW1zIjpbMyw0LDE3LDEzLDVdLCJ0b3RhbCI6MjAsInRzIjoxNzYwNTIzMzgxMDgyfQ" s[html]


[/html]ig="sfaBqsAGxrjFUgbWR-j-iJ327KOxUSnJBTgnLudu9Tg"]


34

0

21

[signed-dice data="eyJudW1zIjpbMTIsNDEsNTYsNjcsNzYsNTMsMjEsNDIsNzQsMjhdLCJ0b3RhbCI6ODAsInRzIjoxNzYwNTI2NTMzODg2fQ" sig="kccTHGAFUBJGcKqqHQ3hVIilvxracVQiI8Y1BRL4r4k"]

0

22

[page=battleship_game]

0

23

https://test006.rusff.me/pages/battleship_game

0

24

<div id="lotto-container" style="max-width:600px;margin:20px auto;padding:15px;border:2px solid #f4731f;border-radius:10px;background:#fffbe8;">
  <h2 style="text-align:center;">🎃 Русское лото — 80 бочонков</h2>

  <div id="drawn-numbers" style="display:flex;flex-wrap:wrap;gap:5px;justify-content:center;font-size:18px;margin:10px 0;"></div>

  <div style="text-align:center;">
    <button id="draw-btn" style="padding:10px 20px;font-size:16px;background:#f4731f;color:white;border:none;border-radius:8px;cursor:pointer;">🎲 Тянуть бочонок</button>
    <button id="reset-btn" style="padding:10px 15px;margin-left:10px;font-size:14px;">♻️ Сбросить</button>
  </div>

  <div id="last-number" style="font-size:28px;text-align:center;margin-top:15px;color:#f4731f;font-weight:bold;"></div>
</div>

<script>
(function(){
  const total = 80;
  const key = "lotto_numbers_rusff";
  const drawnDiv = document.getElementById("drawn-numbers");
  const lastDiv = document.getElementById("last-number");

  function loadState() {
    try {
      return JSON.parse(localStorage.getItem(key)) || [];
    } catch { return []; }
  }

  function saveState(state) {
    localStorage.setItem(key, JSON.stringify(state));
  }

  function render(state) {
    drawnDiv.innerHTML = "";
    for (let i = 1; i <= total; i++) {
      const el = document.createElement("div");
      el.textContent = i;
      el.style.width = "32px";
      el.style.height = "32px";
      el.style.lineHeight = "32px";
      el.style.textAlign = "center";
      el.style.borderRadius = "6px";
      el.style.background = state.includes(i) ? "#f4731f" : "#eee";
      el.style.color = state.includes(i) ? "#fff" : "#333";
      drawnDiv.appendChild(el);
    }
  }

  let drawn = loadState();
  render(drawn);

  document.getElementById("draw-btn").onclick = () => {
    if (drawn.length >= total) {
      alert("🎉 Все бочонки уже вытянуты!");
      return;
    }
    let num;
    do { num = Math.floor(Math.random() * total) + 1; }
    while (drawn.includes(num));
    drawn.push(num);
    saveState(drawn);
    render(drawn);
    lastDiv.textContent = "Выпал бочонок №" + num;
  };

  document.getElementById("reset-btn").onclick = () => {
    if (confirm("Сбросить игру и начать заново?")) {
      drawn = [];
      saveState(drawn);
      render(drawn);
      lastDiv.textContent = "";
    }
  };
})();
</script>

0

25

[html]<div id="lotto-container" style="max-width:600px;margin:20px auto;padding:15px;border:2px solid #f4731f;border-radius:10px;background:#fffbe8;">
  <h2 style="text-align:center;">🎃 Русское лото — 80 бочонков</h2>

  <div id="drawn-numbers" style="display:flex;flex-wrap:wrap;gap:5px;justify-content:center;font-size:18px;margin:10px 0;"></div>

  <div style="text-align:center;">
    <button id="draw-btn" style="padding:10px 20px;font-size:16px;background:#f4731f;color:white;border:none;border-radius:8px;cursor:pointer;">🎲 Тянуть бочонок</button>
    <button id="reset-btn" style="padding:10px 15px;margin-left:10px;font-size:14px;">♻️ Сбросить</button>
  </div>

  <div id="last-number" style="font-size:28px;text-align:center;margin-top:15px;color:#f4731f;font-weight:bold;"></div>
</div>

<script>
(function(){
  const total = 80;
  const key = "lotto_numbers_rusff";
  const drawnDiv = document.getElementById("drawn-numbers");
  const lastDiv = document.getElementById("last-number");

  function loadState() {
    try {
      return JSON.parse(localStorage.getItem(key)) || [];
    } catch { return []; }
  }

  function saveState(state) {
    localStorage.setItem(key, JSON.stringify(state));
  }

  function render(state) {
    drawnDiv.innerHTML = "";
    for (let i = 1; i <= total; i++) {
      const el = document.createElement("div");
      el.textContent = i;
      el.style.width = "32px";
      el.style.height = "32px";
      el.style.lineHeight = "32px";
      el.style.textAlign = "center";
      el.style.borderRadius = "6px";
      el.style.background = state.includes(i) ? "#f4731f" : "#eee";
      el.style.color = state.includes(i) ? "#fff" : "#333";
      drawnDiv.appendChild(el);
    }
  }

  let drawn = loadState();
  render(drawn);

  document.getElementById("draw-btn").onclick = () => {
    if (drawn.length >= total) {
      alert("🎉 Все бочонки уже вытянуты!");
      return;
    }
    let num;
    do { num = Math.floor(Math.random() * total) + 1; }
    while (drawn.includes(num));
    drawn.push(num);
    saveState(drawn);
    render(drawn);
    lastDiv.textContent = "Выпал бочонок №" + num;
  };

  document.getElementById("reset-btn").onclick = () => {
    if (confirm("Сбросить игру и начать заново?")) {
      drawn = [];
      saveState(drawn);
      render(drawn);
      lastDiv.textContent = "";
    }
  };
})();
</script>[/html]

0

26

[signed-dice data="eyJudW1zIjpbNTgsMyw3Niw0Miw3NCw1NywzOCwzMSwyNCw3XSwidG90YWwiOjgwLCJ0cyI6MTc2MDU1NjIzOTI4Nn0" sig="BcjZ96E2oGWoBnaCOka0qH3uHumA_nWVICDmY1zQSB0"]

0

27

[signed-dice data="eyJudW1zIjpbNTgsMyw3Niw0Miw3NCw1NywzOCwzMSwyNCw3XSwidG90YWwiOjgwLCJ0cyI6MTc2MDU1NjIzOTI4Nn0" sig="BcjZ96E2oGWoBnaCOka0qH3uHumA_nWVICDmY1zQSB0"]

0

28

[html]
<h3>🎲 Генератор ЗЛА — Красивые карточки</h3>
<button id="makeCard">Сгенерировать карточку</button>

<textarea id="result" style="width:100%;height:200px;margin-top:10px;" readonly placeholder="После генерации здесь появится готовый код..."></textarea>

<div id="preview" style="margin-top:10px;"></div>

<style>
.lotto-card table {
    border-collapse: collapse;
    text-align: center;
    border: 3px solid #000; /* рамка вокруг всей карточки */
}
.lotto-card td {
    width: 40px;
    height: 40px;
    border: 2px solid #000; /* границы ячеек */
    vertical-align: middle;
    font-weight: bold;
    font-size: 16px;
    background-color: #f0f0f0; /* цвет пустой ячейки */
}
.lotto-card td.filled {
    background-color: #fff; /* цвет с числом */
}
</style>

<script>
var makeBtn = document.getElementById('makeCard');
var resultArea = document.getElementById('result');
var preview = document.getElementById('preview');

makeBtn.onclick = function() {
    // Генерируем карточку 3x9
    var card = [[],[],[]];
    var ranges = [[1,10],[11,20],[21,30],[31,40],[41,50],[51,60],[61,70],[71,80],[81,90]];
    for (var c=0;c<9;c++) {
        var nums=[];
        while(nums.length<3){
            var n=Math.floor(Math.random()*(ranges[c][1]-ranges[c][0]+1))+ranges[c][0];
            if(nums.indexOf(n)===-1) nums.push(n);
        }
        nums.sort(function(a,b){return a-b});
        for(var r=0;r<3;r++) card[r][c]=nums[r];
    }
    // Убираем по 4 числа в строке
    for(var r=0;r<3;r++){
        var inds=[0,1,2,3,4,5,6,7,8].sort(()=>Math.random()-0.5);
        for(var i=0;i<4;i++) card[r][inds[i]]='';
    }

    // Создаём HTML карточки с классами
    var html = '<div class="lotto-card"><table>';
    for(var r=0;r<3;r++){
        html += '<tr>';
        for(var c=0;c<9;c++){
            var val = card[r][c];
            var cls = val ? 'filled' : '';
            html += `<td class="${cls}">${val || ''}</td>`;
        }
        html += '</tr>';
    }
    html += '</table></div>';

    // Показываем превью
    preview.innerHTML = html;

 
};
</script>
[/html]

0

29

[dohtml]
<script>
(function() {
  const SECRET = 'X4xN5uY8d7Wc2HqzL1tR9aJ0mVfG6sP3eBzQyTnKcUvD8pAoFjRrSxMwZbEhLgC';

  function simpleHash(str) {
    let h = 0;
    for (let i = 0; i < str.length; i++) {
      h = Math.imul(31, h) + str.charCodeAt(i) | 0;
    }
    return ('00000000' + (h >>> 0).toString(16)).slice(-8);
  }

  function sign(payload) {
    return simpleHash(SECRET + '|' + payload);
  }

  function escapeHTML(s) {
    return s.replace(/[&<>"']/g, m => (
      {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'''}[m]
    ));
  }

  function decodeDiceBlocks(context=document) {
    const posts = context.querySelectorAll('.post, .postbody, .post-content, .postmsg, .msg-content');
    posts.forEach(post => {
      const html = post.innerHTML;
      const regex = /\[signed-dice\s+data="([^"]+)"\s+sig="([^"]+)"\]/g;
      let newHTML = html, match;
      while ((match = regex.exec(html)) !== null) {
        const [full, data, sig] = match;
        try {
          const json = decodeURIComponent(escape(atob(data.replace(/-/g,'+').replace(/_/g,'/'))));
          const check = sign(json);
          const payload = JSON.parse(json);
          if (sig === check) {
            const nums = payload.nums.join(', ');
            const count = payload.nums.length;
            const total = payload.total;
            const box = `
              <div style="border:1px solid #ccc;padding:6px 10px;border-radius:6px;background:#fafafa;margin-top:4px;">
                🎲 <strong>Выпавшие числа (${count} из ${total}):</strong> ${escapeHTML(nums)}
              </div>`;
            newHTML = newHTML.replace(full, box);
          } else {
            newHTML = newHTML.replace(full, '<div style="color:red;">⚠️ Ошибка подписи — результат недействителен</div>');
          }
        } catch(e) {
          newHTML = newHTML.replace(full, '<div style="color:red;">⚠️ Ошибка чтения результата</div>');
        }
      }
      if (newHTML !== html) post.innerHTML = newHTML;
    });
  }

  function addDiceButton() {
    const ta = document.querySelector('textarea#main-reply[name="req_message"]');
    const panel = document.querySelector('#form-buttons, .button-row, .button-container, .post-editor-buttons');
    if (!ta || !panel || document.getElementById('dice-btn')) return;

    const btn = document.createElement('input');
    btn.type = 'button';
    btn.id = 'dice-btn';
    btn.className = 'button';
    btn.value = '🎲 Кубики';
    btn.title = 'Сгенерировать случайные числа';
    btn.style.marginLeft = '3px';
    btn.style.cursor = 'pointer';
    btn.style.padding = '2px 6px';
    btn.style.fontSize = '11px';

    panel.appendChild(btn);

    function randUnique(total, draw) {
      const arr = Array.from({ length: total }, (_, i) => i + 1);
      for (let i = arr.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [arr[i], arr[j]] = [arr[j], arr[i]];
      }
      return arr.slice(0, draw);
    }

    btn.addEventListener('click', () => {
      const total = parseInt(prompt('Введите общее количество чисел (например, 80):', '80'));
      if (isNaN(total) || total < 1) return alert('Введите положительное число.');
      const draw = parseInt(prompt(`Сколько чисел вытянуть из ${total}?`, '10'));
      if (isNaN(draw) || draw < 1 || draw > total) return alert(`Введите число от 1 до ${total}.`);

      const nums = randUnique(total, draw);
      const payload = { nums, total, ts: Date.now() };
      const json = JSON.stringify(payload);
      const data = btoa(unescape(encodeURIComponent(json))).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'');
      const sig = sign(json);
      const tag = `[signed-dice data="${data}" sig="${sig}"]`;

      ta.value = tag;
      ta.setAttribute('readonly', 'readonly');
      btn.disabled = true;
      btn.value = '✅ Зафиксировано';
      alert('Результат вставлен и зафиксирован.');
    });
  }

  document.addEventListener('DOMContentLoaded', function() {
    decodeDiceBlocks();
    addDiceButton();
  });

  new MutationObserver(() => decodeDiceBlocks()).observe(document.body, { subtree: true, childList: true });
})();
</script>
[/dohtml]

0


Вы здесь » test » Тестовый форум » лото


Рейтинг форумов | Создать форум бесплатно