Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hex
ygopro2
Commits
19910d74
Commit
19910d74
authored
Jul 19, 2025
by
hex
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Optimized UnityFileDownloader.cs
parent
3e267a81
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
142 additions
and
35 deletions
+142
-35
Assets/NGUI/Scripts/UI/UITexture.cs
Assets/NGUI/Scripts/UI/UITexture.cs
+1
-1
Assets/SibylSystem/CardDescription/CardDescription.cs
Assets/SibylSystem/CardDescription/CardDescription.cs
+40
-31
Assets/SibylSystem/Program.cs
Assets/SibylSystem/Program.cs
+3
-3
Assets/SibylSystem/ResourceManagers/UnityFileDownloader.cs
Assets/SibylSystem/ResourceManagers/UnityFileDownloader.cs
+98
-0
No files found.
Assets/NGUI/Scripts/UI/UITexture.cs
View file @
19910d74
...
...
@@ -46,7 +46,7 @@ public class UITexture : UIBasicSprite
protected
override
void
OnStart
()
{
base
.
OnStart
();
if
(
mOutPath
!=
""
)
if
(
mOutPath
!=
null
&&
mOutPath
!=
""
)
{
mainTexture
=
GameTextureManager
.
get
(
mOutPath
);
}
...
...
Assets/SibylSystem/CardDescription/CardDescription.cs
View file @
19910d74
using
System
;
using
System.Text
;
using
System.Collections.Generic
;
using
UnityEngine
;
using
YGOSharp.OCGWrapper.Enums
;
...
...
@@ -27,7 +28,7 @@ public class CardDescription : Servant
Program
.
camera_main_2d
.
ScreenToWorldPoint
(
new
Vector3
(-
256
,
Screen
.
height
/
2
,
600
)),
new
Vector3
(
0
,
0
,
0
),
true
,
Program
.
ui_
back_ground
_2d
Program
.
ui_
main
_2d
);
picLoader
=
gameObject
.
AddComponent
<
cardPicLoader
>();
picLoader
.
code
=
0
;
...
...
@@ -453,52 +454,60 @@ public class CardDescription : Servant
List
<
string
>
Logs
=
new
List
<
string
>();
private
StringBuilder
logBuilder
=
new
StringBuilder
(
1024
);
// 在类成员中创建一个 StringBuilder 实例,初始容量为1024字符,避免频繁扩容
public
void
mLog
(
string
result
)
{
Logs
.
Add
(
result
);
string
all
=
""
;
for
(
int
i
=
0
;
i
<
Logs
.
Count
;
i
++)
// 1. 添加新日志到列表
Logs
.
Add
(
result
.
Replace
(
"\0"
,
""
));
// 在添加时就替换掉空字符
// 2. [可选但推荐] 控制日志列表的最大长度,防止无限增长
if
(
Logs
.
Count
>
50
)
// 例如,最多保留50条日志
{
if
(
i
==
Logs
.
Count
-
1
)
{
all
+=
Logs
[
i
].
Replace
(
"\0"
,
""
);
}
else
{
all
+=
Logs
[
i
].
Replace
(
"\0"
,
""
)
+
"\n"
;
}
Logs
.
RemoveAt
(
0
);
}
UIHelper
.
trySetLableTextList
(
UIHelper
.
getByName
(
gameObject
,
"chat_"
),
all
);
// 3. 更新UI显示
UpdateLogDisplay
();
// 4. 设置定时清除
Program
.
go
(
8000
,
clearOneLog
);
}
void
clearOneLog
()
{
if
(
Logs
.
Count
>
0
)
if
(
Logs
.
Count
>
0
)
{
Logs
.
RemoveAt
(
0
);
string
all
=
""
;
foreach
(
var
item
in
Logs
)
{
all
+=
item
+
"\n"
;
}
try
{
all
=
all
.
Substring
(
0
,
all
.
Length
-
1
);
}
catch
(
System
.
Exception
e
)
{
}
UIHelper
.
trySetLableTextList
(
UIHelper
.
getByName
(
gameObject
,
"chat_"
),
all
);
UpdateLogDisplay
();
}
else
}
// 提取出的公共方法,用于更新UI
private
void
UpdateLogDisplay
()
{
// 1. 清空 StringBuilder
logBuilder
.
Length
=
0
;
// 2. 高效地构建日志字符串
for
(
int
i
=
0
;
i
<
Logs
.
Count
;
i
++)
{
logBuilder
.
AppendLine
(
Logs
[
i
]);
// AppendLine 会自动在末尾添加换行符
}
// 3. 将最终结果设置到UI控件
// getByName 可能会有性能开销,如果这个方法被非常频繁调用,可以考虑缓存这个GameObject
GameObject
chatObject
=
UIHelper
.
getByName
(
gameObject
,
"chat_"
);
if
(
chatObject
!=
null
)
{
UIHelper
.
trySetLableTextList
(
UIHelper
.
getByName
(
gameObject
,
"chat_"
),
""
);
UIHelper
.
trySetLableTextList
(
chatObject
,
logBuilder
.
ToString
()
);
}
}
public
void
clearAllLog
()
{
Program
.
notGo
(
clearOneLog
);
Program
.
notGo
(
clearOneLog
);
// 取消所有待执行的 clearOneLog 任务
Logs
.
Clear
();
U
IHelper
.
trySetLableTextList
(
UIHelper
.
getByName
(
gameObject
,
"chat_"
),
""
);
U
pdateLogDisplay
();
// 清空列表后,调用一次更新方法来清空UI
}
}
Assets/SibylSystem/Program.cs
View file @
19910d74
...
...
@@ -552,7 +552,7 @@ public class Program : MonoBehaviour
string
cardsUrl
=
"https://cdn02.moecube.com:444/koishipro/ygopro-database/zh-CN/cards.cdb"
;
string
cardsPath
=
Path
.
Combine
(
dbDir
,
"cards.cdb"
);
yield
return
StartCoroutine
(
UnityFileDownloader
.
DownloadFile
Async
(
UnityFileDownloader
.
DownloadFile
WithHeadCheck
(
cardsUrl
,
cardsPath
,
(
success
)
=>
...
...
@@ -570,7 +570,7 @@ public class Program : MonoBehaviour
string
lflistUrl
=
"https://cdn02.moecube.com:444/koishipro/ygopro-database/zh-CN/lflist.conf"
;
string
lflistPath
=
Path
.
Combine
(
dbDir
,
"lflist.conf"
);
yield
return
StartCoroutine
(
UnityFileDownloader
.
DownloadFile
Async
(
UnityFileDownloader
.
DownloadFile
WithHeadCheck
(
lflistUrl
,
lflistPath
,
(
success
)
=>
...
...
@@ -588,7 +588,7 @@ public class Program : MonoBehaviour
"https://cdn02.moecube.com:444/koishipro/ygopro-database/zh-CN/strings.conf"
;
string
stringsPath
=
Path
.
Combine
(
dbDir
,
"strings.conf"
);
yield
return
StartCoroutine
(
UnityFileDownloader
.
DownloadFile
Async
(
UnityFileDownloader
.
DownloadFile
WithHeadCheck
(
stringsUrl
,
stringsPath
,
(
success
)
=>
...
...
Assets/SibylSystem/ResourceManagers/UnityFileDownloader.cs
View file @
19910d74
...
...
@@ -86,6 +86,104 @@ public class UnityFileDownloader
}
}
/// <summary>
/// 检查文件版本,如果不是最新则下载。
/// 最终结果统一为成功(true)或失败(false)。
/// </summary>
/// <param name="url">文件下载地址</param>
/// <param name="filePath">文件本地存储路径</param>
/// <param name="onComplete">完成时的回调。true表示成功(已是最新或已下载),false表示失败。</param>
/// <param name="onProgress">下载过程中的进度回调(仅在需要下载时触发)</param>
public
static
IEnumerator
DownloadFileWithHeadCheck
(
string
url
,
string
filePath
,
Action
<
bool
>
onComplete
,
Action
<
float
>
onProgress
=
null
)
// 移除了onProgress的默认值null,以兼容旧版C#
{
string
etagFilePath
=
filePath
+
".etag"
;
string
localEtag
=
null
;
bool
localFileExists
=
File
.
Exists
(
filePath
);
// 1. 读取本地ETag(如果存在)
if
(
File
.
Exists
(
etagFilePath
))
{
try
{
localEtag
=
File
.
ReadAllText
(
etagFilePath
);
}
catch
(
Exception
e
)
{
Debug
.
LogWarning
(
string
.
Format
(
"读取本地ETag文件失败: {0}. Error: {1}. 将强制更新。"
,
etagFilePath
,
e
.
Message
));
localEtag
=
null
;
// 读取失败则当做不存在
}
}
// 2. 发送HEAD请求获取服务器ETag
Debug
.
Log
(
string
.
Format
(
"[HEAD] 正在检查: {0}"
,
Path
.
GetFileName
(
filePath
)));
UnityWebRequest
headRequest
=
UnityWebRequest
.
Head
(
url
);
yield
return
headRequest
.
SendWebRequest
();
if
(
headRequest
.
isNetworkError
||
headRequest
.
isHttpError
)
{
Debug
.
LogError
(
string
.
Format
(
"[HEAD] 请求失败: {0}\n错误: {1}"
,
url
,
headRequest
.
error
));
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
false
);
yield
break
;
}
string
serverEtag
=
headRequest
.
GetResponseHeader
(
"ETag"
);
if
(
string
.
IsNullOrEmpty
(
serverEtag
))
{
Debug
.
LogError
(
string
.
Format
(
"[HEAD] 服务器未提供ETag头信息: {0}"
,
url
));
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
false
);
yield
break
;
}
Debug
.
Log
(
string
.
Format
(
"版本比较: Local ETag='{0}', Server ETag='{1}'"
,
localEtag
,
serverEtag
));
// 3. 比较ETag
if
(
localFileExists
&&
!
string
.
IsNullOrEmpty
(
localEtag
)
&&
localEtag
.
Equals
(
serverEtag
))
{
Debug
.
Log
(
string
.
Format
(
"[OK] 文件已是最新版本: {0}"
,
Path
.
GetFileName
(
filePath
)));
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
true
);
// 已是最新,也算成功
yield
break
;
}
// 4. ETag不匹配或本地文件不存在,执行下载
Debug
.
Log
(
string
.
Format
(
"发现新版本或本地文件不存在,开始下载: {0}"
,
Path
.
GetFileName
(
filePath
)));
// --- Chaining Coroutine to get the result ---
bool
downloadSucceeded
=
false
;
// 创建一个回调,用于从DownloadFileAsync获取其执行结果
Action
<
bool
>
downloadCallback
=
delegate
(
bool
success
)
{
downloadSucceeded
=
success
;
};
// 调用下载协程,并等待它完成
yield
return
DownloadFileAsync
(
url
,
filePath
,
downloadCallback
,
onProgress
);
// --- Coroutine finished, now check the result ---
// 5. 下载完成后,更新ETag并回调
if
(
downloadSucceeded
)
{
try
{
File
.
WriteAllText
(
etagFilePath
,
serverEtag
);
Debug
.
Log
(
string
.
Format
(
"成功保存新的ETag到: {0}"
,
etagFilePath
));
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
true
);
// 下载并保存ETag成功
}
catch
(
Exception
e
)
{
Debug
.
LogError
(
string
.
Format
(
"保存ETag文件失败: {0}. Error: {1}"
,
etagFilePath
,
e
.
Message
));
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
false
);
// ETag保存失败,算整体失败
}
}
else
{
// DownloadFileAsync 内部已经打印了错误日志
if
(
onComplete
!=
null
)
onComplete
.
Invoke
(
false
);
// 下载失败
}
}
private
static
int
GetTimeoutForFile
(
string
filename
)
{
string
extension
=
Path
.
GetExtension
(
filename
).
ToLower
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment