#!/usr/bin/env python # coding:utf-8 import json import os import sys import datetime import time curr_dir = os.path.split(os.path.abspath(__file__))[0] sys.path.append(os.path.join(curr_dir, '../')) sys.path.append(os.path.join(curr_dir, '../google_drive')) sys.path.append(os.path.join(curr_dir, '../firebase')) sys.path.append(os.path.join(curr_dir, '../ipm')) import config as config import utils as utils from game_play_type import MainPlayType from firebase.firebase_helper import FirebaseHelper from google_drive.google_sheet import GoogleSheetHelper def get_blob_asset_id(blob): filename = os.path.split(blob.name)[1] filename_only = os.path.splitext(filename)[0] asset_id = filename_only.replace("PackageManifest_", "").replace(".version", "") return asset_id # region 更新所有可测试关卡Google Sheet配置表,上传到Google Storage,生成测试文件,更新remote_config def upload_all_levels_sheet(platform, gameplay_levels_dict): """更新所有存在ab包的,psd_id的Google Sheet库""" sheet_helper = GoogleSheetHelper() sheet = sheet_helper.get_sheet_table(config.sheet_all_level, f"{platform}-{config.table_all_levels}") sheet.clear() #清除表格中的所有现有数据 for i, gameplay in enumerate(gameplay_levels_dict): list = gameplay_levels_dict[gameplay] if len(list) <= 0: continue col = i + 1 row_start = 1 row_end = row_start + len(list) - 1 cell_range = sheet.range(row_start, col, row_end, col) # 获取要更新的单元格范围 sheet_helper.sheet_update_cells_value(sheet, cell_range, list) config.notification_helper.append_msg(f"[{config.sheet_all_level}, {platform}-{config.table_all_levels}表格] 更新全关卡资源表成功") def update_all_levels_google_sheet(platform): try: """获取所有的ab包,更新Google Sheet上的所有关卡""" firebase_helper = FirebaseHelper() mainPlayType = MainPlayType() gameplay_levels_dict = {} for gameplay in mainPlayType.all_main_play_type_list: blobs = firebase_helper.get_files_match(f"Bundles/{platform}/Level/{gameplay}/{gameplay}_", "**.version") levels_list = [] for a_blob in blobs: levels_list.append(get_blob_asset_id(a_blob)) if len(levels_list) > 0: levels_list.insert(0, gameplay) gameplay_levels_dict[gameplay] = levels_list upload_all_levels_sheet(platform, gameplay_levels_dict) except Exception as e: error = "更新Google Sheet所有可验收关卡信息失败,错误信息:" + repr(e) print(error) config.notification_helper.append_msg(error) # endregion # region 更新所有验收过地关卡到Google Sheet def update_all_acceptance_passed_levels_2_google_sheet(platform): """更新所有验收过地关卡到Google Sheet""" try: firebase_helper = FirebaseHelper() mainPlayType = MainPlayType() gameplay_acceptance_passed_levels_dict = {} # 获取验收通过关卡列表 for gameplay in mainPlayType.all_main_play_type_list: blobs = firebase_helper.get_files_match(f"Bundles/{platform}/Level/{gameplay}/{gameplay}_", "**.version") levels_list = [] for a_blob in blobs: if config.meta_pass_count not in a_blob.metadata: continue pass_count = int(a_blob.metadata[config.meta_pass_count]) if pass_count <= 0: continue levels_list.append(get_blob_asset_id(a_blob)) if len(levels_list) > 0: gameplay_acceptance_passed_levels_dict[gameplay] = levels_list # 更新Google Sheet sheet_helper = GoogleSheetHelper() for gameplay in mainPlayType.all_main_play_type_list: if gameplay not in gameplay_acceptance_passed_levels_dict: print(f"{gameplay}玩法没有验收通过地关卡") continue levels_list = gameplay_acceptance_passed_levels_dict[gameplay] if len(levels_list) <= 0: print(f"{gameplay}玩法验收通过关卡列表为空") continue sheet, _ = sheet_helper.get_or_create_sheet_table(f"{platform}-{config.sheet_acceptance_passed_levels}", f"{gameplay}", 10000, 1) # 过滤已经记录在sheet里地已验收关卡 sheet_datas = sheet.get_all_values(major_dimension='COLUMNS') print(sheet_datas) col = 1 row_start = 1 if len(sheet_datas) > 0: sheet_acceptance_level_list = sheet_datas[0] row_start = len(sheet_acceptance_level_list) + 1 for acceptance_level in sheet_acceptance_level_list: if acceptance_level in levels_list: levels_list.remove(acceptance_level) # 添加新的验收通过关卡到sheet if len(levels_list) > 0: row_end = row_start + len(levels_list) - 1 cell_range = sheet.range(row_start, col, row_end, col) sheet_helper.sheet_update_cells_value(sheet, cell_range, levels_list) config.notification_helper.append_msg(f"{gameplay}模式新增关卡{len(levels_list)}个 关卡ID:{str(levels_list)}") else: print(f"{gameplay}玩法模式,没有新的验收通过关卡可以添加到sheet") except Exception as e: error = "添加新验收过地关卡到验收通过表格失败,错误信息:" + repr(e) print(error) config.notification_helper.append_msg(error) # endregion # region 更新Find Object关卡文档里地资源表 def update_level_config_assets(platform): """更新关卡表里对应玩法资源表每一关属性内容""" firebase_helper = FirebaseHelper() mainPlayType = MainPlayType() gameplay_blobs_dict = {} # 获取验收通过关卡列表 for gameplay in mainPlayType.all_main_play_type_list: blobs = firebase_helper.get_files_match(f"Bundles/{platform}/Level/{gameplay}/{gameplay}_", "**.version") for blob_item in blobs: asset_id = get_blob_asset_id(blob_item) if gameplay not in gameplay_blobs_dict: gameplay_blobs_dict[gameplay] = {} gameplay_blobs_dict[gameplay][asset_id] = blob_item sheet_helper = GoogleSheetHelper() for gameplay in mainPlayType.all_main_play_type_list: if gameplay not in gameplay_blobs_dict: print(f"{gameplay}玩法没有验收通过地关卡") continue if len(gameplay_blobs_dict[gameplay]) <= 0: print(f"{gameplay}玩法验收通过关卡列表为空") continue # 资源表创建和更新 gameplay_sheet, is_new_create = sheet_helper.get_or_create_sheet_table(config.sheet_level_config, f"{gameplay}资源表", 10000, 27) if is_new_create: # 新创建表设置表数据 first_row = [] first_row.append(["Asset_ID", "Asset_Name", "A_G", "I_G", "FindNum", "IsUsed"]) gameplay_sheet.update("A1", first_row, value_input_option="USER_ENTERED") gameplay_sheet.freeze(rows=1, cols=2) notes = { "C1": "android version file generation", "D1": "ios version file generation", "E1": "寻找物品个数", "F1": "是否已被主线使用" } gameplay_sheet.insert_notes(notes) # 设置表公式 second_row = [] id_formula = f"=ARRAYFORMULA(IF(B2:B<>\"\", ROW(B2:B)-ROW(B$2)+1, \"\"))" name_formula = "=IMPORTRANGE(" + "\"https://docs.google.com/spreadsheets/d/1mwisjfsQwcSqQ0BJ2TszThSZRCRqOaAqgpHaPGGCzYs\", " + f"\"{gameplay}!A:A\")" second_row.append([id_formula, name_formula]) gameplay_sheet.update("A2", second_row, value_input_option="USER_ENTERED") print(f"延时10秒,等待公式计算完成") time.sleep(10) # 更新表里资源generation等数据 gameplay_sheet_datas = gameplay_sheet.get_all_values(major_dimension='ROWS') gameplay_blobs_map = gameplay_blobs_dict[gameplay] cell_list = [] for i, row_values in enumerate(gameplay_sheet_datas): if i == 0: continue row = i + 1 asset_name = row_values[1] if asset_name not in gameplay_blobs_map: print(f"{platform}平台{gameplay}玩法资源表里没有找到对应资源{asset_name}") continue blob = gameplay_blobs_map[asset_name] if config.meta_pass_count not in blob.metadata: continue pass_count = int(blob.metadata[config.meta_pass_count]) if pass_count <= 0: continue a_g = row_values[2] i_g = row_values[3] find_num = row_values[4] str_generation = str(blob.generation) if platform == "Android" and str_generation != a_g: cell = gameplay_sheet.cell(row, 3) cell.value = str_generation cell_list.append(cell) time.sleep(1) if platform == "iOS" and str_generation != i_g: cell = gameplay_sheet.cell(row, 4) cell.value = str_generation cell_list.append(cell) time.sleep(1) if blob.metadata is not None and config.meta_find_num in blob.metadata: if str(blob.metadata[config.meta_find_num]) != find_num: cell = gameplay_sheet.cell(row, 5) cell.value = str(blob.metadata[config.meta_find_num]) cell_list.append(cell) time.sleep(1) if len(cell_list) > 0: gameplay_sheet.update_cells(cell_list, value_input_option="USER_ENTERED") # 关卡表创建 gameplay_level_db_sheet, is_new_create = sheet_helper.get_or_create_sheet_table(config.sheet_level_config, f"{gameplay}_db", 10000, 27) if is_new_create: time.sleep(5) # 设置表头 first_row = [] first_row.append(["Level", "Asset_ID", "Asset_Name", "Thumbnail", "A_G", "I_G", "FindNum", "配置合法性"]) gameplay_level_db_sheet.update("A1", first_row, value_input_option="USER_ENTERED") gameplay_level_db_sheet.freeze(rows=1, cols=4) # 设置表公式 second_row = [] level_formula = "=ARRAYFORMULA(IF(B2:B<>\"\", ROW(B2:B)-ROW(B$2)+1, \"\"))" asset_name_formula = f"=ARRAYFORMULA(IF(B2:B<>\"\", VLOOKUP(B2:B, '{gameplay}资源表'!A:E, 2, FALSE), \"\"))" a_g_formula = f"=ARRAYFORMULA(IF(B2:B<>\"\", VLOOKUP(B2:B, '{gameplay}资源表'!A:E, 3, FALSE), \"\"))" i_g_formula = f"=ARRAYFORMULA(IF(B2:B<>\"\", VLOOKUP(B2:B, '{gameplay}资源表'!A:E, 4, FALSE), \"\"))" find_num_formula = f"=ARRAYFORMULA(IF(B2:B<>\"\", VLOOKUP(B2:B, '{gameplay}资源表'!A:E, 5, FALSE), \"\"))" valid_formula = f"=ARRAYFORMULA(IF(B2:B=\"\", \"\", IF(COUNTIF(B:B, B2:B)>1, \"素材重复\", IF(ISERROR(MATCH(B2:B, '{gameplay}资源表'!A:A, 0)), \"素材缺失\", \"\"))))" second_row.append([level_formula, "", asset_name_formula, "", a_g_formula, i_g_formula, find_num_formula, valid_formula]) gameplay_level_db_sheet.update("A2", second_row, value_input_option="USER_ENTERED") # endregion # region 更新Find object主线关卡配置 # 如果要修改此处逻辑,记得下面的update_main_country_level_db方法的逻辑一起修改 ### def update_main_level_db(platform, mode): sheet_helper = GoogleSheetHelper() mainPlayType = MainPlayType() levels_data_dic = {} record_levels = {} error = "" gameplay_list = mainPlayType.debug_enable_main_play_type_list if mode == config.mode.debug.value else mainPlayType.release_enable_main_play_type_list for gameplay in gameplay_list: google_sheet_file = sheet_helper.get_sheet_table(config.sheet_level_config, f"{gameplay}_db") if google_sheet_file is None: print(f"{gameplay}玩法目前没有配置关卡表") continue # 读取所有信息对应列数 col_level, col_asset_id, col_asset_name, col_a_g, col_i_g, col_find_num, col_valid , col_game_play_type ,col_game_play_param, col_game_elements= -1, -1, -1, -1, -1, -1, -1,-1,-1,-1 first_row_datas = google_sheet_file.row_values(1) for i, value in enumerate(first_row_datas): if value == "Level": col_level = i + 1 elif value == "Asset_ID": col_asset_id = i + 1 elif value == "Asset_Name": col_asset_name = i + 1 elif value == "A_G": col_a_g = i + 1 elif value == "I_G": col_i_g = i + 1 elif value == "FindNum": col_find_num = i + 1 elif value == "配置合法性": col_valid = i + 1 # elif value == "GamePlayType": # col_game_play_type = i + 1 elif value == "GamePlayParam": col_game_play_param = i + 1 # elif value == "GameElements": # col_game_elements = i + 1 if col_level == -1 or col_asset_id == -1 or col_asset_name == -1 or col_a_g == -1 or col_i_g == -1 \ or col_find_num == -1 or col_valid == -1: config.notification_helper.append_msg(f"{gameplay}玩法目前配置关卡表格式不正确") return # 验证配置有效性 col_valid_datas = google_sheet_file.col_values(col_valid) for i, value in enumerate(col_valid_datas): if i == 0 or value == "": continue error += f"{gameplay}玩法第{i + 1}行配置错误:{value}\n" if error != "": config.notification_helper.append_msg(error) return # 验证所有关卡都有对应generation(表示对应平台有资源) col_generation = col_a_g if platform == "Android" else col_i_g col_generation_datas = google_sheet_file.col_values(col_generation) for i, value in enumerate(col_generation_datas): if i == 0: continue if value == "": error += f"{gameplay}玩法第{i + 1}行{platform}平台资源没有generation配置\n" if error != "": config.notification_helper.append_msg(error) return # 读取所有配置好关卡信息 sheet_main_db_datas = google_sheet_file.get_all_values(major_dimension='ROWS') for i, row_datas in enumerate(sheet_main_db_datas): if i == 0: continue one_level_data = {} level_id = row_datas[col_asset_name - 1] # game_play_type = row_datas[col_game_play_type - 1] # if len(game_play_type) == 0: # game_play_type = "normal" game_play_param = row_datas[col_game_play_param - 1] if len(game_play_param) == 0: game_play_param = "" # game_elements_param = row_datas[col_game_elements - 1] if col_game_elements > 0 else '' level_type = gameplay level_map_name = "" level_thum_name = "" one_level_data["LevelId"] = level_id one_level_data["LevelMapName"] = level_map_name one_level_data["LevelType"] = level_type one_level_data["LevelThumName"] = level_thum_name # one_level_data["GamePlayType"] = game_play_type one_level_data["GamePlayParam"] = game_play_param # one_level_data["GameElements"] = game_elements_param if gameplay not in levels_data_dic: levels_data_dic[gameplay] = [] levels_data_dic[gameplay].append(one_level_data) record_levels[level_id] = True # debug模式还要获取其他未配置但可以上线地关卡数据 # if mode == config.mode.debug.value: # sheet_asset = sheet_helper.get_sheet_table(config.sheet_level_config, f"{gameplay}资源表") # if sheet_asset is None: # print(f"{gameplay}玩法目前没有资源表") # continue # sheet_asset_datas = sheet_asset.get_all_values(major_dimension='ROWS') # for i, row_datas in enumerate(sheet_asset_datas): # if i == 0: # continue # asset_name = row_datas[1] # # game_play_type = "normal" # # if gameplay in levels_data_dic and asset_name in record_levels: # # continue # level_id = asset_name # level_type = gameplay # level_map_name = "" # level_thum_name = "" # game_play_param = "" # # game_elements_param = "" # one_level_data = {} # one_level_data["LevelId"] = level_id # one_level_data["LevelType"] = level_type # one_level_data["LevelMapName"] = level_map_name # one_level_data["LevelThumName"] = level_thum_name # # one_level_data["GamePlayType"] = game_play_type # one_level_data["GamePlayParam"] = game_play_param # # one_level_data["GameElements"] = game_elements_param # if gameplay not in levels_data_dic: # levels_data_dic[gameplay] = [] # levels_data_dic[gameplay].append(one_level_data) if len(levels_data_dic) <= 0: print(f"没有任何可上线关卡数据") return main_level_db = {} main_level_db["TotalLevelsDataDic"] = levels_data_dic # print(main_level_db) # 上传配置到Google Storage firebase_helper = FirebaseHelper() _json = json.dumps(main_level_db) config_json_filename = f"{platform.lower()}_main_level_db_{mode}.json" utils.write_json_file("gen_file", config_json_filename, _json) generation = firebase_helper.upload_file(f"Configs/{config_json_filename}", f"gen_file/{config_json_filename}") # 更新Remote Config condition = config.remote_condition_android if platform == "Android" else config.remote_condition_ios value = f"{config.cdn}/Configs/{config_json_filename}?generation={generation}" firebase_helper.update_remote_config(None, condition, config.remote_key_main_db, f"main_{mode}", value) return value def update_main_country_level_db(platform, mode, all_country_list): sheet_helper = GoogleSheetHelper() mainPlayType = MainPlayType() levels_data_dic = {} record_levels = {} error = "" gameplay_list = mainPlayType.debug_enable_main_play_type_list if mode == config.mode.debug.value else mainPlayType.release_enable_main_play_type_list country_and_url_list = [] for cur_country in all_country_list: for gameplay in gameplay_list: google_sheet_file = sheet_helper.get_sheet_table(config.sheet_level_config, f"{gameplay}_main_db_{cur_country}") if google_sheet_file is None: print(f"{gameplay}玩法目前没有{cur_country}的配置关卡表,使用默认表") google_sheet_file = sheet_helper.get_sheet_table(config.sheet_level_config,f"{gameplay}_db") if google_sheet_file is None: print(f"{gameplay}玩法目前没有配置关卡表") continue # 读取所有信息对应列数 col_level, col_asset_id, col_asset_name, col_a_g, col_i_g, col_find_num, col_valid, col_game_play_type, col_game_play_param, col_game_elements = -1, -1, -1, -1, -1, -1, -1, -1, -1,-1 first_row_datas = google_sheet_file.row_values(1) for i, value in enumerate(first_row_datas): if value == "Level": col_level = i + 1 elif value == "Asset_ID": col_asset_id = i + 1 elif value == "Asset_Name": col_asset_name = i + 1 elif value == "A_G": col_a_g = i + 1 elif value == "I_G": col_i_g = i + 1 elif value == "FindNum": col_find_num = i + 1 elif value == "配置合法性": col_valid = i + 1 # elif value == "GamePlayType": # col_game_play_type = i + 1 elif value == "GamePlayParam": col_game_play_param = i + 1 # elif value == "GameElements": # col_game_elements = i + 1 if col_level == -1 or col_asset_id == -1 or col_asset_name == -1 or col_a_g == -1 or col_i_g == -1 \ or col_find_num == -1 or col_valid == -1: config.notification_helper.append_msg(f"{gameplay}玩法目前配置关卡表格式不正确") return # 验证配置有效性 col_valid_datas = google_sheet_file.col_values(col_valid) for i, value in enumerate(col_valid_datas): if i == 0 or value == "": continue error += f"{gameplay}玩法第{i + 1}行配置错误:{value}\n" if error != "": config.notification_helper.append_msg(error) return # 验证所有关卡都有对应generation(表示对应平台有资源) col_generation = col_a_g if platform == "Android" else col_i_g col_generation_datas = google_sheet_file.col_values(col_generation) for i, value in enumerate(col_generation_datas): if i == 0: continue if value == "": error += f"{gameplay}玩法第{i + 1}行{platform}平台资源没有generation配置\n" if error != "": config.notification_helper.append_msg(error) return # 读取所有配置好关卡信息 sheet_main_db_datas = google_sheet_file.get_all_values(major_dimension='ROWS') for i, row_datas in enumerate(sheet_main_db_datas): if i == 0: continue one_level_data = {} level_id = row_datas[col_asset_name - 1] # game_play_type = row_datas[col_game_play_type - 1] # if len(game_play_type) == 0: # game_play_type = "normal" game_play_param = row_datas[col_game_play_param - 1] if len(game_play_param) == 0: game_play_param = "" # game_elements_param = row_datas[col_game_elements - 1] if col_game_elements > 0 else '' level_type = gameplay level_map_name = "" level_thum_name = "" one_level_data["LevelId"] = level_id one_level_data["LevelMapName"] = level_map_name one_level_data["LevelType"] = level_type one_level_data["LevelThumName"] = level_thum_name # one_level_data["GamePlayType"] = game_play_type one_level_data["GamePlayParam"] = game_play_param # one_level_data["GameElements"] = game_elements_param if gameplay not in levels_data_dic: levels_data_dic[gameplay] = [] levels_data_dic[gameplay].append(one_level_data) record_levels[level_id] = True # # debug模式还要获取其他未配置但可以上线地关卡数据 # if mode == config.mode.debug.value: # sheet_asset = sheet_helper.get_sheet_table(config.sheet_level_config, f"{gameplay}资源表") # if sheet_asset is None: # print(f"{gameplay}玩法目前没有资源表") # continue # sheet_asset_datas = sheet_asset.get_all_values(major_dimension='ROWS') # for i, row_datas in enumerate(sheet_asset_datas): # if i == 0: # continue # asset_name = row_datas[1] # game_play_type = "normal" # if gameplay in levels_data_dic and asset_name in record_levels: # continue # level_id = asset_name # level_type = gameplay # level_map_name = "" # level_thum_name = "" # game_play_param = "" # one_level_data = {} # one_level_data["LevelId"] = level_id # one_level_data["LevelType"] = level_type # one_level_data["LevelMapName"] = level_map_name # one_level_data["LevelThumName"] = level_thum_name # one_level_data["GamePlayType"] = game_play_type # one_level_data["GamePlayParam"] = game_play_param # if gameplay not in levels_data_dic: # levels_data_dic[gameplay] = [] # levels_data_dic[gameplay].append(one_level_data) if len(levels_data_dic) <= 0: print(f"没有任何可上线关卡数据") return main_level_db = {} main_level_db["TotalLevelsDataDic"] = levels_data_dic # print(main_level_db) # 上传配置到Google Storage firebase_helper = FirebaseHelper() _json = json.dumps(main_level_db) config_json_filename = f"{platform.lower()}_main_level_db_{cur_country}.json" utils.write_json_file("gen_file", config_json_filename, _json) generation = firebase_helper.upload_file(f"Configs/{config_json_filename}", f"gen_file/{config_json_filename}") value = f"{config.cdn}/Configs/{config_json_filename}?generation={generation}" country_and_url_list.append(f"配置{cur_country}的URL为:{value}") return country_and_url_list # endregion if __name__ == '__main__': pass # update_all_levels_google_sheet("Android") # update_all_acceptance_passed_levels_2_google_sheet("Android") # update_level_config_assets("Android") # update_main_level_db("Android", "debug")