本文为博主原创,未经许可严禁转载。
本文链接:https://blog.csdn.net/zyooooxie/article/details/117427808
最近做了连连看的需求,这是我首次测 小游戏,测得有些心虚;就来简单做个总结吧。
【实际这篇博客推迟发布N个月】
个人博客:https://blog.csdn.net/zyooooxie
【以下所有内容仅为个人项目经历,如有不同,纯属正常;实际所有接口参数值 均有加密处理】
游戏开局,有个3s的倒计时;倒计时结束后,前端页面会对N个图案(每个图案重复M次)做随机排列、展示,用户要将 2个实际转弯数在2次以内的相同图案消除,在S秒内完成全部消除,奖励J金币;
游戏规则 说几句:
实际请求 说几句:
看不到的 说几句:
关于上面看不到的 解释几句:
想要弄明白整个游戏过程,先得清楚 接口的传参规则【第一次、第二次请求 通用此接口】
参数名 类型 是否必填 说明
uuid String 是 唯一标识
p1 String 否 开局棋盘数据;开局时必传
startTime Long 否 开局时间戳;开局时必传
p2 List<String> 否 游戏成功步骤数据;游戏结束并且成功后必传
细说:
p1 是开局后的游戏图案;假设有4种图案,图案设置为1234,每种出现4次,游戏时图案数量共16个;前端的游戏界面为 4*4(4行,每行4列),假设某次游戏的图案为 1234(第一行) 4321(第二行) 2341(第三行) 3214(第四行),故p1的值为 1234432123413214;
1 | 2 | 3 | 4 |
---|---|---|---|
4 | 3 | 2 | 1 |
2 | 3 | 4 | 1 |
3 | 2 | 1 | 4 |
p2 是将游戏过程 消除坐标+消除时间戳的list;
根据前面假设的p1图案【上面的表格】,我们真消除的只有2个可能:第二行 第二列的3 和 第三行 第二列的3、第二行 第四列的1 和第三行 第四列的1;
假设第一步选消除1,用的坐标为24、34;若消除的时间戳为1640966400(2022-01-01 00:00:00);故在这一步消除过程,结果为24164096640034;第二步选消除3,坐标为22、32;若消除的时间戳为1640966460(2022-01-01 00:01:00);故在第二步消除过程,结果为22164096646032;依次往后,最终将8个结果(16个图案,只能消除8次) 组合为list;
图案、开局时间戳、游戏次数
1,当天游戏次数 默认是C次;
2,p1成功请求后,次数会-1;
3,次数为0,继续去请求,报错;
1,此时间戳 < 服务器当前时间戳;【网络传输需要时间】(规则:此时间戳 最多小于 服务器时间戳 B秒)
2,此时间戳是 用户手机时间转化的;【有重大隐患:用户手机时间可随意设置,很多人会调快手机时间】(规则:此时间戳 最多大于 服务器时间戳 A 秒)
1,图案是否只有4种类型;
2,每种只出现4次;
1,将某次成功拿到响应的请求p1 重复发送N次,查看实际响应、表里记录;
2,并发请求p1;
消除图案、消除时间戳、消除步数
1,不重复消除,但消除的图案是不一样的;(举例-某次游戏的消除步骤:1行1列和1行2列消除、1行3列和1行4列消除、2行1列和2行2列消除)
2,重复消除 某几个图案;(举例:1行1列和1行2列消除、1行1列和1行2列消除、1行1列和1行2列消除)
3,不重复消除,消除的图案是一致的;
1,前、后时间戳:混合加减、递减、相等、递加;
2,first时间戳 和 服务器当前时间戳;
3,end时间戳 和 服务器当前时间戳;
1,8步、非8步;
1,将某次成功拿到响应的请求p2 重复发送N次,查看实际响应、表里记录;
2,并发请求p2;
前后图案、前后时间戳
1,前后图案不对应;
2,前后图案对应,但p2消除的图案出现 重复;
3,前后图案对应,但p2消除的图案出现 不一致;
1,前后时间戳 不匹配;(p1是2018年,p2是当前)
2,前后时间长匹配,但不现实;(p1、p2都是2018年,或者2025年)
1,p2的步数;
2,重复请求 某正常响应的p1、p2;
代码仅供参考,代码有删减、部分代码有特意修改
@File: p_c_web.py
把前端参数反推,校验实际消除图案是否相同。
def p1(data_dict: dict):
uuid_1, start_time_1, parameters_str = data_dict['uuid'], data_dict['start'], data_dict['p1']
Log.info(uuid_1)
Log.info('p1 开始时间的时间戳:{}'.format(start_time_1))
parameters_list = list(parameters_str)
ele_list_1 = list()
for i in range(4):
ele = parameters_list[i * 4:(i + 1) * 4]
Log.info(ele)
for e_index, e in enumerate(ele):
new = (e, (i + 1) * 10 + (e_index+1))
ele_list_1.append(new)
Log.info(ele_list_1)
return ele_list_1, uuid_1, start_time_1
def p2(data_dict_list: dict or list):
if isinstance(data_dict_list, dict):
uuid_2, parameters = data_dict_list['uuid'], data_dict_list['p2']
else:
uuid_2 = 'zy'
parameters = data_dict_list
time_stamp_list_2 = list()
ele_list_2 = list()
for p in parameters:
Log.debug('当前元素:{}'.format(p))
res_str = str(p)
now_time_stamp = res_str[2:-2]
time_stamp_list_2.append(now_time_stamp)
if parameters[0] != p:
assert time_stamp_list_2[-1] > time_stamp_list_2[-2]
new1, new2 = res_str[:2], res_str[-2:]
Log.info('第一步的结果:{}-{}'.format(new1, new2))
ele_list_2.append((new1, new2))
Log.info(ele_list_2)
return ele_list_2, uuid_2, time_stamp_list_2
def check_func(p1_ele_list: list, p1_uuid: str, p1_start_time: int, p2_ele_list: list, p2_uuid: str, p2_time_stamp_list: list):
assert p2_uuid == p1_uuid
assert p1_start_time < p2_time_stamp_list[0]
p2_ele_dict = dict.fromkeys(p2_ele_list)
Log.info('p2 dict:{}'.format(p2_ele_dict))
p1_ele_dict = {e[1]: e[0] for e in p1_ele_list}
Log.info('p1 dict:{}'.format(p1_ele_dict))
for p2e in p2_ele_dict:
# Log.info(p2e)
# Log.info(p1_ele_dict[p2e[0]])
# Log.info(p1_ele_dict[p2e[1]])
assert p1_ele_dict[p2e[0]] == p1_ele_dict[p2e[1]]
else:
Log.info('消除的图案 一一对应')
def main(p1_dict: dict, p2_dict: dict):
ele_list1, uuid1, start_time1 = p1(p1_dict)
ele_list2, uuid2, time_stamp_list2 = p2(p2_dict)
check_func(ele_list1, uuid1, start_time1, ele_list2, uuid2, time_stamp_list2)
@File: p_c.py
1,模拟真实游戏消除过程,发请求
2,校验 收到请求后,表记录的更新 【2次校验都是 人眼识别、人脑校验,是因为就几个字段,日志都打印出来了,我就没写 细致的方法】
def send_requests(session: str, uuid_num: str, **kwargs):
url = "https://zyooooxie/csdn~startGame"
data_dict = kwargs
data_dict.update(uuid=uuid_num)
header = {'Cookie': 'sessionId={}'.format(session)}
res = requests.post(url, json=data_dict, verify=False, headers=header)
# Log.info(dump.dump_all(res).decode('utf-8'))
Log.info('实际返回值:{}'.format(res.json()))
return res.json()['success']
def new_compose_func(p1_dict: dict, p2_dict: dict, session_id: str, new_end_time_stamp: int or tuple,
new_start_time_stamp: int = None, new_p2start: int = None):
new_parameters_str = p1_dict['p1']
# new_parameters = p1_dict['p1']
# new_parameters_str = new_parameters[::-1]
new_ele_list, *args = p2(p2_dict)
Log.info('实际坐标 list:{}'.format(new_ele_list))
# 第一次请求
new_give_time_stamp, new_start_time_stamp = return_time_stamp(give_time_stamp=new_start_time_stamp)
Log.info(new_give_time_stamp)
# return_time_stamp这个方法是返回 really开始时间戳、p1的start_time_stamp 【方法 无法提供,见谅】
new_uuid = return_uuid()
res1 = send_requests(session=session_id, uuid_num=new_uuid, p1=new_parameters_str, startTime=int(new_start_time_stamp))
if res1 is True:
Log.info('uuid的字段值是 {}'.format(new_uuid))
exe_sql = """
SELECT uuid FROM t_zyooooxie WHERE user_id = 'zyooooxie' ORDER BY create_time DESC LIMIT 1;
"""
sql_data = get_data_info(exe_sql)
Log.info('实际表的数据:{}'.format(sql_data))
# 第二次请求
Log.info('really结束时间戳:{}'.format(new_end_time_stamp))
new_time_stamp_list = list()
start = new_give_time_stamp
for i in range(8):
if new_p2start is None: # p2请求第一个时间戳和p1的不同
abc = i + 1
else:
abc = i
# Log.debug('p2请求中 第一个时间戳 == 开始时间戳')
if type(new_end_time_stamp) == int: # 整数 即 真实时间戳
time_difference = (new_end_time_stamp - int(start)) // 8
Log.debug('时间差:{}'.format(time_difference))
else: # 元组内部为 时间差
if len(new_end_time_stamp) == 1:
time_difference = new_end_time_stamp[0]
Log.debug('时间差:{}'.format(time_difference))
else:
time_difference = (random.choice(new_end_time_stamp), True)
start += time_difference[0]
Log.debug('时间差:{}'.format(time_difference[0]))
if isinstance(time_difference, tuple):
cuo = start
else:
cuo = abc * time_difference + int(new_give_time_stamp)
Log.debug('当前时间戳:{}'.format(cuo))
new_time_stamp_list.append(cuo)
Log.info('p2的 时间戳list:{}'.format(new_time_stamp_list))
# new_time_stamp_list[0] -= 100000
# Log.info('p2的 时间戳list:{}'.format(new_time_stamp_list))
p2_list = list()
for location, time_stamp in zip(new_ele_list, new_time_stamp_list):
Log.debug('消除的坐标为{}'.format(location))
Log.debug("实际消除的time_stamp:{}".format(time_stamp))
data = str(time_stamp) + str(location)
Log.debug('第二步的结果:{}'.format(data))
p2_list.append(data)
# Log.info(p2_list)
# # p2_list.append(p2_list[-1])
# p2_list.pop()
# p2_list.pop()
# p2_list.pop()
# Log.info(p2_list)
Log.info('实际p2 last_time_stamp - p1开始时间戳 = :{}'.format(fact))
if fact < 10:
gc = False
elif fact < 20:
gc = 100
elif fact < 30:
gc = 200
elif fact < 40:
gc = 300
else:
gc = False
res2 = send_requests(session=session_id, uuid_num=new_uuid, p2=p2_list)
# redis_use()
if res2 is True:
Log.info('uuid的字段值是 {}'.format(new_uuid))
Log.info('gold_coin的字段值是 {}'.format(gc if isinstance(gc, int) else '0'))
exe_sql = """
SELECT uuid, gold_coin FROM t_zyooooxie WHERE user_id = 'zyooooxie' ORDER BY create_time DESC LIMIT 1;
"""
sql_data = get_data_info(exe_sql)
Log.info('实际表的数据:{}'.format(sql_data))
def main2(dict_p1: dict, dict_p2: dict, session_id: str):
# start_time_stamp_2 = None # 使用当前时间戳
start_time_stamp_2 = 1747670401000 # 2025-05-20 00:00:01
# start_time_stamp_2 = 1526745601000 # 2018-05-20 00:00:01
# start_time_stamp_2 = int(time.time()) * 1000 + 120000 # 当前时间+120s
# start_time_stamp_2 = int(time.time()) * 1000 + 5000 # 当前时间 + Ns
# end_time_stamp_2 = start_time_stamp_2 + 18000
# end_time_stamp_2 = int(time.time()) * 1000 + 2000 # 当前时间 + Ns
# end_time_stamp_2 = int(time.time()) * 1000 + 120000 # 当前时间+120s
# end_time_stamp_2 = 1526745601000 # 2018-05-20 00:00:01
# end_time_stamp_2 = 1526918401000 # 2018-05-22 00:00:01
# end_time_stamp_2 = 1747670401000 # 2025-05-20 00:00:01
# end_time_stamp_2 = 1747843201000 # 2025-05-22 00:00:01
# end_time_stamp_2 = (0,) # 固定时间差
end_time_stamp_2 = (900,) # 固定时间差
# end_time_stamp_2 = (-1000,) # 固定时间差
# end_time_stamp_2 = (1300, 1500, 700, 800) # 随机时间+
# end_time_stamp_2 = (-1200, -1300, -900, -800) # 随机时间-
# end_time_stamp_2 = (-1200, 1300, -900, 800) # 随机混合
# end_time_stamp_2 = int(time.time()) * 1000 - 12000 # 当前时间-12s
# end_time_stamp_2 = int(time.time()) * 1000 - 120000 # 当前时间-120s
p2start = None # 第二个请求中 第一个元素时间戳 不等于 第一个请求的时间戳
# p2start = 1 # 等于
new_compose_func(dict_p1, dict_p2, session_id, end_time_stamp_2, new_start_time_stamp=start_time_stamp_2, new_p2start=p2start)
这篇博客内容就这些,实际很多东西不敢、不能说得特别细致;本文链接:https://blog.csdn.net/zyooooxie/article/details/117427808
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie