Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增换老婆指令相关,解决issue #18

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
"koishi": "^4.17.7"
},
"devDependencies": {
"@koishijs/cache": "^2.1.0"
"@koishijs/cache": "^2.1.0",
"koishi": "^4.17.7"
},
"koishi": {
"description": {
"en": "Marry with your groupmate",
"zh": "娶群友!来寻找你今日的群友老婆吧!"
},
"browser": true
}
},
"packageManager": "[email protected]"
}
5 changes: 4 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
## 可选的

### 特性

* 避免用户抽中他人的老婆
* 只让用户抽中活跃的群友

### 指令

* 强娶
* 求婚
* 离婚
* 离婚
* 换老婆
165 changes: 154 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,29 @@ export const inject = ['cache']
declare module '@koishijs/cache' {
interface Tables {
[key: `waifu_members_${string}`]: Universal.GuildMember

[key: `waifu_members_active_${string}`]: string

[key: `waifu_marriages_${string}`]: string

[key: `waifu_times_${string}`]: number
}
}

export interface Config {
avoidNtr: boolean
onlyActiveUser: boolean
activeDays: number
forceMarry: boolean
propose: boolean
divorce: boolean
excludeUsers: {
uid: string
note?: string
}[]
maxTimes: number
isBinding: boolean
forceMarry: boolean
propose: boolean
divorce: boolean
changeWaifu: boolean
}

export const Config: Schema<Config> = Schema.intersect([
Expand All @@ -34,14 +41,17 @@ export const Config: Schema<Config> = Schema.intersect([
excludeUsers: Schema.array(Schema.object({
uid: Schema.string().required(),
note: Schema.string()
})).role('table').default([{ uid: 'red:2854196310', note: 'Q群管家' }])
})).role('table').default([{ uid: 'red:2854196310', note: 'Q群管家' }]),
maxTimes: Schema.natural().default(2),
isBinding: Schema.boolean().default(true)
}).i18n({
'zh-CN': require('./locales/zh-CN'),
}),
Schema.object({
forceMarry: Schema.boolean().description('是否启用强娶指令').default(false),
propose: Schema.boolean().description('是否启用求婚指令').experimental().default(false),
divorce: Schema.boolean().description('是否启用离婚指令').experimental().default(false),
changeWaifu: Schema.boolean().description('是否启用换老婆指令').experimental().default(false)
}).description('附加指令')
])

Expand Down Expand Up @@ -74,7 +84,8 @@ export function apply(ctx: Context, cfg: Config) {
const { data } = await session.bot.getGuildMemberList(session.guildId, next)
result.push(...data)
}
} catch { }
} catch {
}
if (!result.length) {
for await (const value of ctx.cache.values(`waifu_members_${gid}`)) {
result.push(value)
Expand All @@ -95,7 +106,8 @@ export function apply(ctx: Context, cfg: Config) {
let selected: Universal.GuildMember
try {
selected = await session.bot.getGuildMember(session.guildId, target)
} catch { }
} catch {
}
try {
const member = await ctx.cache.get(`waifu_members_${gid}`, target)
if (!selected) {
Expand All @@ -105,10 +117,12 @@ export function apply(ctx: Context, cfg: Config) {
selected.user ??= member.user
selected.user.name ??= member.user.name
}
} catch { }
} catch {
}
try {
selected ??= { user: await session.bot.getUser(target) }
} catch { }
} catch {
}
const [name, avatar] = getMemberInfo(selected, target)
return session.text('.marriages', {
quote: h.quote(session.messageId),
Expand Down Expand Up @@ -156,7 +170,11 @@ export function apply(ctx: Context, cfg: Config) {
}
const maxAge = getMaxAge()
await ctx.cache.set(`waifu_marriages_${gid}`, session.userId, selectedId, maxAge)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, session.userId, maxAge)
if (cfg.isBinding && cfg.avoidNtr)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, session.userId, maxAge)

//记录已经结婚,设置times为1,确保用户下次调用换老婆时能够获得正确的次数
await ctx.cache.set(`waifu_times_${gid}`, session.userId, 1, maxAge);

const [name, avatar] = getMemberInfo(selected, selectedId)
return session.text('.marriages', {
Expand Down Expand Up @@ -197,7 +215,8 @@ export function apply(ctx: Context, cfg: Config) {
const selectedId = selected.user.id
const maxAge = getMaxAge()
await ctx.cache.set(`waifu_marriages_${gid}`, session.userId, selectedId, maxAge)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, session.userId, maxAge)
if (cfg.isBinding && cfg.avoidNtr)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, session.userId, maxAge)

const [name, avatar] = getMemberInfo(selected, selectedId)
return session.text('.force-marry', {
Expand Down Expand Up @@ -239,6 +258,7 @@ export function apply(ctx: Context, cfg: Config) {
const selectedId = selected.user.id
const [name, avatar] = getMemberInfo(selected, selectedId)


await session.send(
session.text('.request', {
targetAt: h.at(selected.user.id),
Expand All @@ -262,6 +282,15 @@ export function apply(ctx: Context, cfg: Config) {
if (reply === '我愿意') {
dispose()
clearTimeout(timeoutId)
const isMarriaged = await ctx.cache.get(`waifu_marriages_${gid}`, selectedId);
if (isMarriaged) {
await send(
text('commands.propose.messages.already-marriage2', {
quote: h.at(selectedId)
})
)
return
}
const maxAge = getMaxAge()
await ctx.cache.set(`waifu_marriages_${gid}`, sourceUserId, selectedId, maxAge)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, sourceUserId, maxAge)
Expand Down Expand Up @@ -301,11 +330,125 @@ export function apply(ctx: Context, cfg: Config) {
quote: h.quote(session.messageId)
})
} else {
ctx.cache.delete(`waifu_marriages_${gid}`, marriage)
ctx.cache.delete(`waifu_marriages_${gid}`, session.userId)
return session.text('.divorcement', {
quote: h.quote(session.messageId)
})
}
})
}
}

if (cfg.changeWaifu) {
ctx.command('change-waifu')
.alias('换老婆')
.action(async ({ session }) => {
if (!session.guildId) {
return session.text('.members-too-few');
}
const { gid } = session
const marriage = await ctx.cache.get(`waifu_marriages_${gid}`, session.userId);

const times = await ctx.cache.get(`waifu_times_${gid}`, session.userId);
if (times > cfg.maxTimes && cfg.maxTimes != 0) {
if (marriage) {
if (cfg.isBinding && cfg.avoidNtr)
ctx.cache.delete(`waifu_marriages_${gid}`, marriage);
ctx.cache.delete(`waifu_marriages_${gid}`, session.userId);
}
return session.text(".times-too-many", {
quote: h.quote(session.messageId)
});
} else if (!marriage || times == 0 || typeof times == 'undefined') {
return session.text(".not-married", {
quote: h.quote(session.messageId)
});
}
const excludes = cfg.excludeUsers.map(({ uid }) => uid);
excludes.push(session.uid, session.sid);
const memberList = await getMemberList(session, gid);
let list = memberList.filter((v) => {
return v.user && !excludes.includes(`${session.platform}:${v.user.id}`) && !v.user.isBot;
});
if (cfg.onlyActiveUser) {
let activeList = [];
for await (const value of ctx.cache.keys(`waifu_members_active_${gid}`)) {
activeList.push(value);
}
list = list.filter((v) => activeList.find((active) => active === v.user.id));
}

//如果没有人,就返回members-too-few
if (list.length === 0) return session.text(".members-too-few");

//随机获取一个人,并且获取他的id和marriages信息
let selected = Random.pick(list);
let selectedId = selected.user.id;
const selectedTarget = await ctx.cache.get(`waifu_marriages_${gid}`, selectedId);

//获取被选中的人的信息
if (selectedTarget) {
selected = Random.pick(list);
selectedId = selected.user.id;
}

//避免 ntr
if (cfg.avoidNtr) {
let i = 0;
//循环判断,如果选中的人还是结婚,那么就重新获取一个
while (true) {
const selectedTarget2 = await ctx.cache.get(`waifu_marriages_${gid}`, selectedId);
if (selectedTarget2) {
selected = Random.pick(list);
selectedId = selected.user.id;
} else {
//跳出循环
break;
}
//循环次数如果超过,那么就返回人太少
i++;
if (i > list.length) return session.text(".members-too-few");
}
}

//如果程序运行到这里,那么说明已经获取了一个新的人,那么就继续

//解绑当前关系
if (cfg.isBinding && cfg.avoidNtr)
ctx.cache.delete(`waifu_marriages_${gid}`, marriage);
ctx.cache.delete(`waifu_marriages_${gid}`, session.userId);

//绑定新的关系
const maxAge = getMaxAge();

await ctx.cache.set(`waifu_marriages_${gid}`, session.userId, selectedId, maxAge);
if (cfg.isBinding && cfg.avoidNtr)
await ctx.cache.set(`waifu_marriages_${gid}`, selectedId, session.userId, maxAge);



//请求次数+1
await ctx.cache.set(`waifu_times_${gid}`, session.userId, times + 1, maxAge);


const [name2, avatar] = getMemberInfo(selected, selectedId);
if (times == cfg.maxTimes && cfg.maxTimes != 0) {
return session.text(".last-times", {
quote: h.quote(session.messageId),
name: name2,
avatar: avatar && h.image(avatar)
});
} else if (times < cfg.maxTimes || cfg.maxTimes == 0) {
return session.text(".change-success", {
quote: h.quote(session.messageId),
name: name2,
avatar: avatar && h.image(avatar)
});
} else {
return session.text("Error");
}


});
}
}
13 changes: 12 additions & 1 deletion src/locales/zh-CN.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
avoidNtr: 是否避免用户抽中他人的老婆
onlyActiveUser: 是否只让用户抽中活跃的群友
activeDays: 活跃天数最小值 (onlyActiveUser 判断活跃的标准)
maxTimes: 每日换老婆次数上限 (对换老婆指令生效,0 为不限制)
isBinding: "是否在用户使用娶群友、强娶、换老婆指令时改变双方状态\n(开启 avoidNtr 时才有效,且求婚和离婚指令固定生效)"
excludeUsers:
$description: 排除的用户
$value:
Expand Down Expand Up @@ -28,11 +30,20 @@ commands:
failure: '{quote}对方拒绝了'
no-target: '{quote}向谁求婚呀~'
already-marriage: '{quote}你已经有对象了,今天别再求婚啦!'
already-marriage2: '{quote} 你已经有对象了,怎么能接受别人求婚呢!'
members-too-few: 能求婚的群友没有这位,或许可以先把对方骗出来聊天?!
target-self: '{quote}向自己求婚干嘛!'
request: '{targetAt} {targetAvatar}<br/>群友「{name}」向你求婚,那么...你愿意嫁给ta吗?在{time}秒内发送【{agree}】或者【{reject}】,回应对方哦!'
divorce:
description: 和群友离婚
messages:
not-married: '{quote}你还是只单身狗,不能离婚!'
divorcement: '{quote}你已经离婚,江湖有缘再相见~'
divorcement: '{quote}你已经离婚,江湖有缘再相见~'
changewaifu:
description: "换老婆"
messages:
not-married: '{quote}你没有老婆,不能换!'
change-success: '{quote}换好了!你今日的老婆是:{name}{avatar}'
last-times: '{quote}再换你就没老婆了!你今日的老婆是:{name}{avatar}'
times-too-many: '{quote}渣男,你今天没老婆了!'
members-too-few: 能换的群友没有了!