在unity资源中发现无效引用

news/2024/9/28 9:04:39/

本文主要解决在不打开unity的情况下搜索出无效引用的资源的方法

1. 概述

  1. 一般只要遍历一下目录里所有资源,判空一下就好了
  2. 但有些情况下,不希望打开unity, 尤其希望是在资源整合时,想更快验证资源的合法性, 这对合并提交及出包验证时,都要较大的需求

2. 简单的验证方法

  1. 简单来说,要直接分析untiy的资源文件, 而且unity资源大部分是文本文件
  2. 他们的文本格式大多是YAML, 如果直接使用PyYaml, 目前发现不行, 不过幸好, 格式相对简单, 通过分析属性的名称,再找到属性的内容,方法,可以定位出Guid的值, 例如, 要查找XXX, YYY的值
import osGuidStr = "guid: "
GuidStrLen = len(GuidStr)class CheckAssetInfo:def __init__(self, filePath):self.filePath = filePathself.allGuids = []self.isInit = Falseself.checkValueNames = ["XXX", "YYY"]self.initData()def initData(self):if not self.isInit:self.allGuids = self.get_file_to_guids(self.filePath) self.isInit = Truedef get_all_guids(self):return self.allGuidsdef get_target_value(self, valueName, valueInfos):for i in range(len(valueInfos)):n, j = valueInfos[i]if n == valueName:return ireturn -1def get_file_to_guids(self, targetFilterPath):allGuids = []with open(targetFilterPath, 'r') as assetFile:contentLines = assetFile.readlines()valueInfos = self.get_all_value_index(contentLines)for checkName in self.checkValueNames:valueIndex = self.get_target_value(checkName, valueInfos)if valueIndex != -1:valueName, stline = valueInfos[valueIndex]valueName, endLine = valueInfos[valueIndex+1]allGuids.extend(self.get_value_guids(contentLines, stline, endLine))return allGuidsdef get_all_value_index(self, contentLines):valueInfos = []lineCount = len(contentLines)for i in range(lineCount):oneLine = contentLines[i]findIndex = oneLine.find(":")if findIndex != -1:valueName = oneLine[0:findIndex].strip()if valueName[0].isalpha():valueInfos.append((valueName, i))valueInfos.append(("", lineCount))return valueInfosdef get_value_guids(self, contentLines, startLineIndex, endLineIndex):allGuids = []for i in range(startLineIndex, endLineIndex):oneLine = contentLines[i]guidIndex = oneLine.find(GuidStr)if guidIndex != -1:endIndex = oneLine.find(", ", guidIndex)allGuids.append(oneLine[guidIndex + GuidStrLen: endIndex].strip())return allGuids
  1. 获得引用的GUID后,还要知道都有什么GUID的资源, 这个比较简单,只要分析meta文件就好, 以下就简单粗暴地遍历资源目录下的meta文件即可
class MetaInfo: def __init__(self, filePath):self.filePath = filePath; self.guid = self.get_guid_from_file(filePath)def get_guid_from_file(self, filePath):with open(filePath, 'r') as metaFile:allLine = metaFile.readlines()for oneLine in allLine:guidIndex = oneLine.find(GuidStr)if guidIndex != -1: return oneLine[guidIndex + GuidStrLen:len(oneLine)].strip()return ""lass VegChecker: def __init__(self, baseDir):self.checkAssetDir = "Assets/checkDir" self.allAssetDir = "Assets"self.allAssetGuids = {}def get_all_target_files(self, targetDir, extName):res = []for root, dirs, files in os.walk(targetDir):for file in files:if os.path.splitext(file)[1] == extName:file_path = os.path.join(root, file)res.append(file_path)return resdef get_all_asset_guids(self):allMetaFiles = self.get_all_veg_files(self.allAssetDir, ".meta")for metaFile in allMetaFiles:metaInfo = MetaInfo(metaFile)self.allAssetGuids[metaInfo.guid] = Trueprint("Get total asset count meta count: " + str(len(self.allAssetGuids)))
  1. 获得要引用的GUID与所有的资源GUID,就很简单了,发引用的GUID不在所有的资源GUID里就可以了
    def check_all_asset(self):res = Trueself.get_all_asset_guids()checkFiles = self.get_all_target_files(self.checkVegDir, ".asset")for oneFilter in checkFiles:assetInfo = CheckAssetInfo(oneFilter)for guid in assetInfo.allGuids:if not self.allAssetGuids.get(guid, False):print(f"fail to find guid {guid} in check asset {oneFilter}")res = Falsereturn res

3.Q&A

  1. 可能直接分析文件, 而且要大范围遍历文件,会有效率问题, 但实则试验下来, 还是挺快的, 测试验证几十个文件引用, 遍历了4万多个文件, 在i9机器,大概就8秒, 这已经比直接打unity快多了.
  2. 当然会有分析错误的风险,但如果在一些相对明确的结构上, 也许是安全,但人工维护是免不了的

http://www.ppmy.cn/news/1531483.html

相关文章

安全审计与监控的核心作用!确保网络安全等级保护的有效性

安全审计和监控是确保网络安全等级保护有效实施的关键手段。通过定期审计系统的安全性和实时监控网络活动,可以及时发现潜在的安全问题和异常行为。本文将探讨安全审计和监控在网络安全等级保护中的作用,介绍实施审计和监控的最佳实践,并提供…

走进上海郭培高定会馆:以冠珠华脉、华珍筑就至臻至性的艺术空间

“我热爱高级时装,因为她是一种生命的停驻。我希望我的高级时装成为馆藏级的精品,殿堂级的珍宝,成为传世杰作。” ——郭培 中国唯一一位法国高定公会受邀会员,曾荣登《TIME》时代周刊全球100位最具影响力人物榜单。纽约时报评价…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(四)-搜索

搜索 搜索内容比较多,onesearch分成两部分,第一部分,Query构建,其中包括搜索词设置,设置返回字段,filter,高亮;第二部分分页和排序。第一部分是映射引擎负责,映射通用表…

XXL-JOB:将accessToken扩展为动态

背景: xxl-job版本:2.0.2 xxl-rpc-core版本:1.4.0 springboot版本:1.5.20.RELEASE Kingbase版本:V8R6 针对业务上的需求,做一些个性化扩展: 1、启用accessToken,并且使用SM2加密&…

Serilog文档翻译系列(六) - 可用的接收器、增强器、格式化输出

01、提供的接收器 Serilog 使用接收器将日志事件以各种格式写入存储。许多接收器由更广泛的 Serilog 社区开发和支持;可以通过在 NuGet 上搜索 serilog 标签找到。 02、增强器 日志事件可以通过多种方式增强属性。通过 NuGet 提供了一些预构建的增强器&#xff…

pyhton语法 正则表达式

pyhton语法 正则表达式 1.正则表达式介绍1.1 正则表达式入门1.2 正则替换 2.正则效验2.1正则-校验单个字符2.2正则-校验多个字符2.3 正则-校验开头和结尾2.4 正则-校验分组2.5 正则校验邮箱2.6正则获取分组后的数据2.7 引用指定组的内容 总结 1.正则表达式介绍 1.1 正则表达式…

1.MySQL的安装

目录 下载安装包 安装前环境的准备 正式安装 下载安装包 MySQL安装网址:https://www.mysql.com/cn/ 进去之后就是上面这个页面,进行汉化的时候将这个网页拉至最下,右下角点成中文就可以,如下这个页面。 回到页面顶端,点击下载&a…

NVIDIA 的 Blackwell 架构:解析 B100、B200 和 GB200

随着人工智能和机器学习领域继续以惊人的速度发展,NVIDIA 的最新创新——Blackwell 架构,将以无与伦比的并行计算能力重新定义AI和HPC。 NVIDIA 展示了一系列新技术,有望以前所未有的方式加速 AI 训练和推理。他们推出了 Blackwell GPU、GB20…