蓝图计划 是 [镜芯] 旗下由一铭负责开发的QQ频道图片对战机器人

项目提示

由于编写的比较仓促,很多细节都没有去处理,需要你们自己去填坑,就当提升一下技能吧

项目结构

xiangsu.py 是图像处理模块,负责处理所有图像事务
ymsql.py 是游戏逻辑以及数据库接口
xs_bot.py 负责与频道机器人建立连接,传受数据,控制对局
bk-demo2.png 一个背景模板

运行流程

xs_bot.py 收到消息后,初始化消息,处理完毕后传入到ymsql.py
ymsql.py 对传入的消息进行处理,传出处理结果
xiangsu.py 生成对局图片到缓存路径,返回图片名称,url

坑位提示

1.SQL未每次执行都写入数据库
2.SQL注入并未完美解决
3.ymsql.py写的太垃圾了
4.需要自己去修改胜利条件,对局人数,用你善于发现的眼睛找一找
5.由于数据库版本及数据库自身问题的原因,可能存在神奇的问题
6.如果运行模式改为异步
7.没有做全局配置
8.你可能没有好好看这个文档

运行环境

运行环境:
环境:无限制 Python3.7 Mysql5.6

一个web服务器
一个可用的qq频道机器人账号
申请地址:https://q.qq.com/#/
(其他应用场景需要自己对接xiangsu.py模块去开发使用)

安装方法

安装方法
1.安装web服务器,安装mysql,安装python3.7,可使用宝塔一键安装
2.修改ymsql.py内数据库相关信息
3.修改xs_bot.py内机器人botid和token
4.修改所有源码内文件缓存路径
5.安装依赖Pillow qq-bot
6.导入xiangsu.sql

运行主程序
python xs_bot.py

源码下载

蓝图计划-完整代码下载

部分代码展示

# 数据库操作方法
class AdminSql:
	'''
	playid : 对局ID
	membid : 对局成员ID
	'''
	# 链接数据库
	def __init__(self,playid='',membid=''):
		self.db_con = pymysql.connect(host='localhost',port=3306,db=db,user=user,password=password)
		self.cursor = self.db_con.cursor()
		# 用户顺序颜色列表
		self.user_colors = {1:(106,123,222),2:(106,196,222)
					,3:(42,100,114),4:(87,87,87)
					,5:(199,75,75),6:(76,205,97)}

	# 关闭数据库连接
	def Closedb(self):
		self.db_con.close()

	# 创建一个对局
	# 需传入  用户id,用户昵称,用户头像url,频道id,频道昵称
	# 根据用户参加游戏的顺序给定用户颜色,默认为第一个(106,123,222)
	def Creat_Play(self,uid,name,author,chanid,chanme):

		# 首先查询用户是否在对局中
		seart = self.Saech_User_Play_stau(uid)
		user_stau = int(seart['code'])
		# 202则表示该用户不存在
		# 可进行对局创建
		# 同时初始化写入该用户信息
		if user_stau == 202:
			# 获取一个可用的gameid
			gameid = self._Get_New_Gameid()
			# 对局创建的时间
			create = int(time.time())
			# 写入一个新的对局
			#new_games = '''INSERT INTO `xiangsu`.`Ex_games` (`id`, `gameid`, `users`, `status`, `modtime`, `gametype`, `mateid`, `souruse`, `create`, `templ`) VALUES (null, '%s', '[{"id":"%s","name":"%s","author":"%s","color":(106,123,222),"had":"0"}]', '1', '%s', '0', '{"id":"%s","name":"%s"}', '{"id":"%s","name":"%s"}', '%s', '0')'''%(gameid,uid,name,author,create,chanid,chanme,uid,name,create)
			new_games = '''INSERT INTO `xiangsu`.`Ex_games` (`gameid`, `users`, `status`, `modtime`, `gametype`, `mateid`, `souruse`, `create`, `templ`) VALUES (%s, '[{"id":"%s","name":"%s","author":"%s","color":(106,123,222),"had":"0"}]', 1, '%s', 0, '{"id":"%s","name":"%s"}', '{"id":"%s","name":"%s"}', '%s', '0')'''%(gameid,uid,name,author,create,chanid,chanme,uid,name,create)
			print(new_games)
			self.cursor.execute(new_games)
			# 新增一个用户
			self._Insert_user_info(uid,name,chanid,chanme,gameid)
			# 设置对局状态为等待中
			self.Set_Game_Done(gameid,1)
			msg = {"code":200,"msg":"创建对局成功","gameid":gameid}
			return msg

		# 203表示参数无效
		if user_stau == 203:
			msg = {"code":203,"msg":"接收到了无效参数"}
			return msg

		# 201表示用户存在,但不在对局中
		# 为用户创建新对局,更新用户对局信息
		if user_stau == 201:
			# 获取一个最新的可用对局ID
			gameid = self._Get_New_Gameid()
			# 对局创建的时间
			create = int(time.time())
			# 写入一个新的对局
			#new_games = '''INSERT INTO `xiangsu`.`Ex_games` (`id`, `gameid`, `users`, `status`, `modtime`, `gametype`, `mateid`, `souruse`, `create`, `templ`) VALUES (null, '%s', '[{"id":"%s","name":"%s","author":"%s","color":(106,123,222),"had":"0"}]', '1', '%s', '0', '{"id":"%s","name":"%s"}', '{"id":"%s","name":"%s"}', '%s', '0')'''%(gameid,uid,name,author,create,chanid,chanme,uid,name,create)
			new_games = '''INSERT INTO `xiangsu`.`Ex_games` (`gameid`, `users`, `status`, `modtime`, `gametype`, `mateid`, `souruse`, `create`, `templ`) VALUES (%s, '[{"id":"%s","name":"%s","author":"%s","color":(106,123,222),"had":"0"}]', 1, '%s', 0, '{"id":"%s","name":"%s"}', '{"id":"%s","name":"%s"}', '%s', '0')'''%(gameid,uid,name,author,create,chanid,chanme,uid,name,create)
			print(new_games)
			self.cursor.execute(new_games)
			# 更新用户的对局状态
			self._Update_User_Game(uid,0,chanid,chanme,gameid)
			# 设置对局状态为等待中
			self.Set_Game_Done(gameid,1)
			msg = {"code":200,"msg":"创建对局成功","gameid":gameid}
			return msg

		# 200表示用户在对局中
		# 返回对局信息
		if user_stau == 210:
			return seart

	# 加入对局 要传入gameid uid username author chanid chanme
	# 传出加入对局是否成功
	def Insert_Game(self,gameid,uid,username,author,chanid,chanme):
		# 先查询对局成员、最后修改时间、对局所在频道id
		self.cursor.execute("SELECT users,modtime,mateid,status FROM `Ex_games` WHERE `gameid`=%s"%(gameid))
		sear = self.cursor.fetchall()
		# 对局所在频道
		# 若对局不存在
		if len(sear) == 0:
			msg = {"code":202,"msg":"该对局不存在"}
			return msg
		# 若对局已结束
		if int(sear[0][3]) == 2:
			return {"code":204,"msg":"该对局已结束"}
		# 若对局正在进行中
		if int(sear[0][3]) == 0:
			return {"code":209,"msg":"该对局已结束"}
		# 判断玩家是否在对局中
		user_info = json.loads(json.dumps(self.Saech_User_Play_stau(uid)))
		user_stau = user_info['code']
		# 若玩家在对局中
		# 返回对局信息,结束语句
		if user_stau == 210:
			msg = user_info
			return msg

		# 若玩家不存在,创建玩家
		if user_stau == 202:
			self._Insert_user_info(uid,username,chanid,chanme,gameid)
		# 其他情况下,认为玩家已存在,并且不在游戏中
		game_chanid = int(json.loads(sear[0][2])['id'])
		# 若对局所在频道不是该频道
		if game_chanid != int(chanid):
			msg = {"code":201,"msg":"该对局不在当前频道,请选择频道内的对局或创建对局"}
			return msg
		# 若对局所在频道属于该频道
		if game_chanid == int(chanid):
			sear = json.loads(json.dumps(self.Search_Game_Stau(gameid)))
			# 判断对局人数是否已满
			game_user_num = literal_eval(sear['data'][2])
			if len(game_user_num) >= 6:
				msg = {"code":203,"msg":"当前对局人数已满,请选择其他对局或发起对局"}
				return msg
			# 人数未满则将玩家加入该对局
			else:
				# 新加入玩家的信息
				# 新玩家的颜色
				new_color = self.user_colors[len(game_user_num)+1]
				new_user_info = {"id":f"{uid}","name":f"{username}","author":f"{author}","color":new_color,"had":"0"}
				game_user_num.append(new_user_info)
				# 对局更新的时间
				update = int(time.time())
				upda_users = '''UPDATE `xiangsu`.`Ex_games` SET `users` = "%s" WHERE `Ex_games`.`gameid` = %s'''%(str(game_user_num),gameid)
				upda_update = '''UPDATE `xiangsu`.`Ex_games` SET `modtime` = '%s' WHERE `Ex_games`.`gameid` = %s'''%(update,gameid)
				self.cursor.execute(upda_users)
				self.cursor.execute(upda_update)
				self.db_con.commit()
				# 更新玩家对局状态
				self._Update_User_Game(uid,0,chanid,chanme,gameid)
				# index为6,表示人数已满,开始对局
				# 否则继续等待玩家
				if len(game_user_num) == 6:
					# 设定对局状态为进行中
					self.Set_Game_Done(gameid,0)
				msg = {"code":200,"msg":f"玩家 {username} 已加入对局 {gameid}","color":f"{new_color}","index":len(game_user_num)}
				return msg

	# 更新用户的对局状态
	def _Update_User_Game(self,uid,code,chanid,chanme,gameid):
		# 更新用户的对局状态
		upt_user = '''UPDATE `xiangsu`.`Ex_user_info` SET `whplay` = '{"code":%s,"chanid":"%s","channame":"%s","gameid":%s}' WHERE `Ex_user_info`.`id` = %s'''%(code,chanid,chanme,gameid,uid)
		self.cursor.execute(upt_user)
		self.db_con.commit()
		msg = {"code":201,"msg":"更改用户对局状态","gameid":gameid}
		return msg

	# 新增一个用户
	def _Insert_user_info(self,uid,name,chanid,chanme,gameid):
		# 新增一个用户
		new_user = '''INSERT INTO `xiangsu`.`Ex_user_info` (`id`, `name`, `gamenub`, `gamevic`, `whplay`) VALUES (%s, '%s', '0', '0', '{"code":0,"chanid":"%s","channame":"%s","gameid":%s}')'''%(uid,name,chanid,chanme,gameid)
		print("新增用户语句:",new_user)
		self.cursor.execute(new_user)
		self.db_con.commit()
		msg = {"code":200,"msg":f"新增用户 {name}"}
		return msg


	# 查询对局所有信息 要传入gameid
	def Search_Game_Stau(self,gameid):
		self.cursor.execute(f"SELECT * FROM `Ex_games` WHERE `gameid`={gameid}")
		sear = self.cursor.fetchall()
		if len(sear) == 0:
			msg = {"code":201,"msg":"未查询到对局信息"}
		else:
			numbp = literal_eval(sear[0][2])
			templ = sear[0][-1]
			msg = {"code":200,"data":list(sear[0]),"num":len(numbp),"users":numbp,"templ":f"{templ}"}
		return msg
		

	# 获得一个可用的对局ID
	# 创建对局需要用到
	def _Get_New_Gameid(self):
		self.cursor.execute(f"SELECT MAX(gameid) from Ex_games")
		return self.cursor.fetchall()[0][0] + 1


	# 查询用户是否在对局中
	# 需传入用户id
	def Saech_User_Play_stau(self,uid):
		if uid == '' or uid == None:
			msg = {"code":203,"msg":"无效参数"}
		# 从user表中查询
		self.cursor.execute(f"SELECT * FROM `Ex_user_info` WHERE `id`={uid}")
		# 查询数据
		seardt = self.cursor.fetchall()
		# 为0则不存在
		if len(seardt) == 0:
			msg = {"code":202,"msg":"未查询到该用户"}
		else:
			# 用户对局信息
			st = json.loads(seardt[0][4])
			# 用户昵称
			user = seardt[0][1]
			# 格式化输出
			if st['code'] == 0:
				chanid,chanme,gameid = st['chanid'],st['channame'],st['gameid']
				msg = {"code":210,"msg":f"{user} 正在频道 {chanme} 进行对战","chanid":chanid,"chanme":f"{chanme}","gameid":gameid}
			if st['code'] == 1:
				msg = {"code":201,"msg":f"{user} 未在对局中"}
			# 关闭数据库
		return msg


	# 开始一个新对局 需要gameid
	# 确保对应对局已拥有 6 人
	# 如果头像重复,则只生成一个头像
	def Start_Game(self,gameid):
		# 先获取玩家列表
		users = self.Search_Game_Stau(gameid)['users']
		# 获取玩家头像列表 传入像素模块使用
		authors = []
		for i in users:
			authors.append(i['author'])
		# 生成对局图片
		game_back = xiangsu.BackGround(aust=authors)
		game_back = json.loads(json.dumps(game_back.Author_Add()))
		print(game_back)
		# 对局图片及url
		templ_url = game_back['url']
		templ = game_back['templ']
		# 更新对局templ 对局信息 对局状态
		upd_templ = '''UPDATE `xiangsu`.`Ex_games` SET `templ` = '%s' WHERE `Ex_games`.`gameid` = %s'''%(templ,gameid)
		upd_status = '''UPDATE `xiangsu`.`Ex_games` SET `status` = '%s' WHERE `Ex_games`.`gameid` = %s'''%(0,gameid)
		self.cursor.execute(upd_templ)
		self.cursor.execute(upd_status)
		self.db_con.commit()
		return game_back

	# 占领一个方块 生成一个像素格
	# 传入uid 根据uid来查找对局图片name,判断玩家是否有对局
	# 需要 指定bt=1 传入像素位置gratt 传入像素颜色gratcolor
	def Game_Add_grat(self,uid,gratt,chanid):
		# 先判断玩家对局状态,获取对局templ
		user_info = self._Search_Uidto_Templ(uid)
		if user_info['code'] == 202 or user_info['code'] == 201 or user_info['code'] == 203:
			return user_info
		if user_info['code'] == 200:
			# 判断对局是否结束
			if user_info['data'][3] == 2:
				return {"code":205,"msg":"该对局已结束"}
			# 若对局在等待中
			if user_info['data'][3] == 1:
				user_info = self.Saech_User_Play_stau(uid)
				gameid = user_info['gameid']
				self.cursor.execute(f"SELECT * FROM `Ex_games` WHERE `gameid`={gameid}")
				sear = self.cursor.fetchall()
				numbp = literal_eval(sear[0][2])
				return {"code":206,"msg":"该对局在等待中,您可以先加入对局","num":len(numbp)}
				gamesuse = self.Saech_User_Play_stau(uid)
				if int(gamesuse['code']) == 210 and int(gamesuse['chanid']) == int(chanid):
					return {"code":206,"msg":"该对局在等待中,您可以先加入对局"}
				else:
					return {"code":207 ,"msg":"请前往对局所在的频道进行对战"}
			templ = user_info['templ']
			# 获取玩家方块颜色
			#print("ymsql输出:",uid,user_info['data'][2],templ)
			grat_color = self._Search_Usergrat_Color(uid,user_info['data'][2])
			# 实例化
			# 新的templ
			templ2 = "xiangsu"+ str(time.time()) + ".png"
			game_admin = xiangsu.BackGround(bt=1,gratt=gratt,gratcolor=grat_color,name=templ,name2=templ2)
			print("ymsql:",templ,templ2,gratt,grat_color)
			# 生成像素格
			add_grat = game_admin.Add_grat()
			# 获取gameid
			gameid = self.Saech_User_Play_stau(uid)['gameid']
			# 更新对局templ
			upd_templ = '''UPDATE `xiangsu`.`Ex_games` SET `templ` = '%s' WHERE `Ex_games`.`gameid` = %s'''%(templ2,gameid)
			print("更新新的templ:",upd_templ)
			self.cursor.execute(upd_templ)
			self.db_con.commit()
			# 给玩家增加一个占领的方块
			incgrat = self._Inc_Game_grat(uid,user_info['data'][2])
			# 获取对局上一次的修改时间
			# modtime = self._Get_Game_Modif(uid)
			# 判断玩家是否获胜 : 占领144个方块
			if int(self.Search_user_grat_Num(uid)) >= 30:	
				msg = {"code":211,"msg":"对局已结束","king":uid}
				# 为对局玩家增加对局次数
				gameid = self.Saech_User_Play_stau(uid)['gameid']
				self.Insert_Game_User_king(uid,gameid)
				# 更改对局中所有玩家的状态为不在对局中
				# 更改对局状态为已结束
				self.Set_Game_User_Done(uid,chanid)
				self.Set_Game_Done(gameid,2)
				return msg
			else:
				msg = {"code":201,"msg":"占领成功"}
			return add_grat


	# 查找uid对应的对局templ
	# 同时判断玩家的对局状态
	def _Search_Uidto_Templ(self,uid):
		data = self.Saech_User_Play_stau(uid)
		# 210说明玩家有对局,继续查找templ
		if data['code'] == 210:
			templ = self.Search_Game_Stau(data['gameid'])
			return templ
		# 玩家没有参与过对局
		if data['code'] == 202:
			return data
		# 玩家当前不在对局中
		if data['code'] == 201:
			return data


	# 获取玩家方块颜色 需要传入uid和users信息
	def _Search_Usergrat_Color(self,uid,users):
		users = literal_eval(users)
		for i in users:
			dt = json.loads(json.dumps(i))
			if int(dt['id']) == int(uid):
				color = dt['color']
		print("ymsql:",color)
		return tuple(color)

	# 给玩家增加一个占领的方块
	def _Inc_Game_grat(self,uid,users):
		users = literal_eval(users)
		busers = []
		for i in users:
			dt = json.loads(json.dumps(i))
			if int(dt['id']) == int(uid):
				dt['had'] = str(int(dt['had']) + 1)
			busers.append(dt)
		inc_grat = '''UPDATE `xiangsu`.`Ex_games` SET `users` = "%s" WHERE `Ex_games`.`gameid` = %s'''%(busers,self.Saech_User_Play_stau(uid)['gameid'])
		self.cursor.execute(inc_grat)
		self.db_con.commit()
		
	# 获取对局上一次的修改时间
	# 根据uid,用于占领方块格子时使用
	def _Get_Game_Modif(self,uid):
		data = self.Saech_User_Play_stau(uid)
		# 210说明玩家有对局,继续查找templ
		if data['code'] == 210:
			modtime = self.Search_Game_Stau(data['gameid'])
			return modtime['data'][4]
		# 玩家没有参与过对局
		if data['code'] == 202:
			return data
		# 玩家当前不在对局中
		if data['code'] == 201:
			return data


	# 获取玩家方块数量
	def Search_user_grat_Num(self,uid):
		user_info = self._Search_Uidto_Templ(uid)
		users = literal_eval(user_info['data'][2])
		for i in users:
			dt = json.loads(json.dumps(i))
			if int(dt['id']) == int(uid):
				gratnum = dt['had']
		return int(gratnum)

	# 为对局中的胜出玩家增加一次胜利次数和对局次数
	# 所有玩家增加一次对局次数
	# king为胜利玩家uid
	def Insert_Game_User_king(self,king,gameid):
		data = self.Search_Game_Stau(gameid)
		self._Update_user_Games_king(king)
		for i in literal_eval(data['data'][2]):
			uid = json.loads(json.dumps(i))['id']
			self._Update_user_Games(uid)


	# 为玩家增加一次对局次数
	def _Update_user_Games(self,uid):
		updt = '''UPDATE `xiangsu`.`Ex_user_info` SET `gamenub` = gamenub+1 WHERE `Ex_user_info`.`id` = %s'''%(uid)
		self.cursor.execute(updt)
		self.db_con.commit()

	# 为玩家增加一次胜利次数
	def _Update_user_Games_king(self,uid):
		updt = '''UPDATE `xiangsu`.`Ex_user_info` SET `gamevic` = gamevic+1 WHERE `Ex_user_info`.`id` = %s'''%(uid)
		self.cursor.execute(updt)
		self.db_con.commit()
		
	# 设置对局状态
	# 0进行中 1等待中 2已结束
	def Set_Game_Done(self,gameid,sta):
		updt = '''UPDATE `xiangsu`.`Ex_games` SET `status` = '%s' WHERE `Ex_games`.`gameid` = %s'''%(sta,gameid)
		self.cursor.execute(updt)
		self.db_con.commit()
		

	# 设置对局中所有玩家状态为不在对局中
	def Set_Game_User_Done(self,uid,chanid):
		# 获取gameid
		gameid = self.Saech_User_Play_stau(uid)['gameid']
		dataa = self.Search_Game_Stau(gameid)
		chanme = json.loads(dataa['data'][6])['name']
		users = dataa['users']
		# 获取所有id
		#ids = []
		for i in users:
			#ids.append(i['id'])
			self._Update_User_Game(i['id'],1,chanid,chanme,gameid)
# 背景图像操作类
class BackGround:
    '''
    必须在满足以下条件后调用
    1 拥有六个玩家
    '''
    def __init__(self,aust='',name='',path='',bt=0,gratt='',gratcolor='',name2=''):
        '''
        path :存储路径
        name :图片名称 要打开的图像,已有的对局需要此参数
        bt :0需要生成背景 1需要打开已有背景
        aust :玩家头像列表
        gratt :要生成的像素格的位置 如(1,1)
        gratcolor : 要生成的像素格的颜色
        '''
        # 像素格颜色
        self.gratcolor = gratcolor
        # 生成要存储的背景名称
	# 或要打开的图片
        if name == '' or name == None:
            self.name = "xiangsu" + str(time.time()) + ".png"
        else:
            self.name = name

        # 图片最新的名字
        try:
            self.name2 = name2
        except:
            pass
        if path == '' or path == None:
            self.path = "C:/wwwroot/xiangsu.siriusbot.cn/cache/" + self.name
        else:
            self.path = path
        
        # 生成新背景或使用已有背景
        if bt == 0:
            self.back = Image.open("bk-demo2.png")
            self.aust = aust
        elif bt == 1:
            self.back = Image.open(self.path)

        # 头像处理后的大小 像素
        self.px, self.py = 50,50

        # 颜色列表
        self.Authors_Colors = [(106,123,222),(106,196,222)
                                ,(42,100,114),(87,87,87)
                                ,(199,75,75),(76,205,97)]
        
        # 每个玩家的头像生成位置
        self.Authors_Add = [(26,16),(127,16)
                            ,(227,16),(26,82)
                            ,(127,82),(227,82)]
        # 像素格的大小 默认15
        self.grat = (15,15)
        # 每个像素格的x位置
        self.gratsx = {1:41,2:60,3:79,4:98,5:117,6:136,7:156,8:175,9:194,10:213,11:232,12:251}
        # 每个像素格的y位置
        self.gratsy = {1:157,2:176,3:195,4:213,5:232,6:251,7:270,8:289,9:308,10:327,11:346,12:365}
        # 输入的要生成的像素格位置
        self.gratt = gratt

    # 生成一个像素格
    def Add_grat(self):
        '''
        需要初始化传入gratt
        '''
        # 生成方块 传入大小,颜色
        grat = Image.new('RGBA',self.grat,self.gratcolor)
        # 计算要生成像素格的位置
        try:
            grtobk = (int(self.gratsx[int(self.gratt[0])]),int(self.gratsy[int(self.gratt[1])]))
        except KeyError:
            return {"code":100,"msg":"位置超出了预期"}
        # 生成到背景图的位置
        self.back.paste(grat,grtobk,grat)
        self.back.save("C:/wwwroot/xiangsu.siriusbot.cn/cache/" + self.name2)
        print("xiangsu:图片的新名字:",self.name2)
        print("xiangsu:图片的旧名字:",self.name)
        self.back.close()
        return {"code":200,"url":f"https://xiangsu.siriusbot.cn/cache/{self.name2}","templ":f"{self.name2}"}
        #grat.close()

    # 下载头像
    def _Get_Author(self):
        '''
        传入一个头像url 传出一个Image对象

        author :头像URL
        '''
        author = request.urlopen(unquote(self.author))
        authorio = io.BytesIO(author.read())
        self.author = Image.open(authorio)
        # 处理gif,取第一帧
        if "Content-Type: image/gif" in str(author.headers):
            self.author.seek(0)
            self.author = self.author.convert("RGBA")
            print("已处理该gif")
        author.close()
        self.author = self.author.resize((self.px,self.py))
        # 处理头像圆角
        self._Author_Circle()

    # 处理头像圆角
    def _Author_Circle(self):
        '''
        需要传入头像对象到self.author
        '''
        alpha_layer = Image.new('L', (self.px, self.py), 0)
        draw = ImageDraw.Draw(alpha_layer)
        draw.ellipse((0,0,self.px,self.py), fill=255)
        self.author.putalpha(alpha_layer)
        #alpha_alyer.close()

    # 将头像合成到背景中指定位置
    def _Author_To_Back(self):
        '''
        需提前传入头像对象到self.author
        '''
        self.back.paste(self.author,self.autobk,self.author)

    # 生成玩家头像到demo背景
    def Author_Add(self):
        try:
            if len(self.aust) > 6:
                return "aust数量超出预期"
            for self.author in self.aust:
                if self.author != None:
                    self.autobk = self.Authors_Add[self.aust.index(self.author)]
                    self._Get_Author()
                    self._Author_To_Back()
            #测试用
            # self.back.save("adddemo.png")
            # 实际使用
            self.back.save(self.path)
            self.back.close()
            authorurl = "https://xiangsu.siriusbot.cn/cache/" + self.name
            return {"code":200,"url":f"{authorurl}","templ":self.name}
        except:
            return {"code":100}