cc2190-buddy 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/fast_buddy.mjs +152 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# cc2190-buddy
|
|
2
|
+
|
|
3
|
+
快速搜索 legendary + shiny 宠物,支持自定义物种、眼睛、帽子选项。
|
|
4
|
+
|
|
5
|
+
## 致谢
|
|
6
|
+
|
|
7
|
+
本项目使用了 [cc-buddy](https://www.npmjs.com/package/cc-buddy) 的部分代码,在其基础上进行了修改和简化。
|
|
8
|
+
|
|
9
|
+
## 安装使用
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx cc2190-buddy
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 功能
|
|
16
|
+
|
|
17
|
+
- 🎯 自动搜索 **LEGENDARY + SHINY** 宠物
|
|
18
|
+
- 🦆 可选物种(18种)
|
|
19
|
+
- 👀 可选眼睛样式(6种)
|
|
20
|
+
- 🎩 可选帽子(7种)
|
|
21
|
+
- ✏️ 自定义名字和性格
|
|
22
|
+
|
|
23
|
+
## 运行流程
|
|
24
|
+
|
|
25
|
+
1. 选择物种(可选)
|
|
26
|
+
2. 选择眼睛(可选)
|
|
27
|
+
3. 选择帽子(可选)
|
|
28
|
+
4. 输入名字(可选)
|
|
29
|
+
5. 输入性格(可选)
|
|
30
|
+
6. 开始搜索
|
|
31
|
+
7. 自动写入配置
|
|
32
|
+
|
|
33
|
+
搜索完成后,重启 Claude Code 并运行 `/buddy` 查看结果。
|
|
34
|
+
|
|
35
|
+
## 要求
|
|
36
|
+
|
|
37
|
+
- Node.js >= 16.0.0
|
|
38
|
+
- Claude Code >= 2.1.89
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT
|
package/fast_buddy.mjs
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 快速搜索 legendary + shiny 宠物,支持自定义选项
|
|
3
|
+
import { randomBytes } from 'node:crypto'
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, copyFileSync } from 'node:fs'
|
|
5
|
+
import { join } from 'node:path'
|
|
6
|
+
import { homedir } from 'node:os'
|
|
7
|
+
import { createInterface } from 'node:readline'
|
|
8
|
+
|
|
9
|
+
const CONFIG_PATH = join(homedir(), '.claude.json')
|
|
10
|
+
const SALT = 'friend-2026-401'
|
|
11
|
+
|
|
12
|
+
const SPECIES = ['duck','goose','blob','cat','dragon','octopus','owl','penguin','turtle','snail','ghost','axolotl','capybara','cactus','robot','rabbit','mushroom','chonk']
|
|
13
|
+
const SP_E = { duck:'🦆',goose:'🪿',blob:'🫧',cat:'🐱',dragon:'🐉',octopus:'🐙',owl:'🦉',penguin:'🐧',turtle:'🐢',snail:'🐌',ghost:'👻',axolotl:'🦎',capybara:'🦫',cactus:'🌵',robot:'🤖',rabbit:'🐰',mushroom:'🍄',chonk:'🐈' }
|
|
14
|
+
const RARITIES = ['common','uncommon','rare','epic','legendary']
|
|
15
|
+
const RARITY_W = { common:60, uncommon:25, rare:10, epic:4, legendary:1 }
|
|
16
|
+
const EYES = ['·','✦','×','◉','@','°']
|
|
17
|
+
const HATS = ['none','crown','tophat','propeller','halo','wizard','beanie','tinyduck']
|
|
18
|
+
const HAT_E = { none:'—',crown:'👑',tophat:'🎩',propeller:'🧢',halo:'😇',wizard:'🧙',beanie:'⛑',tinyduck:'🐤' }
|
|
19
|
+
const STATS = ['DEBUGGING','PATIENCE','CHAOS','WISDOM','SNACK']
|
|
20
|
+
const RARITY_FLOOR = { common:5, uncommon:15, rare:25, epic:35, legendary:50 }
|
|
21
|
+
|
|
22
|
+
// ANSI colors
|
|
23
|
+
const E = { rs:'\x1b[0m',b:'\x1b[1m',c:'\x1b[36m',g:'\x1b[32m',y:'\x1b[33m',m:'\x1b[35m',d:'\x1b[2m' }
|
|
24
|
+
const c = (code, text) => `${code}${text}${E.rs}`
|
|
25
|
+
|
|
26
|
+
// wyhash
|
|
27
|
+
const M64=(1n<<64n)-1n,WYP=[0xa0761d6478bd642fn,0xe7037ed1a0b428dbn,0x8ebc6af09c88c6e3n,0x589965cc75374cc3n]
|
|
28
|
+
function _mx(A,B){const r=(A&M64)*(B&M64);return((r>>64n)^r)&M64}
|
|
29
|
+
function _r8(p,i){return BigInt(p[i])|(BigInt(p[i+1])<<8n)|(BigInt(p[i+2])<<16n)|(BigInt(p[i+3])<<24n)|(BigInt(p[i+4])<<32n)|(BigInt(p[i+5])<<40n)|(BigInt(p[i+6])<<48n)|(BigInt(p[i+7])<<56n)}
|
|
30
|
+
function _r4(p,i){return BigInt(p[i])|(BigInt(p[i+1])<<8n)|(BigInt(p[i+2])<<16n)|(BigInt(p[i+3])<<24n)}
|
|
31
|
+
function _r3(p,i,k){return(BigInt(p[i])<<16n)|(BigInt(p[i+(k>>1)])<<8n)|BigInt(p[i+k-1])}
|
|
32
|
+
function wyhash(key,seed=0n){const len=key.length;seed=(seed^_mx(seed^WYP[0],WYP[1]))&M64;let a,b;if(len<=16){if(len>=4){a=((_r4(key,0)<<32n)|_r4(key,((len>>3)<<2)))&M64;b=((_r4(key,len-4)<<32n)|_r4(key,len-4-((len>>3)<<2)))&M64}else if(len>0){a=_r3(key,0,len);b=0n}else{a=0n;b=0n}}else{let i=len,p=0;if(i>48){let s1=seed,s2=seed;do{seed=_mx(_r8(key,p)^WYP[1],_r8(key,p+8)^seed);s1=_mx(_r8(key,p+16)^WYP[2],_r8(key,p+24)^s1);s2=_mx(_r8(key,p+32)^WYP[3],_r8(key,p+40)^s2);p+=48;i-=48}while(i>48);seed=(seed^s1^s2)&M64}while(i>16){seed=_mx(_r8(key,p)^WYP[1],_r8(key,p+8)^seed);i-=16;p+=16}a=_r8(key,p+i-16);b=_r8(key,p+i-8)}a=(a^WYP[1])&M64;b=(b^seed)&M64;const r=(a&M64)*(b&M64);a=r&M64;b=(r>>64n)&M64;return _mx((a^WYP[0]^BigInt(len))&M64,(b^WYP[1])&M64)}
|
|
33
|
+
function hWy(s){return Number(wyhash(Buffer.from(s,'utf8'))&0xffffffffn)}
|
|
34
|
+
|
|
35
|
+
function prng(seed){let a=seed>>>0;return()=>{a|=0;a=(a+0x6d2b79f5)|0;let t=Math.imul(a^(a>>>15),1|a);t=(t+Math.imul(t^(t>>>7),61|t))^t;return((t^(t>>>14))>>>0)/4294967296}}
|
|
36
|
+
function pick(rng,arr){return arr[Math.floor(rng()*arr.length)]}
|
|
37
|
+
function rollRar(rng){let r=rng()*100;for(const x of RARITIES){r-=RARITY_W[x];if(r<0)return x}return'common'}
|
|
38
|
+
function rollStats(rng,rar){const fl=RARITY_FLOOR[rar],pk=pick(rng,STATS);let dp=pick(rng,STATS);while(dp===pk)dp=pick(rng,STATS);const s={};for(const n of STATS){if(n===pk)s[n]=Math.min(100,fl+50+Math.floor(rng()*30));else if(n===dp)s[n]=Math.max(1,fl-10+Math.floor(rng()*15));else s[n]=Math.min(100,fl+Math.floor(rng()*40))}return s}
|
|
39
|
+
function roll(uid,salt=SALT){const rng=prng(hWy(uid+salt)),rar=rollRar(rng);return{rarity:rar,species:pick(rng,SPECIES),eye:pick(rng,EYES),hat:rar==='common'?'none':pick(rng,HATS),shiny:rng()<0.01,stats:rollStats(rng,rar)}}
|
|
40
|
+
|
|
41
|
+
function readCfg(){if(!existsSync(CONFIG_PATH))return null;try{return JSON.parse(readFileSync(CONFIG_PATH,'utf8'))}catch{return null}}
|
|
42
|
+
|
|
43
|
+
function writeConfig(uid, buddy, name, personality){
|
|
44
|
+
const cfg=readCfg()||{}
|
|
45
|
+
if(existsSync(CONFIG_PATH))copyFileSync(CONFIG_PATH,CONFIG_PATH+`.bak.${Date.now()}`)
|
|
46
|
+
cfg.userID=uid
|
|
47
|
+
cfg.companion={hatchedAt:cfg.companion?.hatchedAt||Date.now()}
|
|
48
|
+
const bones={species:buddy.species,rarity:buddy.rarity,eye:buddy.eye,hat:buddy.hat,shiny:buddy.shiny,stats:buddy.stats}
|
|
49
|
+
cfg.companionOverride=bones
|
|
50
|
+
cfg.companion.bones=bones
|
|
51
|
+
Object.assign(cfg.companion,bones)
|
|
52
|
+
if(name)cfg.companion.name=name
|
|
53
|
+
if(personality)cfg.companion.personality=personality
|
|
54
|
+
writeFileSync(CONFIG_PATH,JSON.stringify(cfg,null,2),'utf8')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 交互式选择
|
|
58
|
+
const ask = q => new Promise(r => { const rl = createInterface({input:process.stdin,output:process.stdout}); rl.question(q, a => { rl.close(); r(a.trim()) }) })
|
|
59
|
+
|
|
60
|
+
async function select(title, items, allowSkip=false){
|
|
61
|
+
console.log(`\n ${c(E.b,title)}\n`)
|
|
62
|
+
items.forEach((it,i) => console.log(` ${c(E.c,`[${i+1}]`)} ${it}`))
|
|
63
|
+
if(allowSkip) console.log(` ${c(E.d,`[0] 不限制`)}`)
|
|
64
|
+
const a = await ask(`\n ${c(E.c,'>')} `)
|
|
65
|
+
const idx = parseInt(a)-1
|
|
66
|
+
if(allowSkip && a==='0') return null
|
|
67
|
+
return idx>=0&&idx<items.length ? items[idx] : (allowSkip?null:items[0])
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function main(){
|
|
71
|
+
console.log(`\n ${c(E.b+E.c,'🎰 快速 Buddy 搜索器')}`)
|
|
72
|
+
console.log(` ${c(E.d,'目标: LEGENDARY + SHINY ✨')}\n`)
|
|
73
|
+
|
|
74
|
+
// 选择物种
|
|
75
|
+
const speciesList = SPECIES.map(s => `${SP_E[s]} ${s}`)
|
|
76
|
+
const species = await select('选择物种 (可选)', speciesList, true)
|
|
77
|
+
console.log(species ? ` ✓ 物种: ${SP_E[species]} ${species}` : ` ✓ 物种: 不限制`)
|
|
78
|
+
|
|
79
|
+
// 选择眼睛
|
|
80
|
+
const eyeList = EYES.map(e => ` ${e}`)
|
|
81
|
+
const eye = await select('选择眼睛 (可选)', eyeList, true)
|
|
82
|
+
console.log(eye ? ` ✓ 眼睛: ${eye}` : ` ✓ 眼睛: 不限制`)
|
|
83
|
+
|
|
84
|
+
// 选择帽子
|
|
85
|
+
const hatList = HATS.map(h => `${HAT_E[h]} ${h}`)
|
|
86
|
+
const hat = await select('选择帽子 (可选)', hatList, true)
|
|
87
|
+
console.log(hat ? ` ✓ 帽子: ${HAT_E[hat]} ${hat}` : ` ✓ 帽子: 不限制`)
|
|
88
|
+
|
|
89
|
+
// 输入名字
|
|
90
|
+
const name = await ask(`\n ${c(E.m,'✏️')} 输入名字 (回车跳过): `)
|
|
91
|
+
console.log(name ? ` ✓ 名字: ${name}` : ` ✓ 名字: 自动生成`)
|
|
92
|
+
|
|
93
|
+
// 输入性格
|
|
94
|
+
const personality = await ask(` ${c(E.m,'✏️')} 输入性格 (回车跳过): `)
|
|
95
|
+
console.log(personality ? ` ✓ 性格: ${personality}` : ` ✓ 性格: 自动生成`)
|
|
96
|
+
|
|
97
|
+
// 开始搜索
|
|
98
|
+
console.log(`\n ${c(E.b,'🎯 开始搜索...')}\n`)
|
|
99
|
+
const start=Date.now()
|
|
100
|
+
let found=null
|
|
101
|
+
let attempts=0
|
|
102
|
+
const maxAttempts=1_000_000_000
|
|
103
|
+
|
|
104
|
+
for(let i=0;i<maxAttempts;i++){
|
|
105
|
+
const uid=randomBytes(32).toString('hex')
|
|
106
|
+
const buddy=roll(uid)
|
|
107
|
+
attempts++
|
|
108
|
+
|
|
109
|
+
// 检查条件: legendary + shiny + 可选的物种、眼睛和帽子
|
|
110
|
+
const matchRarity = buddy.rarity==='legendary'
|
|
111
|
+
const matchShiny = buddy.shiny
|
|
112
|
+
const matchSpecies = !species || buddy.species===species
|
|
113
|
+
const matchEye = !eye || buddy.eye===eye
|
|
114
|
+
const matchHat = !hat || buddy.hat===hat
|
|
115
|
+
|
|
116
|
+
if(matchRarity && matchShiny && matchSpecies && matchEye && matchHat){
|
|
117
|
+
found={uid,buddy}
|
|
118
|
+
console.log(`\n${c(E.g+E.b,' ✓ 找到了!')}`)
|
|
119
|
+
console.log(` 尝试次数: ${attempts.toLocaleString()}`)
|
|
120
|
+
console.log(` 耗时: ${(Date.now()-start)/1000}s`)
|
|
121
|
+
break
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if(i>0 && i%100_000===0){
|
|
125
|
+
process.stdout.write(`\r ${c(E.d,`已搜索 ${i.toLocaleString()} 次...`)}`)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if(found){
|
|
130
|
+
console.log(`\n${c(E.b,' ════════════════════════════════════')}`)
|
|
131
|
+
console.log(`${c(E.b,' 🎉 宠物信息:')}`)
|
|
132
|
+
console.log(`${c(E.b,' ════════════════════════════════════')}`)
|
|
133
|
+
console.log(` ${SP_E[found.buddy.species]} ${c(E.y+E.b,found.buddy.species.toUpperCase())}`)
|
|
134
|
+
console.log(` ${c(E.y,'★★★★★')} legendary ${c(E.y,'✨ SHINY!')}`)
|
|
135
|
+
console.log(` 眼睛: ${found.buddy.eye}`)
|
|
136
|
+
console.log(` 帽子: ${HAT_E[found.buddy.hat]} ${found.buddy.hat}`)
|
|
137
|
+
console.log(`\n 属性:`)
|
|
138
|
+
for(const [n,v] of Object.entries(found.buddy.stats)){
|
|
139
|
+
const bar='█'.repeat(Math.round(v/5))+'░'.repeat(20-Math.round(v/5))
|
|
140
|
+
console.log(` ${n.padEnd(10)} ${c(v>=80?E.g:v>=50?E.y:E.d,bar)} ${v}`)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log(`\n 写入配置...`)
|
|
144
|
+
writeConfig(found.uid, found.buddy, name, personality)
|
|
145
|
+
console.log(`${c(E.g+E.b,' ✓ 完成!')}`)
|
|
146
|
+
console.log(`\n ${c(E.c,'重启 Claude Code 运行 /buddy 查看结果')}`)
|
|
147
|
+
}else{
|
|
148
|
+
console.log(`\n${c(E.y,' ⚠ 未找到,请再运行一次或放宽条件')}`)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main()
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc2190-buddy",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "快速搜索 legendary + shiny 宠物,支持自定义物种、眼睛、帽子选项",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cc2190-buddy": "./fast_buddy.mjs"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node fast_buddy.mjs"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"buddy",
|
|
16
|
+
"pet",
|
|
17
|
+
"reroll",
|
|
18
|
+
"companion",
|
|
19
|
+
"anthropic",
|
|
20
|
+
"legendary",
|
|
21
|
+
"shiny"
|
|
22
|
+
],
|
|
23
|
+
"author": "ssooddaa",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=16.0.0"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"fast_buddy.mjs",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"README.md"
|
|
32
|
+
]
|
|
33
|
+
}
|