转跳到内容

367ddd

【动漫】动漫综合区
  • 内容数

    2,251
  • 加入

  • 最后访问

  • 赢得天数

    38

关于367ddd

经济

  • 羽毛 702.00 根
  • 节操值 670.00 节操值

最近资料访问用户

8,736 次访问

367ddd的成就

朋满天下【组建伐魔队只需振臂一呼】

朋满天下【组建伐魔队只需振臂一呼】 (7/9)

  • 关键的一票:最后一根稻草
  • 12周年庆:【荣誉成就】以希望铸成破敌之剑!
  • 开拓者:世上本没有路,走的人多了,也便成了路
  • 要溢出来了:这可满满地都是精华
  • 小小水怪:水怪的入门之路

最近徽章

8

社区解答

  1. 电脑端,使用tampermonkey插件,试试看把这个脚本拷贝进去,如果是你有修改权限的帖子会删除附件,如果你没修改权限的话会报404,至少我实验是有效的 // ==UserScript== // @name SSTM 附件页删除按钮(区分主题/回复) // @namespace https://example.com/ // @version 0.2.0 // @author sstm脚本组 // @description 在 https://sstm.moe/attachments/ 页面为每个附件块插入删除按钮,并根据来源链接自动判断编辑主题还是编辑回复 // @match https://sstm.moe/attachments/* // @match https://sstm.moe/attachments/ // @grant none // ==/UserScript== (function () { 'use strict'; const CONFIG = { itemSelector: 'div.ipsDataItem.ipsAttach', attachmentLinkSelector: 'a[href*="/applications/core/interface/file/attachment.php?id="]', sourceLinkSelector: '.ipsDataItem_generic.ipsDataItem_size9 a[href*="/topic/"]', buttonClass: 'sstm-delete-attachment-btn', confirmBeforeDelete: true, debug: true }; function log(...args) { if (CONFIG.debug) { console.log('[SSTM Attachment Delete]', ...args); } } function absoluteUrl(url) { return new URL(url, location.origin).toString(); } function getCsrfKey() { const fromMeta = document.querySelector('meta[name="csrfKey"]')?.content; if (fromMeta) return fromMeta; const fromWindow1 = window.ips?.getSetting?.('csrfKey'); if (fromWindow1) return fromWindow1; const fromWindow2 = window.ipsSettings?.csrfKey; if (fromWindow2) return fromWindow2; const m = document.cookie.match(/(?:^|;\s*)csrfKey=([^;]+)/); if (m) return decodeURIComponent(m[1]); return null; } function extractAttachmentId(item) { const link = item.querySelector(CONFIG.attachmentLinkSelector); if (!link) return null; try { const url = new URL(link.href, location.origin); return url.searchParams.get('id'); } catch (e) { return null; } } function extractFileName(item) { const el = item.querySelector('.ipsAttach_title a, .ipsDataItem_title a'); return el ? el.textContent.trim() : '未知附件'; } function extractSourceInfo(item) { const sourceLink = item.querySelector(CONFIG.sourceLinkSelector); if (!sourceLink) return null; const href = absoluteUrl(sourceLink.href); const url = new URL(href); const commentId = url.searchParams.get('comment'); const doValue = url.searchParams.get('do'); const isReply = doValue === 'findComment' && !!commentId; if (isReply) { url.searchParams.delete('do'); url.searchParams.delete('comment'); return { type: 'reply', sourceUrl: href, baseTopicUrl: url.toString(), commentId }; } url.searchParams.delete('do'); url.searchParams.delete('comment'); return { type: 'topic', sourceUrl: href, baseTopicUrl: url.toString(), commentId: null }; } function buildEditUrl(sourceInfo, csrfKey) { const url = new URL(sourceInfo.baseTopicUrl, location.origin); if (sourceInfo.type === 'reply') { url.searchParams.set('do', 'editComment'); url.searchParams.set('comment', sourceInfo.commentId); } else { url.searchParams.set('do', 'edit'); } if (csrfKey) { url.searchParams.set('csrfKey', csrfKey); } return url.toString(); } async function fetchText(url, options = {}) { const resp = await fetch(url, { credentials: 'include', cache: 'no-cache', ...options }); if (!resp.ok) { throw new Error(`请求失败 ${resp.status} ${resp.statusText}`); } return await resp.text(); } function parseHTML(html) { return new DOMParser().parseFromString(html, 'text/html'); } function extractPostKeyFromEditHtml(html) { const doc = new DOMParser().parseFromString(html, 'text/html'); // 1. 优先从 IPS 编辑器容器读取 const editorEl = doc.querySelector('[data-ipseditor-postkey]'); if (editorEl) { const postKey = editorEl.getAttribute('data-ipseditor-postkey'); if (postKey) return postKey; } // 2. 兜底:兼容可能存在的 input const input = doc.querySelector('input[name="postKey"]'); if (input?.value) return input.value; // 3. 再兜底:正则扫原始 HTML let m = html.match(/data-ipseditor-postkey=["']([^"']+)["']/i); if (m) return m[1]; m = html.match(/name=["']postKey["'][^>]*value=["']([^"']+)["']/i); if (m) return m[1]; m = html.match(/["']postKey["']\s*:\s*["']([^"']+)["']/i); if (m) return m[1]; return null; } async function deleteAttachment(editUrl, attachmentId, postKey, csrfKey) { const url = new URL(editUrl, location.origin); url.searchParams.set('postKey', postKey); url.searchParams.set('deleteFile', attachmentId); if (csrfKey) { url.searchParams.set('csrfKey', csrfKey); } log('删除请求 URL:', url.toString()); const resp = await fetch(url.toString(), { method: 'GET', credentials: 'include', mode: 'cors', headers: { 'accept': '*/*', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'x-requested-with': 'XMLHttpRequest' }, referrer: editUrl }); if (!resp.ok) { throw new Error(`删除请求失败 ${resp.status} ${resp.statusText}`); } return await resp.text(); } function setBtnState(btn, state, text) { btn.disabled = state === 'loading'; btn.textContent = text; if (state === 'loading') { btn.style.opacity = '0.7'; btn.style.cursor = 'wait'; } else { btn.style.opacity = '1'; btn.style.cursor = 'pointer'; } } function removeItem(item) { item.style.transition = 'opacity .25s ease, transform .25s ease'; item.style.opacity = '0'; item.style.transform = 'scale(0.98)'; setTimeout(() => item.remove(), 260); } async function handleDelete(item, btn) { const attachmentId = extractAttachmentId(item); const fileName = extractFileName(item); const sourceInfo = extractSourceInfo(item); const csrfKey = getCsrfKey(); if (!attachmentId) { alert('未找到附件 ID'); return; } if (!sourceInfo) { alert('未找到该附件对应的主题/回复链接'); return; } if (!csrfKey) { alert('未找到 csrfKey'); return; } const targetText = sourceInfo.type === 'reply' ? `回复 #${sourceInfo.commentId}` : '主题首楼'; if (CONFIG.confirmBeforeDelete) { const ok = confirm( `确定删除附件吗?\n\n文件名:${fileName}\n附件ID:${attachmentId}\n挂载位置:${targetText}` ); if (!ok) return; } try { setBtnState(btn, 'loading', '读取编辑页...'); const editUrl = buildEditUrl(sourceInfo, csrfKey); log('编辑页 URL:', editUrl); log('来源类型:', sourceInfo.type, sourceInfo); const editHtml = await fetchText(editUrl, { headers: { 'accept': 'text/html,application/xhtml+xml' } }); const postKey = extractPostKeyFromEditHtml(editHtml); if (!postKey) { throw new Error('未能从编辑页中解析出 postKey'); } setBtnState(btn, 'loading', '提交删除...'); const result = await deleteAttachment(editUrl, attachmentId, postKey, csrfKey); log('删除响应:', result); setBtnState(btn, 'success', '已删除'); removeItem(item); } catch (err) { console.error(err); setBtnState(btn, 'error', '删除失败'); alert(`删除失败:${err.message}`); setTimeout(() => { setBtnState(btn, 'idle', '删除附件'); }, 1200); } } function injectButton(item) { if (item.querySelector(`.${CONFIG.buttonClass}`)) return; const attachmentId = extractAttachmentId(item); const sourceInfo = extractSourceInfo(item); if (!attachmentId || !sourceInfo) return; const btn = document.createElement('button'); btn.type = 'button'; btn.className = CONFIG.buttonClass; btn.textContent = '删除附件'; btn.style.marginTop = '8px'; btn.style.padding = '6px 10px'; btn.style.border = '1px solid #cc3333'; btn.style.borderRadius = '4px'; btn.style.background = '#fff5f5'; btn.style.color = '#b30000'; btn.style.fontSize = '12px'; btn.style.lineHeight = '1.2'; btn.style.cursor = 'pointer'; btn.addEventListener('mouseenter', () => { if (!btn.disabled) btn.style.background = '#ffeaea'; }); btn.addEventListener('mouseleave', () => { if (!btn.disabled) btn.style.background = '#fff5f5'; }); btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); handleDelete(item, btn); }); const target = item.querySelector('.ipsDataItem_main') || item; target.appendChild(btn); } function processAll() { document.querySelectorAll(CONFIG.itemSelector).forEach(injectButton); } function observe() { const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (!(node instanceof Element)) continue; if (node.matches?.(CONFIG.itemSelector)) { injectButton(node); } node.querySelectorAll?.(CONFIG.itemSelector).forEach(injectButton); } } }); observer.observe(document.body, { childList: true, subtree: true }); } processAll(); observe(); })(); 然后之后如果想上传图片/视频的话,可以试试看这个https://sstm.moe/topic/378868-【油猴脚本】便捷文件上传自定义表情包/?do=findComment&comment=18887760
  2. 作者:SS同盟脚本组 便捷文件上传-脚本安装地址 该脚本利用catbox提供的API,在sstm站内完成文件上传+外链插入的功能,避免同时打开多个窗口来回切换以插入外链文件的困扰,同时支持图片,视频,音频的插入 该脚本需要提供catbox账号hash,创建catbox账号并登陆后,进入https://catbox.moe/user/manage.php可得到当前userhash,写入脚本代码第26行。对于不想打开脚本编辑界面的用户,脚本在未检测到userhash时,也会通过弹窗提醒输入用户hash并保存 使用示例:(基于网络状况和文件大小,使用时可能会产生一定的延迟) 自定义表情包-脚本安装地址 该脚本允许将imgbox的gallery用作表情包,并插入到论坛的表情包组件中,本质上仍是将imgbox的外链图片插入,但是简化了其步骤 类似的,可以将用作表情包的链接写入脚本代码第26行。对于不想打开脚本编辑界面的用户,脚本在未检测到相册链接时,也会通过弹窗提醒输入并保存,为了避免过多的网络请求与分析,并不会每次插入都实时检查相册链接内容,当相册内上传了新图片时请点击刷新并耐心等待 使用示例: SS同盟脚本组目前正在组建中,后续会有新的脚本和信息放出,敬请期待
  3. 担心健康推荐还是自己做饭吧,清炒包菜之类的蔬菜,挑选好一点的菜,不给盐正常也会有清甜味,肉可以用香料代偿一下味道,例如葱姜蒜这些,买点超市散称鸡腿回来去皮再做,脂肪也不用太担心
  4. 有的喔,很强的喔,非常非常强大的喔
  5. 好恐怖,我过两天也要去开组会了就是了
  6. 妖精嗼,可是漫区的大大大前辈嗼
  7. 亡零也在卡论文啊,我这边也在赶就是了,陪着的师兄ddl是二十号要初稿,现在才一半进展
  8. 好久不见了,亡零桑最近怎么样喔
  9. 好问题嗼,是怎样认识的嗼,大概是被通知出现了新的脚本仙人嗼
  10. 让chatgpt来做,到椭圆曲线的推导都很正常,结果后面写sagemath代码的时候就开始犯病出现幻觉,经典开始调用错误的属性和错误的函数,以及提前投降说此题无解,放弃本题了 顺便,如果暴力求解的话,ABC在-2000到2000的取值范围内,可以找到-1936, -1849, -1764, -1681, -1600, -1521, -1444, -1369, -1296, -1225, -1156, -1089, -1024, -961, -900, -841, -784, -729, -676, -625, -576, -529, -484, -441, -400, -361, -324, -309, -289, -256, -225, -205, -196, -193, -169, -144, -121, -111, -100, -81, -64, -60, -57, -49, -36, -25, -24, -22, -17, -16, -11, -10, -9, -4, -1, 3, 5, 6, 9, 10, 14, 15, 19, 40, 41, 53, 66, 87, 159, 261这几个系数的解
  11. 像坐牢也正常,鹰角这个养成系统杂糅了很多元素。难民营和流水线的意义在于进度拉满了之后定期卖物资换票去买刷珠子的票券和送干员的礼物,不想玩可以去抄蓝图,但是电线,矿机和滑索就得自己拉,好消息是拉一次以后就不用再拉了。 抱抱和拉手这种剧情难说,鹰角目前的态度明显是有意识到角色是核心的,42,伊冯,老庄都有长段和管理员交互的剧情,毕竟是要进限定池骗人氪金的,但是不太会做到一个明显能称得上是爱情的级别。后面倒是有个见了你就脸红的小红帽,但是会和主角发展到什么阶段现在也难说,据说一个月后进卡池,到时候应该才有剧情。
×
×
  • 新建...

重要消息

为使您更好地使用该站点,请仔细阅读以下内容: 使用条款