游戏盘被 VN 爆破后如何科学节约储存空间 硬链接兼用版
本帖最后由 FErD 于 2024-6-27 17:29 编辑下载
这一版与之前的不同,对硬链接使用了winrar的rar5专有格式而非7zip的tar格式进行压缩,
相比较体积更小,但需要额外指定winrar命令行模式的可执行程序位置。
修复了Game_Clean删文件的bug
请自行按自己的习惯修改,用脚本转化.ps1可将其转化为exe执行文件
使用指南
运行前的文件目录结构,
可自行在用户变量内修改
运行后的文件目录结构,
可自行在用户变量内修改
#游戏文件夹名字
$GamefileName
#nodvd游戏 iso文件放置位置
Runtime
#安装文件
Install
#附加内容,建议拆了入库(图库 音乐库 漫画库等)
Extra
#游戏本体
*JPN*
*CHI*
*ENG*
$GamefileName*
#游戏文件夹名字
$GamefileName
#nodvd游戏 iso文件放置位置
Runtime
#安装文件
$GamefileName-Install.7z
#附加内容,建议拆了入库(图库 音乐库 漫画库等)
$GamefileName-Extra.7z
#游戏本体
$GamefileName.7z|rar
#对游戏本体而言的差别,比如存档
$GamefileName-updata.7z
使用指南
运行前的文件目录结构,
可自行在用户变量内修改
运行后的文件目录结构,
可自行在用户变量内修改
#游戏文件夹名字
$GamefileName
#nodvd游戏 iso文件放置位置
Runtime
#安装文件
Install
#附加内容,建议拆了入库(图库 音乐库 漫画库等)
Extra
#游戏本体
*JPN*
*CHI*
*ENG*
$GamefileName*
#游戏文件夹名字
$GamefileName
#nodvd游戏 iso文件放置位置
Runtime
#安装文件
$GamefileName-Install.7z
#附加内容,建议拆了入库(图库 音乐库 漫画库等)
$GamefileName-Extra.7z
#游戏本体
$GamefileName.7z|$GamefileName.tar
#对游戏本体而言的差别,比如存档
$GamefileName-updata.7z
上一版
游戏盘被VN爆破后如何科学节约储存空间
https://www.gamemale.com/forum.p ... 4382&fromuid=668102
(出处: GameMale)
大概压出了50g(
上一稿修修改改对硬链接支持不太好。
加了挺多行(答辩山越来越高了)
(主要是给黑奴ai提需求造出来了一堆模块,写好逻辑放了进去)
(ai推荐用函数,但powershell和7zip好像攻受不合)
这一版对仓鼠,日文 中文 英文各存一份,或者中+原文一份的优化量比上一版会好巨多。
建议相配合查重软件查重后进行硬链接。
用户变量
如有自定义需求请对照P1进行自定义。
# 设置 7-Zip 可执行文件的路径
$7zipPath = "B:\program\7-Zip\7z.exe"
# 创建 7-Zip 命令的别名
Set-Alias Expand-7Zip $7zipPath
Set-Alias Compress-7Zip $7zipPath
#7Zip最好不要用设定文件名的变量
# 获取当前工作目录的完整路径
$GameFilePath = Get-Location
# 提取当前路径的文件夹名称
$GameFolderName = Split-Path -Path $GameFilePath -Leaf
#设定文件名
$GameFile = "$GameFolderName"
$GameFileUpdata = "$GameFolderName-updata"
$GameFileInstall = "$GameFolderName-Install"
$GameFileExtra = "$GameFolderName-Extra"
#temp ssd路径
$TempssdFolder = "Y:\temp\game\$GameFolderName"
# 转换排除项为 7-Zip 排除参数
$7zipExclusions = @(
"ReadyRunGame_linktemp.exe",
"ReadyCloseGame_linktemp.exe",
"ReadyRunGame_runtime.exe",
"ReadyCloseGame_runtime.exe",
"Game_Clean.exe",
"UserVar.ps1",
"$GameFileInstall.7z",
"Install",
"Install\*",
"$GameFileRuntime.7z",
"Runtime",
"Runtime\*",
"$GameFileExtra.7z",
"Extra",
"Extra\*"
)
$7zipExclusionParams = $7zipExclusions | ForEach-Object { "-x!$_" }
ReadyRunGame
. "$PWD\UserVar.ps1"
#挂载无nodisk补丁游戏运行文件
#文件在Runtime挂载
#游戏的nodisk补丁无用时使用
if (Test-Path "$PWD\Runtime") {
Start-Process "$PWD\ReadyRunGame_runtime.exe" -Wait
}
else {
# 如果 "$PWD\Runtime" 路径不存在,则可以在这里添加其他操作
}
#解压
# 检查 $GameFolderName.* 文件是否存在
if (Test-Path "$PWD\$GameFile.*") {
# 如果$GameFile文件存在 检查 $GameFolderName-update.7z 文件是否存在
if (Test-Path "$PWD\$GameFile.7z") {
Expand-7Zip x "$PWD\$GameFile.7z" -o"$TempssdFolder" -aoa
}
if (Test-Path "$PWD\$GameFile.tar") {
Expand-7Zip x "$PWD\$GameFile.tar" -o"$TempssdFolder" -aoa
#创建SHA256表
{
# 创建一个空的哈希表来存储文件路径和对应的哈希值
$hashTable = @{}
# 获取目录 A 中所有文件的列表
$files = Get-ChildItem -Path "$TempssdFolder" -Recurse
# 遍历文件列表,计算每个文件的 SHA256 哈希值
foreach ($file in $files) {
if (!$file.PSIsContainer) {
$hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash
# 将文件的相对路径和哈希值添加到哈希表中
$relativePath = $file.FullName.Substring($TempssdFolder.Length + 1)
$hashTable[$relativePath] = $hash
}
}
# 将哈希表中的内容转换为字符串,并保存到 fileA.txt
$hashTableString = $hashTable.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }
$hashTableString | Out-File "$TempssdFolder.txt" -Encoding UTF8
}
}
if (Test-Path "$PWD\$GameFileUpdata.7z") {
Expand-7Zip x "$PWD\$GameFileUpdata.7z" -o"$TempssdFolder" -aoa
}
} else { }
#软连接
{
# 获取源目录根下的所有文件夹和文件
$TempssdFolderitems = Get-ChildItem -Path $TempssdFolder -Name
# 为每个文件或文件夹创建软链接
foreach ($TempssdFolderitem in $TempssdFolderitems) {
$GameFolderlink = Join-Path -Path $PWD -ChildPath $TempssdFolderitem
$TempssdFoldertarget = Join-Path -Path $TempssdFolder -ChildPath $TempssdFolderitem
New-Item -ItemType SymbolicLink -Path $GameFolderlink -Target $TempssdFoldertarget
}}
ReadyRunGame_runtime
nodvd的游戏内部的游戏数据文件是可删的,一般安装位置如果存在这些文件就没有问题
bin光盘映像建议转化iso后另存为,转载后可解决游戏不识别的问题。
. "$PWD\UserVar.ps1"
#挂载无nodisk补丁游戏运行文件
#文件在Runtime挂载
#游戏的nodisk补丁无用时使用
if (Test-Path "$PWD\Runtime") {
Start-Process "$PWD\ReadyRunGame_runtime.exe" -Wait
} else {
# 如果 "$PWD\Runtime" 路径不存在,则可以在这里添加其他操作
}
#解压
# 检查 $GameFolderName.* 文件是否存在
if ((Test-Path "$PWD\${GameFile}.7z") -or (Test-Path "$PWD\${GameFile}.tar")) {
# 如果$GameFile文件存在 检查 $GameFolderName-update.7z 文件是否存在
if (Test-Path "$PWD\${GameFile}.7z") {
Expand-7Zip x "$PWD\${GameFile}.7z" -o"$TempssdFolder" -aoa
}
if (Test-Path "$PWD\${GameFile}.tar") {
Expand-7Zip x "$PWD\${GameFile}.tar" -o"$TempssdFolder" -aoa
#创建SHA256表
$hashTable = @{}
# 获取目录 A 中所有文件的列表
$files = Get-ChildItem -Path "$TempssdFolder" -Recurse
# 遍历文件列表,计算每个文件的 SHA256 哈希值
foreach ($file in $files) {
if (!$file.PSIsContainer) {
$hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash
# 将文件的相对路径和哈希值添加到哈希表中
$relativePath = $file.FullName.Substring($TempssdFolder.Length + 1)
$hashTable[$relativePath] = $hash
}
}
# 将哈希表中的内容转换为字符串,并保存到 fileA.txt
$hashTableString = $hashTable.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }
$hashTableString | Out-File "$TempssdFolder.txt" -Encoding UTF8
}
if (Test-Path "$PWD\${GameFileUpdata}.7z") {
Expand-7Zip x "$PWD\${GameFileUpdata}.7z" -o"$TempssdFolder" -aoa
}
} else { }
# 创建软链接
if (Test-Path "$TempssdFolder") {
# 获取源目录根下的所有文件夹和文件
$TempssdFolderitems = Get-ChildItem -Path $TempssdFolder -Name
# 为每个文件或文件夹创建软链接
foreach ($TempssdFolderitem in $TempssdFolderitems) {
$GameFolderlink = Join-Path -Path $PWD -ChildPath $TempssdFolderitem
$TempssdFoldertarget = Join-Path -Path $TempssdFolder -ChildPath $TempssdFolderitem
New-Item -ItemType SymbolicLink -Path $GameFolderlink -Target $TempssdFoldertarget
}}
ReadyCloseGame_linktemp
改动最大的部分。
匹配游戏本体目录中,如果重复出现2个于2个以上则使用tar模式压缩
如果需要自动硬链接也能自行添加在这一部分
(在139行之前加这个功能,具体写法可用要求bingai)
Compress-7Zip a "$PWD\$GameFile.tar" "$PWD\*" -mx=9 -snh -snl @7zipExclusionParams
咒语参考
如何使用PS1脚本编写以下命令
计算目录A中文件的sha256,保存到文件A。
比较文件A中的计算记录,只有当文件的文件名、文件大小与sha256均相同的情况下,将这些全部相同的文件进行硬链接。
硬链接的tar文件用更新模式有很多奇奇怪怪的问题,包括但不限于重复压缩 文字乱码 硬链接失效等,
powershell自带的比7zip的更吓人。
最后用的查重删除命令解决的,
. "$PWD\UserVar.ps1"
#Runtime 卸载
#游戏的 nodisk 补丁无用时使用
if (Test-Path "$PWD\Runtime") {
Start-Process "$PWD\ReadyCloseGame_runtime.exe" -Wait
}else {
# 如果 "$PWD\Runtime" 路径不存在,则可以在这里添加其他操作
}
#安装文件压缩
if (Test-Path "$PWD\Install") {
if (Test-Path "$PWD\${GameFileInstall}.7z") {
# 等待用户按下任意键
$null = Read-Host "存在 Install 目录与 Install 压缩包,你最好检查一下"
} else {
Compress-7Zip a "$PWD\${GameFileInstall}.7z" "$PWD\Install\*" -mx=9 -m0=LZMA2 -snh -snl -md=256m -ms=on -mfb=273 -mmc=10000000 -bsp1
Remove-Item "$PWD\Install" -Recurse -Force
}
} else {
# 继续执行脚本的其他部分
}
#Extra 文件压缩
if (Test-Path "$PWD\Extra") {
if (Test-Path "$PWD\${GameFileExtra}.7z") {
# 等待用户按下任意键
$null = Read-Host "存在 Extra 目录与 Extra 压缩包,你最好检查一下,将其分别入库"
} else {
Compress-7Zip a "$PWD\${GameFileExtra}.7z" "$PWD\Extra\*" -mx=9 -m0=LZMA2 -snh -snl -md=256m -ms=on -mfb=273 -mmc=10000000 -bsp1
Remove-Item "$PWD\Extra" -Recurse -Force
}
} else {
# 继续执行脚本的其他部分
}
#游戏文件压缩
# 如果 "$PWD\$GameFile" 文件存在
if ((Test-Path "$PWD\${GameFile}.7z") -or (Test-Path "$PWD\${GameFile}.tar")) {
# 如果 "$PWD\${GameFile}.7z" 文件存在
if (Test-Path "$PWD\${GameFile}.7z") {
# 如果 ${GameFileUpdata}.7z 文件存在
if (Test-Path "$PWD\${GameFileUpdata}.7z") {
# 删除 ${GameFileUpdata}.7z 文件
Remove-Item "$PWD\${GameFileUpdata}.7z" -Recurse -Force
}
# 使用更新模式将对象添加到 ${GameFile}.7z
Compress-7Zip u "$PWD\${GameFile}.7z" "$TempssdFolder\*" -mx9 -u- -up0q3x2z0!GameUpdatasave @7zipExclusionParams
Rename-Item -Path "$PWD\GameUpdatasave.7z" -NewName "${GameFileUpdata}.7z"
}
# 如果 "$PWD\${GameFile}.tar" 文件存在
if (Test-Path "$PWD\${GameFile}.tar") {
# 创建 SHA256 表
$hashTable = @{}
# 获取目录 A 中所有文件的列表
$files = Get-ChildItem -Path "$TempssdFolder" -Recurse
# 遍历文件列表,计算每个文件的 SHA256 哈希值
foreach ($file in $files) {
if (!$file.PSIsContainer) {
$hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash
# 将文件的相对路径和哈希值添加到哈希表中
$relativePath = $file.FullName.Substring($TempssdFolder.Length + 1)
$hashTable[$relativePath] = $hash
}
}
# 将哈希表中的内容转换为字符串,并保存到 fileA.txt
$hashTableString = $hashTable.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }
$hashTableString | Out-File "$TempssdFolder-Updata.txt" -Encoding UTF8
# 从文件 A 和文件 B 中读取比较哈希值,并删除匹配的文件
# 从文件 A 和文件 B 中读取哈希值和相关信息
$hashInfoA = Get-Content "${TempssdFolder}.txt" -Raw | ConvertFrom-StringData
$hashInfoB = Get-Content "${TempssdFolder}-Updata.txt" -Raw | ConvertFrom-StringData
# 比较文件 A 和文件 B 中记录的哈希值,并删除匹配的文件
foreach ($key in $hashInfoA.Keys) {
if ($hashInfoB.ContainsKey($key) -and $hashInfoA[$key] -eq $hashInfoB[$key]) {
$fileToDelete = Join-Path "$TempssdFolder" $key
if (Test-Path $fileToDelete) {
Remove-Item $fileToDelete -Force
Write-Host "已删除文件: $fileToDelete"
} else {
Write-Host "未找到文件: $fileToDelete"
}
}
}
if (Test-Path "$PWD\${GameFileUpdata}.7z") {
# 如果文件存在,则删除 ${GameFileUpdata}.tar 文件
Remove-Item "$PWD\${GameFileUpdata}.7z" -Recurse -Force
}
Compress-7Zip a "$PWD\${GameFileUpdata}.7z" "$TempssdFolder\*" -mx=9 -m0=LZMA2 -snh -snl -md=256m -ms=on -mfb=273 -mmc=10000000 -bsp1 @7zipExclusionParams
}
#删除主目录的软连接
# 获取目录 A 中的所有项
$itemsInDirectoryGame = Get-ChildItem -Path "$PWD"
# 遍历目录 A 中的每个项
foreach ($item in $itemsInDirectoryGame) {
# 检查是否为软链接
if ($item.Attributes -band ::ReparsePoint) {
# 删除软链接
Remove-Item -Path $item.FullName -Recurse -Force
} }
#清理 temp
Remove-Item -Path "$TempssdFolder" -Recurse -Force
Remove-Item -Path "${TempssdFolder}.txt" -Recurse -Force
Remove-Item -Path "${TempssdFolder}-Updata.txt" -Recurse -Force
} else {
# 如果文件不存在,使用创建 $GameFile 文件
# 定义要匹配的文件夹模式
$GameFolderTest = @(
"*CHI*",
"*ENG*",
"*JPN*",
"*$GameFile*"
)
# 获取匹配模式的文件夹列表
$GameFolderTestList = Get-ChildItem -Path $PWD -Recurse -Directory | Where-Object {
foreach ($pattern in $GameFolderTest) {
if ($_.Name -like $pattern) {
return $true
}
}
return $false
}
if ($GameFolderTestList.Count -ge 2) {
Compress-7Zip a "$PWD\${GameFile}.tar" "$PWD\*" -mx=9 -snh -snl @7zipExclusionParams
}
if ($GameFolderTestList.Count -eq 1) {
Compress-7Zip a "$PWD\${GameFile}.7z" "$PWD\*" -mx=9 -m0=LZMA2 -snh -snl -md=256m -ms=on -mfb=273 -mmc=10000000 -bsp1 @7zipExclusionParams
}
}
#清理主目录
if ((Test-Path "$PWD\${GameFile}.7z") -or (Test-Path "$PWD\${GameFile}.tar")) {
# 定义要排除的文件和文件夹模式数组
$delitemsToExclude = @(
"$PWD\*.iso",
"$PWD\${GameFile}.*", "$PWD\${GameFileUpdata}.*", "$PWD\${GameFileInstall}.*",
"$PWD\ReadyRunGame_linktemp.exe", "$PWD\ReadyCloseGame_linktemp.exe", "$PWD\ReadyRunGame_runtime.exe", "$PWD\ReadyCloseGame_runtime.exe", "$PWD\UserVar.ps1", "$PWD\Game_Clean.exe"
"$PWD\Runtime", "$PWD\Runtime\*", "$PWD\Install", "$PWD\Install\*", "$PWD\Extra", "$PWD\Extra\*"
)
$delitemsToRemove = Get-ChildItem -Path $PWD -Recurse | Where-Object {
$exclude = $false
foreach ($delpattern in $delitemsToExclude) {
if ($_.FullName -like $delpattern) {
$exclude = $true
break
}
}
-not $exclude # 如果没有匹配任何排除模式,则选择该项
}
# 检查每个项是否存在,然后删除
foreach ($delitem in $delitemsToRemove) {
if (Test-Path $delitem.FullName) {
Remove-Item $delitem.FullName -Recurse -Force
}
}
}
Start-Process "$PWD\Game_Clean.exe"
ReadyCloseGame_runtime
# 导入变量
. "$PWD\UserVar.ps1"
# 定义要匹配的文件模式数组
$GameRuntimeitemsToInclude = @("$PWD\Runtime\*.iso")
# 获取 Runtime 文件夹中所有文件,并只选择匹配的文件模式
$GameRuntimeitemsToRuntimePath = Get-ChildItem -Path "$PWD\Runtime" -Recurse | Where-Object {
foreach ($GameRuntimepattern in $GameRuntimeitemsToInclude) {
if ($_.FullName -like $GameRuntimepattern) {
return $true # 如果匹配包含模式,则选择该项
}
}
return $false # 如果没有匹配任何包含模式,则不选择该项
}
# 挂载匹配的磁盘映像
foreach ($GameRuntimeitem in $GameRuntimeitemsToRuntimePath) {
if (Test-Path $GameRuntimeitem.FullName) {
Dismount-DiskImage -ImagePath $GameRuntimeitem.FullName
}
}
# 检查特定路径的程序是否正在运行
$exePath = "$PWD\ReadyCloseGame_linktemp.exe"
$processes = Get-WmiObject Win32_Process | Select-Object ExecutablePath
$running = $processes | Where-Object { $_.ExecutablePath -eq $exePath }
if ($running) {
# 如果程序正在运行
# 在这里添加您想要执行的操作
} else {
# 如果程序未运行
Start-Process -FilePath "$PWD\Game_Clean.exe"
}
放到设置的全局脚本里面
$PlayniteInstallDir = $PlayniteApi.ExpandGameVariables($game, "{PlayniteDir}\app")
$files = @("$PlayniteInstallDir\ReadyRunGame_linktemp.exe", "$PlayniteInstallDir\ReadyCloseGame_linktemp.exe", "$PlayniteInstallDir\ReadyRunGame_runtime.exe", "$PlayniteInstallDir\ReadyCloseGame_runtime.exe", "$PlayniteInstallDir\UserVar.ps1", "$PlayniteInstallDir\Game_Clean.exe")
$GameInstallDir = $PlayniteApi.ExpandGameVariables($game, "{InstallDir}")
放到游戏F3的脚本里面
游戏执行前
Copy-Item -LiteralPath $files -Destination $GameInstallDir -Verbose
Start-Process "$GameInstallDir\ReadyRunGame_linktemp.exe" -Verb RunAs -Wait
游戏执行后
Copy-Item -LiteralPath $files -Destination $GameInstallDir -Verbose
Start-Process "$GameInstallDir\ReadyCloseGame_linktemp.exe" -Verb RunAs -Wait
Start-Sleep -Seconds 5
Remove-Item -Path "$GameInstallDir\Game_Clean.exe" -Recurse -Force
如果你的Game_Clean是ps1脚本,可用删掉
Start-Sleep -Seconds 5
Remove-Item -Path "$GameInstallDir\Game_Clean.exe" -Recurse -Force
用脚本自删的命令
看起来很专业的脚本惹,看起来节省了大量空间呀{:6_165:} 挺方便的脚本,这个可以给网盘做一下瘦身了。 感谢大佬,大佬技术力太高了,可惜我盘里都是奇奇怪怪的东西惹。 看了看楼主之前的帖子,竟然可以有这么多游戏,真的是阅历丰富惹_(:з」∠)_感觉等我以后盘里游戏变多了的话可以用试试,会很好使的感觉~ 好专业的样子,但我刚买了新电脑,暂时用不到嘿嘿~ 流程真的是很复杂了,不过最后效果还不错 哇哦,确实攒了很多VN资源,也很占空间,这下可以攒更多的资源了{:6_169:} 我是一个大容量机械盘存东西,一个固态作为系统和游戏盘,游戏需要玩的时候才会解压到游戏盘玩完就删所以都够用,不过VN也不太需要放到固态 只看这一段代码比上次能接受度高了很多,可以学习以备使用啦 感谢!以后就有法子了 :L:L:L完全看不懂的程度啊思密达 码住,刚换了新电脑暂时还用不上惹{:4_114:} 很有用呢,不过换了硬盘现在空间还够,先收藏了 看不懂但是不妨碍我收藏起来说不定哪天用上了{:4_108:} 老师老师,怎样可以最大程度压缩小说漫画视频{:3_54:} 哇哦下,相当硬核的教程了,确实游戏有点多,硬盘满了 有点想试一下 但素看到这些电脑技术类的东西就有点头疼惹 学习一下,感觉以后会用上的说{:6_167:} 看着很有用的样子,先mark一下,硬盘不够用的时候来看看
页:
[1]
2