尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Discord AI bot: chat, music, tokens and gambling games
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗👉 介紹網頁:不用看程式碼,直接看大笨bot 能做什麼。
讀取頻道的歷史訊息當上下文,用本地模型(例如 Qwen,經 LiteLLM 的 OpenAI 相容 API)回覆。
機器人本體跑在 Linux 伺服器上(systemd 服務 discord-bot),連到你設定的模型 API(LLM_BASE_URL)。
Discord 機器人只需要「往外連」Discord,不用開任何連接埠。
ffmpeg(放音樂用)和 node(yt-dlp 解 YouTube 用)。Ubuntu/Debian:sudo apt install ffmpeg nodejspip install playwright && playwright install chromium,裝在哪個 Python 由 .env 的 SVG_PYTHON 指定);沒裝就只有文字星盤DISCORD_TOKEN,等同機器人的密碼,不要貼到任何公開的地方。YOUR_CLIENT_ID 換成剛才的 Application ID,用瀏覽器打開、選伺服器、同意。git clone https://github.com/ggh93234999/discord-ai-bot.git
cd discord-ai-bot
python3 -m venv .venv
source .venv/bin/activate # Windows:.venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # Windows:copy .env.example .env
然後用文字編輯器打開 .env,把金鑰填在這裡(這個檔案已被 .gitignore 擋住,不會被 git 上傳;千萬不要把它傳給別人或貼到聊天室):
| 變數 | 填什麼 |
|---|---|
DISCORD_TOKEN | 上一步複製的機器人 token |
LLM_BASE_URL | 模型 API 位址,要含 /v1。Ollama:http://localhost:11434/v1;LiteLLM:http://localhost:4000/v1;OpenAI:https://api.openai.com/v1 |
LLM_API_KEY | 模型 API 的金鑰。Ollama 不檢查,隨便填一個非空字串(例如 ollama)即可 |
LLM_MODEL | 模型名稱,要跟 API 那邊的名稱一樣,例如 qwen3:8b、gpt-4o-mini |
DEEPSEEK_API_KEY | 選填,只有想用 /餘額 查 DeepSeek 餘額才需要 |
ADMIN_USER_IDS | 選填,除了機器人擁有者以外,還有誰能用 /模型 切模型(Discord 使用者 ID,逗號分隔) |
其他選填設定都有預設值,說明寫在 .env.example 裡。
python bot.py
看到「已同步斜線指令」就成功了。到 Discord 打 / 就能看到指令(第一次可能要等一兩分鐘,或按 Ctrl+R 重新整理)。
語音和聊天都在這一個程式裡,不需要對外開任何連接埠,機器人只是主動連出去 Discord 和你的模型 API。
要長期運作的話,可以用 systemd:參考 discord-bot.service.example,改掉使用者和路徑後放到 /etc/systemd/system/,再 sudo systemctl enable --now discord-bot。
LLM_BASE_URL 連不到(看終端機的錯誤訊息)。applications.commands。ffmpeg,機器人有「連線」和「說話」權限;YouTube 常改版,pip install -U yt-dlp 通常就會好。.env。/自動回覆 開 開啟的頻道,任何人說話都回其他機器人發的訊息一律不理,避免兩個機器人互相無限對話。 模型那台電腦關機或沒開模型時,機器人會回「模型那台電腦現在沒開或連不到」。
/播放 歌名或網址,或直接說「@大笨bot 放周杰倫的晴天」「放點讀書的音樂」「下一首」。
可以貼單首網址或整個播放清單(最多 50 首)。佇列播完 3 分鐘、或語音頻道沒人 1 分鐘,會自己離開。
yt-dlp 建議定期更新(可參考 update-ytdlp.sh.example 設成每週的 crontab),YouTube 改版時通常更新就會好。/開頻道 名稱 類型 [分類] [私人],或直接說「@大笨bot 幫我開一個叫 xxx 的語音頻道」/改頻道 [頻道] [新名稱] [分類]:改名或搬到別的分類,也可以直接說「把大笨bot 語音頻道移到語音頻道分類」/關頻道 方式 [頻道] [隱藏]:封存(鎖住、可還原)、解除封存、刪除(永久,會先跳確認按鈕)。
用說的只能封存/解除封存,不能刪除。封存需要機器人另有「管理身分組」權限。/頻道狀態 [狀態] [頻道]:設定語音頻道狀態(留空=清除),也能直接說「把語音狀態改成 讀書中」。手動設定的狀態不會被歌名蓋掉。/臨時語音房 開:建立「➕ 建立語音房」入口,有人進去就自動開一間他的房間並移過去,人走光自動刪掉dbot/ai/divination.py):直接聊天說「@大笨bot 幫我抽塔羅問工作」「幫我擲筊問明天面試好不好」「抽支籤問感情」「用易經卜一卦」就好,沒有斜線指令。
dbot/ai/divination_data/;塔羅牌義是自己整理的常見解釋。dbot/ai/drawimg.py):擲筊畫出每一擲兩個筊的平凸面、籤詩畫成直式籤紙、易經畫出本卦與之卦的卦象並標出變爻。dbot/ai/drawimg.py 用 Pillow 畫;牌面是 1909 年的偉特塔羅牌,公有領域,取自維基共享資源,存在 divination_data/tarot/00.jpg~77.jpg,編號同 divination.TAROT,逆位會倒過來畫)。dbot/ai/fortune.py):說「@大笨bot 幫我排八字和星盤,1990-05-15 14:30 台北出生,男」。資料不夠時機器人會先問。
dbot/ai/drawimg.py 畫的。lunar_python(壽星萬年曆):年柱、月柱看出生的絕對時刻(節氣交接準確),日柱、時柱用出生地真太陽時(經度+均時差);附十神、藏干、納音、五行數量,給性別會排大運。可輸入農曆生日(含閏月)。kerykeion(Swiss Ephemeris,回歸黃道、普拉西度宮位):行星落座、宮位、逆行、主要相位、元素分布,並畫成中文星盤圖附在回覆上(svg2png.py 用伺服器的 Chromium/playwright 把 SVG 轉 PNG,SVG_PYTHON 可指定要用哪個 Python)。沒有出生時間時用中午計算並提醒宮位、上升不準。/播放 <歌曲>、/跳過、/暫停、/繼續、/停止、/佇列、system_prompt.txt,存檔後下一則回覆就生效,不用重開。
(上網工具的使用規則和現在時間是程式自動加在後面的,不用寫在這裡。).env,改完要 sudo systemctl restart discord-bot:
HISTORY_LIMIT:往回讀幾則訊息。越多越懂前後文,但模型處理越久。REASONING_EFFORT:none 最快;想要它多想一下改 low / medium / high。MAX_TOKENS:每次回覆長度上限。WEB_TOOLS=off:關掉上網/天氣。IMAGE_LOOKBACK、MAX_IMAGES、IMAGE_MAX_SIDE:看圖的範圍、張數、縮圖大小。sudo systemctl restart discord-bot # 重開
sudo systemctl stop discord-bot # 停
systemctl status discord-bot # 狀態
journalctl -u discord-bot -f # 即時 log
| 檔案 | 用途 |
|---|---|
bot.py | 主程式:Discord client、對話流程、/總結 /重置 /歡迎 /自動回覆 等指令(systemd 只啟動它) |
paths.py | 執行時資料(data/)的路徑統一在這裡決定 |
dbot/core/ | 核心與管理:models.py(/模型 切換與用量統計)、aliases.py(中文指令的英文名字對照)、dmlog.py(/私訊紀錄)、channels.py(開頻道、臨時語音房)、vstatus.py(語音頻道狀態)、memberstatus.py、actstatus.py |
dbot/ai/ | 給 AI 用的工具與生成:dbot/ai/divination.py+dbot/ai/divination_data/(占卜與籤詩周易原文、塔羅牌圖)、dbot/ai/fortune.py+svg2png.py(八字、星盤)、dbot/ai/drawimg.py(占卜與八字附圖)、extras.py(投票、抽籤、亂數、/狀態)、almanac.py、webimg.py、imagegen.py/sfxgen.py/videogen.py(畫圖、音效、影片) |
dbot/money/ | 代幣與帳務:account.py(錢包存取、莊家=大笨bot 的帳戶)、ledger.py(轉帳紀錄、帳本頻道、賭博彙整)、loans.py(借貸、還款、欠債扣款與催債)、minigames.py(老虎機、21 點)、horse_race.py(賽馬)、economy.py(斜線指令、給 Activity 用的內部 API,同時是對外窗口)、botwallet.py(大笨bot 自己的錢包工具:送錢、收還款、查帳) |
dbot/music/ | 音樂播放:tracks.py(歌曲、搜尋、播放紀錄)、player.py(每個伺服器一個播放器)、panel.py(面板按鈕)、persist.py(重啟後接著播)、actions.py(點歌、電台、控制)、ai_tools.py(給 AI 的工具)、music.py(斜線指令與入口) |
activity/ | Discord Activity 小遊戲(前端 src/、後端 server/,見下方) |
update-ytdlp.sh.example | 每週自動更新 yt-dlp 的範例腳本(改路徑後用 crontab 跑) |
.env | 所有設定與金鑰都在這一個檔(只有自己讀得到,不要外傳)。INTERNAL_KEY(機器人與 Activity 後端的內部金鑰)第一次啟動會自動產生寫進來,不用自己設 |
.env.example | 設定範本 |
system_prompt.txt | 機器人的個性設定 |
邀請連結(含斜線指令權限,把 YOUR_CLIENT_ID 換成 Discord Developer Portal 的 Application ID;權限值可依需要調整):
https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot+applications.commands&permissions=281475265154064
wallet.json,每個伺服器各自一本帳。/賽馬 /擲硬幣 /骰子 /老虎機 /21點)目前暫時下架,程式都還在:把 dbot/money/economy.py 的 GAMBLING_ENABLED 改成 True 再重啟機器人就會回來。同樣的遊戲仍可在 Discord Activity 裡玩(見下)。/規則(rules) /錢包(wallet) /排行(leaderboard) /轉帳(pay) /擲硬幣(coinflip) /骰子(dice) /老虎機(slots) /21點(blackjack)。/發錢 對象 金額(give):機器人擁有者專用,直接發代幣。/老虎機 賭注 [格數]:3 格(單排)、9 格(3×3,8 條連線)、16 格(4×4,整排整欄加兩條對角線共 10 條,4 格一樣才算,3 種圖案)。多格版可同時中很多條,3×3 只有 🍒🍋🔔💎 四種圖案(約 41% 的把數會賺錢,三個一樣 1.2~2.8 倍)。各版本理論回報率都調在約 95%。/賽馬 [等待秒數](horserace):開一場賽馬,6 匹馬從 10 匹固定名單隨機出賽,每匹有速度/耐力/爆發數值(存 horses.json)、當天狀態和歷史戰績(出賽、勝場、近 5 場名次)。賠率 = 0.95 ÷ 勝率,勝率由能力+狀態算出,所以強馬賠少、冷門賠多。按按鈕選馬、填賭注;每人一注,截止後播放跑道動畫並結算。機器人在比賽中途重啟,這場的賭注會損失。/借錢 金額 理由:跟大笨bot 借,由它(AI)判斷要不要借,理由正當就盡量借。一般最多 10 萬,手上錢越多可借越多(上限 50 萬)。利息每天 50%、複利,欠款最多滾到本金的 10 倍就不再增加。/還錢 還款、/債務 看欠多少;直接在聊天跟大笨bot 說「我要還錢」也可以。/設定帳本 頻道(需要「管理伺服器」權限)指定一個文字頻道,轉帳、借款、還款會逐筆發在那裡,賭博類輸贏每 10 分鐘彙整一則(同一個人合併)。/關閉帳本 關掉;沒設定就完全不發。紀錄本身仍存在 data/logs/transfers.json,大笨bot 查帳用。.env 的 ACTIVITY_GUILD_ID)。activity/)在語音頻道打開的內嵌遊戲視窗(Discord Embedded App SDK),WebSocket 即時同步。選單依序分五類:
web_image 工具搜圖(ddgs)、下載並貼到頻道;接著說「改成水彩風」就會用 edit_image 改剛找到的圖(暫存 30 分鐘、每頻道最近 3 張)。也可以直接給圖片網址。只抓公網的圖(擋內網位址)、單張 12 MB 以內、一定要是真的圖片;非 NSFW 頻道只搜安全內容。/畫圖、/智慧畫圖 有「大小」選項(一般/大圖長邊約 1900/超大圖長邊 2048,API 上限 2048),只有快速畫質支援;對話裡特別說要大張、高解析度時 bot 也會自己選。/畫圖 或對話說「畫一張…」,呼叫 LiteLLM 的圖片 API(draw-klein 快速/draw-qwen-fast 文字較乾淨/draw-flux 最高畫質約 10 分鐘),背景排隊、畫好自動貼回;內建過濾只擋涉及未成年人的性內容,不限張數(同時只畫一張、最多排 4 張),服務暫停時回覆「暫停中」。也能改圖(draw-klein,約 20 秒):傳圖並說「把背景改成白天」、回覆一張圖說怎麼改,或用 /改圖(最多 3 張參考圖,第一張是主圖)。畫圖和改圖預設只能在年齡限制(NSFW)頻道使用(IMAGE_NSFW_ONLY=off 可關)。設定見 .env.example。activity/server/games/board/botengine.js(alpha-beta + 靜止搜尋,直接用 chess.js/xq.js 的規則,所以走法一定合法),搜尋放在 botworker.js 的獨立執行緒、由 bots.js 管理(兩條輪流,逾時就隨便走一步不卡局)。新手只看一步、常亂走;普通看兩步;高手限時 0.9 秒、大師限時 3 秒。activity/.gitignore)。2–6 人,練習籌碼(起始 1000),可按空位加電腦玩家,其他人旁觀。發牌與判定全在伺服器(activity/server/games/table/poker.js)。
獨立玩法(不是賭博,不寫入賭博紀錄):每個身分一塊田(起始 6 塊,最多 24 塊),作物按真實時間生長,關掉 Activity 也照長,回來再收成。規則、數字、隨機全在 activity/server/games/life/farm.js,前端 src/farm.js 只畫田和送指令。
floor(產量/2))。單價 = 樹苗價 × 1.25 ÷ 一半的數量(進位),所以就算被偷到只剩一半,主人這一輪賣掉也至少是樹苗價的 1.25 倍,不會虧本。連續偷同一種果實,主人的紀錄會合併成「×N」。farm.json 的 pend)。floor(產量/2),主人至少留一半),偷菜沒有每天次數上限;偷到的放進自己的倉庫,被偷的人會在「最近發生的事」看到。data/records/activity/farm.json(含 Discord 使用者代號,已加入 .gitignore)。大家用 AI 畫圖、分類收藏的頁面(活動選單「創作 → 圖創區」)。畫的圖只顯示在這個頁面,不會傳到 Discord,用跟機器人相同的畫圖模型(LiteLLM)。
IMAGE_MAX_QUEUE(預設 4)張;內容只擋「性內容 + 未成年人」;每個伺服器最多留 400 張(GALLERY_MAX_IMAGES),超過刪最舊的。圖片與縮圖存在 activity/server/gallery_data/(GALLERY_DIR 可改,已加入 .gitignore)。這個頁面不受「畫圖只能在 NSFW 頻道」的限制,因為它不是 Discord 頻道。activity/server/media/gallery.js,大笨bot說話走機器人內部 API POST /gallery/chat(bot.py 的 gallery_chat);縮圖用 gallery_thumb.py(Pillow)。獨立玩法(不是賭博,不寫入賭博紀錄、不列在旁觀大廳):把一把劍鍛到最高 100 階(10 種材質 × 10 級,每一階都有程式畫的 SVG 外觀,越高階越華麗;神劍有旋轉光環)。每次鍛造要付鍛造費,有機率成功或劍碎(整把歸零);每階有賣價,隨時可賣。
/forge/role 通知機器人:同一個人一次只送一個請求,送完再檢查劍有沒有又變(避免連續鍛造時舊請求晚到、劍碎了身分組卻沒拔),活動後端每次啟動也會把所有真代幣玩家的身分組重新對一次。activity/server/games/life/forge.js:第 1 階約 47、第 50 階約 1.26 萬、第 70 階約 10.8 萬、第 90 階約 121 萬、第 100 階約 448 萬(真代幣賣出沒有上限);成功率前 49 階 97.3%→94.3%、50 階起 94%→91%;從零全部成功鍛到 100 階共花 100 萬,全部成功的機率:10 階約 74%、30 階約 33%、50 階約 12%、100 階約 0.23%。第 3 階起賣掉就賺;每一步的期望回收率:1~49 階約 103%、50 階以後約 101%,所以鍛造越久期望淨值越高(從零衝到 50 階再賣約 +530、70 階約 +950、100 階約 +2,600)。鍛造在活動選單最上面,獨立成一類。data/records/activity/forge.json(已 .gitignore):練習模式用瀏覽器識別碼,真代幣模式用 Discord 身分。真代幣的費用和賣出走機器人錢包,中途重啟由 escrow 退回/補發;真代幣的鍛造費超過單筆上限時分筆扣款。練習模式起始 10 萬練習幣。賭場分類。幾何在 activity/shared/stonegeo.js(伺服器和前端共用的純數學:石頭形狀、內部、切面格子),邏輯在 activity/server/games/casino/stone.js(隱藏的翡翠、外表線索、價格模型、收購商出價),金流在 server/casino.js(cstone 訊息:market/buy/cut(axis,pos)/sell/open,和 21 點一樣走託管,伺服器中途重啟會全額退回)。3D 畫面在 activity/src/stone3d.js(three.js,只在進賭石時才動態載入)。
RESTOCK_MS);市場只存在記憶體,重啟會重新擺貨。買的時候先從市場拿走再扣款,同時買同一顆只有一人成功,付款失敗會放回去。變動用 smkt 訊息即時推給所有人。bench/stfit.mjs 以模擬資料做 Poisson 迴歸得到的係數 BETA)估每公斤價,加價 12% 並加一點隨機誤差,所以看得準有機會撿便宜。整體價值/價格約 0.9。重量依價格範圍微調。MAX_PIECES)。石頭一開始是一塊盒子(座標軸對齊的 box),每一刀只切你選的那一塊:選軸(x/y/z)和位置(每 0.05,離該塊邊緣至少 0.1),付買價 3%,那塊變成兩塊(applyCut)。伺服器取該平面和翡翠體、裂的交集,回傳 48×48 格子(base64),前端畫成切面圖。切開後各塊保持分開(用裁切平面剪出並沿各刀法線稍微拉開,切面貼那張圖,見 stone3d.js 的 makeSplit)。pieceInfo/estBody):把所有切面上翡翠格子的世界座標範圍合起來,得到翡翠體在 x/y/z 的範圍(只在一個平面看到的方向厚度未知,用已知方向的幾何平均補;某方向有一刀完全沒切到翡翠,就把範圍限在同一邊),當成一個橢球。每一塊的翡翠 = 橢球落在該塊盒子裡的比例 × VOLK × 重量 × 切面平均等級單價 × OFFER_K,另加殘值(買價 × 該塊占石頭的比例 × 4%)。每塊的收購價 = 已看到的部分(上面的橢球)+ 預期(hope)+ 殘值。預期 = 買家看外表(場口、松花、霧、窗口等,用 marketPerKg)對整顆的期望價值 × 該塊占比 × 係數:還沒看到翡翠時係數是 HOPE0=0.65、每切一刀沒看到翡翠就 ×HOPE_DECAY=0.65;看到翡翠後,離橢球越近的塊預期越高(最多 HOPE_NEAR=0.25)。這個預期和賣家的開價不同(賣家有加價和誤差),所以外表看得準、買得比預期便宜的人有機會賺。收購價只依「目前看得到的」,不會偷看隱藏的真值。DENS_JADE(0.3) × 翡翠體積占比)× 石頭本身的密度差異(約 ±7%,所以重不一定有料);價格仍用普通石頭的重量算,所以偏沉的是便宜貨。資訊裡給重量和體積(公升),另外給一個有誤差的「手感」(偏輕/普通/稍沉/很沉,pub.heft)。stone3d.js 的 pickMode,射線打到石頭取 local 點再換成方向)。擦皮(rubAt,買價 1.5%,最多 4 處,買下後才能擦)看到該點內部(同窗口);打燈(lightAt,標價 0.5%,每顆最多 6 處,市場就能打)沿著往內的方向找最近的翡翠,依深度和皮厚的隨機誤差給 0~3 級透光與光的顏色(沒翡翠也有約 8% 的假訊號:石英脈透白光)。標記存在伺服器(市場階段存在 ws.notes,買下後帶進 st.marks),畫在 3D 上。sizeMult(kg)(0.1 公斤以下 ×0.5、1 公斤 ×1、5 公斤以上 ×1.5,取 log2 線性內插),估價和隱藏的真值都用;切碎翡翠會降價。KERF(0.04) 厚度的翡翠(applyCut 扣 hid.vol,估價也扣);切面上翡翠與裂同時出現(裂格數 ≥ 3)時有機率「崩」(機率 = 裂格數 × 0.06,最多 60%):翡翠體積 ×0.75、裂折損 ×0.8,並在切面註明,估價也跟著降。sell,piece = 編號或 "all"),每次賣出就結算那些塊;全部賣完後揭曉隱藏的翡翠(等級、體積、整顆真值、最大切面)。斷線自動賣出剩下的塊;真代幣的託管金額會隨已賣出的收入遞減。stone.js 的 TIERS/CUT_FEE/YIELD/OFFER_K/VOLK/SITES(數值還沒重新平衡,先把玩法做對)。Activity「桌遊・派對」分類,每個 instance 一桌,不足人數由電腦補,不用點數。伺服器 activity/server/games/table/avalon.js,畫面 activity/src/avalon.js。
賭場裡的 4 人牌桌、練習點數,每個 Activity instance 一桌,缺人由電腦補。伺服器 activity/server/games/table/bigtwo.js,牌型判斷在 activity/shared/bigtwo_rules.js(前後端共用),畫面 activity/src/bigtwo.js(沿用橋牌牌桌的 CSS)。
賭場裡的 4 人牌桌、練習點數(不碰代幣),每個 Activity instance 一桌。伺服器 activity/server/games/table/bridge.js,前端 activity/src/bridge.js。
bridge.js 的 PERSONA,跟著名字走,名字旁顯示標籤):愛搶叫、穩健、老狐狸、愛叫無王、保守、挺同伴、新手(偶爾亂出)、老派高花、高手、莽夫,調整叫牌膽量、支持同伴、無王門檻、改叫意願。「高手」橋神另外用抽樣模擬:把看不到的牌照已知缺門隨機發給另外三家,只留跟實際叫牌最吻合的幾組,叫牌時把每個選項(Pass 或各種叫品)的後續叫牌和打牌模擬完、出牌時每張候選牌都模擬打完,選得分/達成機率最高的。複式比較(同一副牌換人打)對上標準電腦平均每手多約 +19 點(每線位 100 點時)。測試工具:bridge.js 的 _playDeal、_deal。賭場裡兩張獨立的牌桌,4 人一桌、練習點數(不碰代幣),每個 Activity instance 各一桌。流程共用 activity/server/games/mahjong/mahjong.js,牌的編碼/向聽數/拆牌在 mjcore.js,計分在 mjtw.js(台數)和 mjjp.js(役、符、翻、點數);前端是 activity/src/mahjong.js。
mjcore.kindOf 換回牌種)、雙倍役滿不另計、一炮多響只算順位最近的一家。mahjong.js 的 PERSONA,跟著名字走,畫面上不顯示):速攻、穩健、老狐狸、愛吃碰、鐵壁、做大牌(清一色/混一色)、新手(會打錯)、門清派(只胡不叫)、高手、莽夫,調整吃碰積極度、立直機率、何時開始打安全牌、做色傾向。「高手」雀神另有一套判斷:日麻會讀牌防守(現物、立直後別人打過的牌、筋、壁、字牌見張算放槍危險度,依向聽數決定要衝還是棄和;有人立直、叫完還沒聽牌就不叫),並留寶牌、赤五、役牌對子;台麻實測防守反而吃虧,所以只保留手牌價值判斷。對上標準電腦:日麻東風戰平均名次約 2.3、台麻約 2.4(四人平均 2.5)。_simGame 可以指定四家電腦。activity/src/mjsfx.js,Web Audio 即時合成、不用音檔):開局洗牌、打牌、自己摸牌、吃碰、槓、立直、補花、輪到自己、可以叫牌、胡牌(自己胡更熱鬧)、放槍、流局;標題列 🔊 可以關,記在瀏覽器。mahjong.js 有 _simGame(rule, cfg, greedy) 可以讓 4 個電腦直接打完一整場(greedy 會什麼都叫、能槓就槓),用來檢查點數守恆和罕見流程。遊戲間「🎬 影音」裡的「📺 一起看影片」:同一個 Activity 的人同步看 YouTube。後端 activity/server/media/theater.js,前端 activity/src/theater.js。
video_cache/,已 .gitignore,超過 30 GB 自動刪最久沒看的),從 /api/tv/<影片ID>.mp4(720p 以外是 <影片ID>.q<畫質>.mp4)串流(支援 Range,可以拖進度)。整部下載好才開始播,清單接下來兩部會先下載。<影片ID>.q1080.mp4 這類檔名,也算在快取上限裡),準備好就從同一秒切過去,選擇記在瀏覽器。1080p 每人約 4~8 Mbps。/api/tv/sub/<影片ID>/<語言>.vtt,還在下載時回 202、前端每 3 秒再問),簡體中文字幕會在本機用 OpenCC 轉成繁體。不用 YouTube 的「自動翻譯」字幕(常被限流 429),也不用 AI 翻譯。openExternalLink 開 …/wordle/?room=<同一個房間>&g=theater,跟 Discord 裡的人同步,瀏覽器可以真正全螢幕。網址帶 ?g=遊戲代號 會直接開那個遊戲。所有人共用同一場;伺服器決定名次、每人畫面一致。10 匹馬的能力值、出賽、勝場、近 5 場存在 data/records/activity/horses.json(所有人共用,已 .gitignore;初始以 1000 場模擬當基本資料)。每匹有跑法(先行/逃馬/追込/穩定/爆發)和毛色,會影響動畫。下注頁每匹馬顯示戰鬥卡:能力雷達圖、歷史戰績、近 5 場、當天狀態、倍率;不顯示本場勝率,要自己判斷。
activity/(Vite 打包,npm install && npm run build,產物在 activity/dist/;前端改動只需重新 build)。把 VITE_CLIENT_ID(Application ID,不是密鑰)和 DISCORD_CLIENT_SECRET(真代幣模式登入用)都寫進專案根目錄的 .env,bot、前端、後端共用同一個檔。activity/server/(Node + ws,預設 127.0.0.1:3101,用 node server.js 或 systemd 常駐;後端改動需重啟)。賭場/撲克/賽馬紀錄等執行時資料(horses.json、casino_log.json、escrow.json…)都在這裡,不進 git。/ 指到你放 dist/ 的目錄;WebSocket 路徑 /ws 要轉到後端(Apache 用 ProxyPass /你的路徑/ws http://127.0.0.1:3101/ws upgrade=websocket)。/launch;整批同步指令時必須把它一起帶上(bot.py 的 sync_commands 已處理)。機器人和 Activity 產生的資料都集中在專案根目錄的 data/(不進 git):
data/records/:存檔與狀態——錢包、賽馬能力、機器人設定、音樂佇列、私訊名單;activity/ 子資料夾是農場、鍛造、抽卡、賭場託管、圖創區的圖。data/logs/:事件流水與紀錄——轉帳帳本(transfers.json)、機器人送錢紀錄、動作紀錄、播放紀錄;activity/ 子資料夾是賭場流水。paths.py(機器人)和 activity/server/paths.js(Activity)決定。從舊版升級時,第一次啟動會自動把舊位置的檔案搬進來。bot.py 機器人入口(systemd 只啟動它)
paths.py 執行時資料路徑
dbot/core/ 設定(config.py)、核心與管理 dbot/ai/ AI 工具、模型呼叫、畫圖指令
dbot/money/ 代幣與帳務(account/ledger/loans/小遊戲) dbot/music/ 音樂(tracks/player/panel…)
data/ 執行時資料(records=存檔、logs=流水),不進 git
activity/server/
server.js bet.js wager.js paths.js 伺服器入口與共用的押注/託管/路徑
games/board/ 棋類與電腦引擎 games/table/ 牌桌與桌遊
games/mahjong/ 麻將 games/action/ 動作遊戲(下樓梯、排球物理)
games/casino/ 賭場(含賭石、老虎機) games/life/ 經營(種菜、鍛造、抽卡)
media/ 一起看影片、圖創區
/隨機/佇列 也能把它叫到最下面。按鈕:⏯️ 暫停/繼續、⏭️ 跳過、🔀 隨機、⏹️ 停止;第二排 🔉🔊 調音量、📻 電台開關(開著時亮綠色,佇列空了自動接相似的歌)。/插播 <歌曲> [立刻播](英文 /playnext):插歌。預設插到「下一首」;「立刻播」選開就馬上播並跳過現在這首。也可以直接說「插一首周杰倫的晴天」,AI 會用 music 工具的 position(end/next/now)/移除 <編號或歌名>:從佇列拿掉某一首;/清空佇列:接下來的全拿掉(現在這首放完)/歷史:看播放紀錄(每首播過的歌自動記在 data/logs/play_history.json);/隨機循環 開|關:懶得選歌時,從紀錄隨機一直放,佇列空了自動補 5 首(避開最近播過的);也可以直接跟機器人說「隨便放」/投票 <題目> <選項1> <選項2> [選項3~5] [分鐘]:按鈕投票,每人一票可改票,時間到公布結果(重開機器人後進行中的投票會失效);/抽籤 <選項> [人數]:從一串選項隨機抽;/亂數 <最小> <最大> [數量] [不重複]:隨機抽數字(也可以直接跟機器人說「8到80隨機一個」,他會呼叫 random_number 工具,不會自己編);/狀態:看模型連線、延遲、啟動多久、有沒有在放歌(程式在 extras.py)/模型 [模型名稱]:看或切換 AI 模型(只有機器人擁有者能切;切之前會先試打一次,選擇存在 state.json)。線上模型(如 deepseek)計費,內容陣列壓成純文字(圖片照送,deepseek 看得懂圖),不送 Ollama 專用參數(keep_alive),但仍會送 reasoning_effort(REMOTE_REASONING_EFFORT,預設 none,因為 DeepSeek 不帶參數會思考、多花 3~4 倍費用);.env 可加 ADMIN_USER_IDS(逗號分隔)讓其他人也能切、LOCAL_MODELS(逗號分隔)標示哪些是本機模型。/狀態 會顯示今天和近 7 天各模型的呼叫次數與 token(程式在 models.py)/播放 = /play、/投票 = /poll、/亂數 = /random),做一樣的事;對照表在 aliases.py 的 TABLE,新增指令時記得在那裡加一行。/help 會顯示每個指令的英文名/餘額:查 DeepSeek 帳戶剩多少錢(只有機器人擁有者能查,結果頻道裡大家看得到;需在 .env 加 DEEPSEEK_API_KEY=,用 DeepSeek 官方的 /user/balance 查)/help:看所有指令/私訊紀錄 [使用者] [則數](英文 /dmlog):機器人擁有者專用、只有自己看得到。不填使用者列出最近私訊過機器人的人(記在 dm_users.json),指定使用者就讀出他跟機器人的私訊(太長會變成附件)。只看得到傳給機器人的私訊,看不到使用者之間的私訊。/help 裡有註明私訊內容擁有者看得到。/總結 [則數] [重點]:總結最近的對話(預設 100 則,最多 500)/重置:讓機器人忘掉這個頻道到目前為止的對話/自動回覆 開|關:這個頻道要不要每則都回(需要「管理頻道」權限)state.json 等 | 執行時資料(自動回覆頻道、錢包、播放紀錄、馬匹資料…),程式自己維護,已被 .gitignore 排除 |
discord-bot.service.example | systemd 服務檔範例(改使用者與路徑後裝到 /etc/systemd/system/) |
requirements.txt | Python 套件(建議用虛擬環境) |
run.bat | 在 Windows 上手動測試用(要連得到模型 API) |