def renewStatus(self, update: Update) -> None: """在每个command Handler前调用,是指令的前置函数""" self.lastchat = getchatid(update) if update.callback_query is None: if ischannel(update): self.lastuser = -1 else: self.lastuser = getfromid(update) self.lastmsgid = getmsgid(update) else: self.lastuser = update.callback_query.from_user.id self.lastmsgid = -1
def trynewcard(self, update: Update, context: CallbackContext) -> bool: """测试建卡,用于熟悉建卡流程。 测试创建的卡一定可以删除。 创建新卡指令的帮助见`/help newcard`, 对建卡过程有疑问,见 `/createcardhelp`。""" if isgroup(update): return self.errorInfo("发送私聊消息创建角色卡。") gp = self.getgp(-1) if gp is None: gp = self.creategp(-1) gp.kp = self.forcegetplayer(ADMIN_ID) return self.getnewcard(self.lastmsgid, -1, getchatid(update))
def delcard(self, update: Update, context: CallbackContext) -> bool: """KP才能使用该指令,删除一张卡片。一次只能删除一张卡。 `/delcard --cardid`:删除id为cardid的卡。""" if len(context.args) == 0: return self.errorInfo("需要卡id作为参数", True) if not isint(context.args[0]) or int(context.args[0]) < 0: return self.errorInfo("参数无效", True) cdid = int(context.args[0]) card = self.getcard(cdid) if card is None: return self.errorInfo("找不到对应id的卡") kp = self.forcegetplayer(update) if not self.checkaccess(kp, card) & CANMODIFY: return self.errorInfo("没有权限", True) # 开始处理 self.reply( f"请确认是否删除卡片\n姓名:{card.getname()}\n如果确认删除,请回复:确认。否则,请回复其他任何文字。") self.addOP(getchatid(update), "delcard "+context.args[0]) return True
def newcard(self, update: Update, context: CallbackContext) -> bool: """随机生成一张新的角色卡。需要一个群id作为参数。 只接受私聊消息。 如果发送者不是KP,那么只能在一个群内拥有最多一张角色卡。 如果不知道群id,请先发送`/getid`到群里获取id。 `/newcard`提交创建卡请求,bot会等待你输入`groupid`。 `/newcard --groupid`新建一张卡片,绑定到`groupid`对应的群。 `/newcard --cardid`新建一张卡片,将卡片id设置为`cardid`,`cardid`必须是非负整数。 `/newcard --groupid --cardid`新建一张卡片,绑定到`groupid`对应的群的同时,将卡片id设置为`cardid`。 当指定的卡id已经被别的卡占用的时候,将自动获取未被占用的id。 当生成时有至少三项基础属性低于50时,可以使用`/discard`来放弃并删除这张角色卡。 创建新卡之后,当前控制卡片会自动切换到新卡,详情参见 `/help switch`。 角色卡说明 一张角色卡具有: `groupid`,`id`,`playerid`基本信息。 STR,CON,SIZ,DEX,APP,INT,EDU,LUCK基本属性; 职业、姓名、性别、年龄; 技能信息; 背景故事(描述,重要之人,重要之地,珍视之物,特质,受过的伤,恐惧之物,神秘学物品,第三类接触); 检定修正值; 物品,财产; 角色类型(PL,NPC); 是否可以被删除; 状态(存活,死亡,疯狂等)。""" gpid: int = None gp: Optional[Group] = None newcdid: Optional[int] = None if isgroup(update): # 先检查是否有该玩家信息 rtbutton = [[InlineKeyboardButton( text="跳转到私聊", callback_data="None", url="t.me/"+self.bot.username)]] rp_markup = InlineKeyboardMarkup(rtbutton) if self.getplayer(update) is None: self.reply("请先开启与bot的私聊", reply_markup=rp_markup) return True if len(context.args) > 0: if not isint(context.args[0]) or int(context.args[0]) < 0: return self.errorInfo("参数无效") gpid = getchatid(update) gp = self.forcegetgroup(gpid) if len(context.args) > 0: newcdid = int(context.args[0]) elif len(context.args) > 0: msg = context.args[0] if not isint(msg): return self.errorInfo("输入无效") if int(msg) >= 0: newcdid = int(msg) else: gpid = int(msg) gp = self.forcegetgroup(gpid) if len(context.args) > 1: if not isint(context.args[1]) or int(context.args[1]) < 0: return self.errorInfo("输入无效") newcdid = int(context.args[1]) if gp is None: self.reply( "准备创建新卡。\n如果你不知道群id,在群里发送 /getid 即可创建角色卡。\n你也可以选择手动输入群id,请发送群id:") if newcdid is None: self.addOP(getchatid(update), "newcard " + str(update.message.message_id)) else: self.addOP(getchatid(update), "newcard " + str(update.message.message_id)+" "+str(newcdid)) return True # 检查(pl)是否已经有卡 pl = self.forcegetplayer(update) plid = pl.id if self.hascard(plid, gpid) and pl != gp.kp: return self.errorInfo("你在这个群已经有一张卡了!") # 符合建卡条件,生成新卡 # gp is not None assert(gpid is not None) remsgid = None if isprivate(update): remsgid = update.message.message_id else: assert rp_markup self.reply("建卡信息已经私聊发送", reply_markup=rp_markup) return self.getnewcard(remsgid, gpid, plid, newcdid)
def addcard(self, update: Update, context: CallbackContext) -> bool: """使用已有信息添加一张卡片,模板使用的是NPC/怪物模板。指令格式如下: `/addcard --attr_1 --val_1 --attr_2 --val_2 …… --attr_n -- val_n`, 其中`attr`是卡的直接属性或子属性。 卡的属性只有三种类型的值:`int`, `str`, `bool`,其他类型暂不支持用本指令。 函数会自动判断对应的属性是什么类型,其中`bool`类型`attr`对应的`val`只能是`true`, `True`, `false`, `False`之一。 不可以直接添加tempstatus这个属性。 如果需要添加主要技能点数,用mainpoints作为`attr`,兴趣技能点则用intpoints,清不要使用points。 如果要添加特殊技能,比如怪物的技能,请令`attr`为`specialskill`,`val`为`特殊技能名:技能值`。 技能值是正整数,技能名和技能值用英文冒号分开。 `name`和背景信息不支持空格,如果要设置这一项信息,需要之后用`/setbkg`来修改,所以尽量不要用该指令设置背景信息。 如果遇到无法识别的属性,将无法创建卡片。 参数中,必须的`attr`之一为`groupid`,如果找不到`groupid`将无法添加卡片。 `playerid`会自动识别为发送者,无需填写`playerid`。 指令使用者是KP的情况下,才可以指定`playerid`这个属性,否则卡片无效。 给定`id`属性的话,在指定的卡id已经被占用的时候,会重新自动选取。""" if isgroup(update): return self.errorInfo("向我发送私聊消息来添加卡", True) if len(context.args) == 0: return self.errorInfo("需要参数") if (len(context.args)//2)*2 != len(context.args): self.reply("参数长度应该是偶数") t = templateNewCard() # 遍历args获取attr和val mem: List[str] = [] for i in range(0, len(context.args), 2): argname: str = context.args[i] if argname in mem: return self.errorInfo(argname+"属性重复赋值") mem.append(argname) argval = context.args[i+1] if argname == "specialskill": skillname, skillval = argval.split(":") if not isint(skillval) or int(skillval) <= 0: return self.errorInfo("技能值应该是正整数") t["skill"]["skills"][skillname] = int(skillval) continue if argname == "points": return self.errorInfo("points应指明是mainpoints还是intpoints") if argname == "mainpoints": argname = "points" dt = t["skill"] elif argname == "intpoints": argname = "points" dt = t["interest"] dt = findattrindict(t, argname) if not dt: # 可能是技能,否则返回 if argname in self.skilllist or argname == "母语" or argname == "闪避": if not isint(argval) or int(argval) <= 0: return self.errorInfo("技能值应该是正整数") dt: dict = t["skill"]["skills"] dt[argname] = 0 # 这一行是为了防止之后判断类型报错 else: return self.errorInfo("属性 "+argname+" 在角色卡模板中没有找到") if isinstance(dt[argname], dict): return self.errorInfo(argname+"是dict类型,不可直接赋值") if type(dt[argname]) is bool: if argval == "false" or argval == "False": argval = False elif argval == "true" or argval == "True": argval = True if not type(argval) is bool: return self.errorInfo(argname+"应该为bool类型") dt[argname] = argval elif type(dt[argname]) is int: if not isint(argval): return self.errorInfo(argname+"应该为int类型") dt[argname] = int(argval) else: dt[argname] = argval # 参数写入完成 # 检查groupid是否输入了 if t["groupid"] == 0: return self.errorInfo("需要groupid!") # 检查是否输入了以及是否有权限输入playerid pl = self.forcegetplayer(update) if not self.searchifkp(pl): if t["playerid"] != 0 and t["playerid"] != pl.id: return self.errorInfo("没有权限设置非自己的playerid") t["playerid"] = getchatid(update) else: if t["groupid"] not in pl.kpgroups and t["playerid"] != 0 and t["playerid"] != pl.id: return self.errorInfo("没有权限设置非自己的playerid") if t["playerid"] == 0: t["playerid"] = pl.id # 生成成功 card1 = GameCard(t) # 添加id if "id" not in context.args or card1.id < 0 or card1.id in self.allids: self.reply("输入了已被占用的id,或id未设置,或id无效。自动获取id") card1.id = self.getoneid() # 生成衍生数值 card1.generateOtherAttributes() # 卡检查 rttext = card1.check() if rttext != "": self.reply( "卡片添加成功,但没有通过开始游戏的检查。") self.reply(rttext) else: self.reply("卡片添加成功") return True if self.addonecard(card1) else self.errorInfo("卡id重复")