Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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) |