Commit a992169d authored by hex's avatar hex

fix download pic

parent e624f859
Pipeline #39153 failed
using UnityEngine;
using System.Collections;
using System.Collections;
using DG.Tweening;
using UnityEngine;
public class toolShift : MonoBehaviour {
public class toolShift : MonoBehaviour
{
public GameObject ObjectMust = null;
public GameObject ObjectOption = null;
......@@ -42,31 +43,28 @@ public class toolShift : MonoBehaviour {
}
public void shift()
{
// 获取当前对象的本地坐标
Vector3 va = ObjectMust.transform.localPosition;
const float duration = 0.6f;
if (ObjectOption == null)
{
// 目标Y坐标,根据当前位置在 0 和 -100 之间切换
float targetY = (va.y >= 0) ? -100f : 0f;
// 使用 DOTween 的 DOLocalMoveY,因为它只改变Y轴,意图更明确且性能稍好
ObjectMust.transform.DOLocalMoveY(targetY, duration);
}
else
{
Vector3 vb = ObjectOption.transform.localPosition;
if (va.y > vb.y)
Vector3 va = ObjectMust.transform.localPosition;
const float duration = 0.6f;
if (ObjectOption == null)
{
ObjectMust.transform.DOLocalMoveY(-100f, duration);
ObjectOption.transform.DOLocalMoveY(0f, duration);
float targetY = (va.y >= 0) ? -100f : 0f;
ObjectMust.transform.DOLocalMoveY(targetY, duration);
}
else
{
ObjectMust.transform.DOLocalMoveY(0f, duration);
ObjectOption.transform.DOLocalMoveY(-100f, duration);
Vector3 vb = ObjectOption.transform.localPosition;
if (va.y > vb.y)
{
ObjectMust.transform.DOLocalMoveY(-100f, duration);
ObjectOption.transform.DOLocalMoveY(0f, duration);
}
else
{
ObjectMust.transform.DOLocalMoveY(0f, duration);
ObjectOption.transform.DOLocalMoveY(-100f, duration);
}
}
}
}
}
......@@ -695,7 +695,7 @@ public class gameCard : OCGobject
//Program.I().audio.clip = Program.I().dididi;
//Program.I().audio.Play();
//deltaTimeCloseUp = 0;
DOTween.Kill(gameObject.transform);
gameObject.transform.DOKill();
if (condition == gameCardCondition.floating_clickable)
{
flash_line_on();
......@@ -874,7 +874,7 @@ public class gameCard : OCGobject
// Let's use the calculated one unless we want a specific "exciting" ease.
// The original code passed no ease, so we will not set one, letting DOTween use its default.
}
bool useArcPath = exciting ||
(Mathf.Abs(gameObject.transform.eulerAngles.x) < 10 && Vector3.Distance(pos, gameObject.transform.position) > 1f) ||
(accurate_position.x == pos.x && accurate_position.y < pos.y && accurate_position.z == pos.z);
......@@ -896,7 +896,7 @@ public class gameCard : OCGobject
float t = (float)i / 29f;
path[i] = from + (to - from) * t + new Vector3(0, 1.5f, 0) * Mathf.Sin(Mathf.PI * t);
}
// Execute path and rotation tweens.
gameObject.transform.DOPath(path, time).SetEase(easeType);
gameObject.transform.DORotate(rot, time).SetEase(easeType);
......@@ -2299,7 +2299,7 @@ public class gameCard : OCGobject
)
{
ES_lock(time_move + time_move + time_still);
gameObject.transform.DOKill();
// Create a sequence to chain the animations together
......@@ -2307,13 +2307,13 @@ public class gameCard : OCGobject
// 1. Move to the specified position and rotation
confirmSequence.Append(gameObject.transform.DOMove(position, time_move));
confirmSequence.Join(gameObject.transform.DORotate(rotation, time_move));
// 2. Wait for the specified "still" time
confirmSequence.AppendInterval(time_still);
// 3. Move back to the original accurate position and rotation
confirmSequence.Append(gameObject.transform.DOMove(accurate_position, time_move).SetEase(Ease.InQuad));
confirmSequence.Join(gameObject.transform.DORotate(accurate_rotation, time_move));
// 4. Set an OnUpdate for the entire sequence to keep decorations in place
confirmSequence.OnUpdate(RefreshFunction_decoration);
// We can assign the sequence to the transform to have it managed automatically
......@@ -2324,7 +2324,7 @@ public class gameCard : OCGobject
{
ES_lock(time_move + time_move + time_still);
gameObject.transform.DOKill();
// Handle the screenFader component as before
var ttt = gameObject.AddComponent<screenFader>();
ttt.from = gameObject.transform.position;
......@@ -2332,11 +2332,11 @@ public class gameCard : OCGobject
ttt.deltaTimeCloseUp = 0;
MonoBehaviour.Destroy(ttt, time_move + time_still);
Sequence confirmSequence = DOTween.Sequence();
// 1. Rotate with a spring-like ease. Ease.OutElastic is a good equivalent for iTween's "spring".
// The movement is handled by the screenFader component.
confirmSequence.Append(gameObject.transform.DORotate(rotation, time_move).SetEase(Ease.OutElastic));
// 2. Hold
confirmSequence.AppendInterval(time_still);
// 3. Return to original state. The original called confirm_step_3, which we replicate here.
......@@ -2351,7 +2351,7 @@ public class gameCard : OCGobject
ES_lock(time);
gameObject.transform.position = accurate_position;
gameObject.transform.eulerAngles = accurate_rotation;
gameObject.transform.DOKill();
gameObject.transform.DOShakePosition(time, 1f)
......@@ -2377,7 +2377,7 @@ public class gameCard : OCGobject
{
return;
}
show_off_disabled = disabled;
show_off_begin_time = Program.TimePassed();
show_off_shokewave = summon;
......
......@@ -367,7 +367,7 @@ public class Program : MonoBehaviour
InterString.initialize("config/translation.conf");
// 显示一个简单的加载提示
PrintToChat(InterString.Get("正在加载本地数据..."));
GameTextureManager.initialize();
// GameTextureManager.initialize();
Config.initialize("config/config.conf");
// [新增] 封装文件加载逻辑,避免重复检查
......
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
......@@ -16,6 +17,51 @@ public enum GameTextureType
public class GameTextureManager
{
#region Main-Thread Bridge & Initialization
// ADDED: A structure to hold download request details.
internal struct DownloadRequest // 'internal' is good practice for helper structs
{
public string Url;
public string FilePath;
public PictureResource PicResource;
}
// ADDED: A thread-safe queue for download requests from the background thread.
private static readonly Queue<DownloadRequest> downloadRequestQueue = new Queue<DownloadRequest>();
// ADDED: Unity will automatically call this method once when the game loads,
// before any scene loads. This is the perfect place to set up our helper.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void InitializeOnLoad()
{
// Create a hidden GameObject to host our runner.
GameObject runnerObject = new GameObject("GameTextureManagerRunner");
// Add our runner component to it.
runnerObject.AddComponent<GameTextureManagerRunner>();
// Ensure it persists across scene changes.
GameObject.DontDestroyOnLoad(runnerObject);
// The original initialize logic now goes here.
Initialize();
}
// ADDED: Helper methods for the runner to interact with the queue.
internal static bool HasDownloadRequests()
{
return downloadRequestQueue.Count > 0;
}
internal static DownloadRequest GetNextDownloadRequest()
{
lock(downloadRequestQueue)
{
return downloadRequestQueue.Dequeue();
}
}
#endregion
static bool bLock = false;
static Stack<PictureResource> waitLoadStack = new Stack<PictureResource>();
......@@ -118,7 +164,7 @@ public class GameTextureManager
}
}
private class PictureResource
public class PictureResource
{
public GameTextureType type;
public long code;
......@@ -199,10 +245,41 @@ public class GameTextureManager
public static Texture2D rs = null;
public static Texture2D ts = null;
internal static IEnumerator DownloadAndProcessFile(DownloadRequest request)
{
yield return UnityFileDownloader.DownloadFileAsync(request.Url, request.FilePath, (success) =>
{
if (success)
{
Debug.Log("Download successful, processing card picture: " + request.PicResource.code);
LoadCardPicture(request.PicResource, request.FilePath);
}
else
{
Debug.LogWarning("Download failed for card: " + request.PicResource.code);
LoadCardPicture(request.PicResource, request.FilePath); // Let it handle the missing file
}
});
}
private static Thread main_thread;
// MODIFIED: In your original code, Program.Running was used. This is a more robust way.
private static bool IsRunning = true;
// Call this method from your main game logic on application quit to stop the thread.
public static void Shutdown()
{
IsRunning = false;
if(main_thread != null && main_thread.IsAlive)
{
main_thread.Join(100);
}
}
static void thread_run()
{
while (Program.Running)
while (IsRunning)
{
try
{
......@@ -236,20 +313,20 @@ public class GameTextureManager
switch (pic.type)
{
case GameTextureType.card_feature:
{
ProcessingCardFeature(pic);
break;
}
{
ProcessingCardFeature(pic);
break;
}
case GameTextureType.card_picture:
{
ProcessingCardPicture(pic);
break;
}
{
ProcessingCardPicture(pic);
break;
}
case GameTextureType.card_verticle_drawing:
{
ProcessingVerticleDrawing(pic);
break;
}
{
ProcessingVerticleDrawing(pic);
break;
}
}
}
}
......@@ -411,37 +488,6 @@ public class GameTextureManager
private static void caculateK(PictureResource pic)
{
//int width = pic.hashed_data.GetLength(0);
//int height = pic.hashed_data.GetLength(1);
//int left = 0;
//int right = width;
//if (width > height)
//{
// left = (width - height) / 2;
// right = width - left;
//}
//int all = 0;
//for (int h = 0; h < height; h++)
//{
// for (int w = left; w < right; w++)
// {
// if (pic.hashed_data[w, h, 3] > 0.05f)
// {
// all += 1;
// }
// }
//}
//float result = ((float)all) / (((float)height) * ((float)(height)));
//pic.k = result + 0.4f;
//if (pic.k > 1)
//{
// pic.k = 1f;
//}
//if (pic.k < 0)
//{
// pic.k = 0.1f;
//}
int width = pic.hashed_data.GetLength(0);
int height = pic.hashed_data.GetLength(1);
int h = 0;
......@@ -848,16 +894,33 @@ public class GameTextureManager
}
if (!File.Exists(path) && pic.code != 0 && AutoPicDownload)
{
//YGOMobile (177x254)
df.Download(
"http://cdn01.moestart.com/images/ygopro-images-zh-CN/"
+ pic.code.ToString()
+ ".jpg",
"picture/card/" + pic.code.ToString() + ".jpg"
);
path = "picture/card/" + pic.code.ToString() + ".jpg";
// //YGOMobile (177x254)
// df.Download(
// "http://cdn01.moestart.com/images/ygopro-images-zh-CN/"
// + pic.code.ToString()
// + ".jpg",
// "picture/card/" + pic.code.ToString() + ".jpg"
// );
// path = "picture/card/" + pic.code.ToString() + ".jpg";
string url = "https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/" + pic.code.ToString() + ".jpg";
// string url = "http://cdn01.moestart.com/images/ygopro-images-zh-CN/" + pic.code.ToString() + ".jpg";
string finalPath = "picture/card/" + pic.code.ToString() + ".jpg";
// Enqueue the request. The runner on the main thread will pick it up.
lock (downloadRequestQueue)
{
downloadRequestQueue.Enqueue(new DownloadRequest
{
Url = url,
FilePath = finalPath,
PicResource = pic
});
}
}
else
{
LoadCardPicture(pic, path);
}
LoadCardPicture(pic, path);
}
catch (Exception e)
{
......@@ -1028,7 +1091,7 @@ public class GameTextureManager
public static UnityEngine.Color chainColor = UnityEngine.Color.white;
internal static void initialize()
internal static void Initialize()
{
attack = UIHelper.getTexture2D("textures/attack.png"); //YGOMobile Paths
myBack = UIHelper.getTexture2D("textures/cover.jpg"); //YGOMobile Paths
......@@ -1076,7 +1139,10 @@ public class GameTextureManager
); //YGOMobile Paths
}
catch (Exception) { }
Thread main = new Thread(thread_run);
main.Start();
if (main_thread == null)
{
main_thread = new Thread(thread_run);
main_thread.Start();
}
}
}
using System.Collections;
using UnityEngine;
/// <summary>
/// 这是一个 MonoBehaviour 帮助器,专为静态的 GameTextureManager 服务。
/// 它的职责是在主线程上执行任务,例如轮询下载队列和启动协程。
/// 这个类的实例由 GameTextureManager 通过 [RuntimeInitializeOnLoadMethod] 自动创建。
/// </summary>
public class GameTextureManagerRunner : MonoBehaviour
{
void Update()
{
// 在主线程的每一帧检查是否有待处理的下载请求
if (GameTextureManager.HasDownloadRequests())
{
// 从 GameTextureManager 获取一个请求
var request = GameTextureManager.GetNextDownloadRequest();
// 使用这个 MonoBehaviour 实例来启动下载协程
StartCoroutine(GameTextureManager.DownloadAndProcessFile(request));
}
}
}
fileFormatVersion: 2
guid: cb7d20dd5a7074bc089a6c75c87e34da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -29,39 +29,40 @@ public static class GlobalCertificateManager
SslPolicyErrors sslPolicyErrors
)
{
// return true;
// Case 1: 证书本身没有问题,直接通过
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
// Case 2: 如果错误是 RemoteCertificateChainErrors,
// 这通常意味着证书链有问题,比如找不到吊销列表或者根证书不受信任。
// 我们将尝试进行一次忽略吊销检查的自定义验证。
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
// 创建一个新的证书链对象
X509Chain customChain = new X509Chain();
// 都是从 cdn02 的官方资源下载,hook 掉不验证证书可以提高下载速度,但是有一定的安全风险
return true;
// // Case 1: 证书本身没有问题,直接通过
// if (sslPolicyErrors == SslPolicyErrors.None)
// {
// return true;
// }
// // Case 2: 如果错误是 RemoteCertificateChainErrors,
// // 这通常意味着证书链有问题,比如找不到吊销列表或者根证书不受信任。
// // 我们将尝试进行一次忽略吊销检查的自定义验证。
// if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
// {
// // 创建一个新的证书链对象
// X509Chain customChain = new X509Chain();
// 设置自定义验证策略
customChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // <-- 核心:不检查证书吊销
customChain.ChainPolicy.VerificationFlags =
X509VerificationFlags.AllowUnknownCertificateAuthority; // 可选:如果你的服务器是自签名证书,需要加上这句。如果服务器证书是由受信任的公共CA颁发的,可以去掉这句。
// // 设置自定义验证策略
// customChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // <-- 核心:不检查证书吊销
// customChain.ChainPolicy.VerificationFlags =
// X509VerificationFlags.AllowUnknownCertificateAuthority; // 可选:如果你的服务器是自签名证书,需要加上这句。如果服务器证书是由受信任的公共CA颁发的,可以去掉这句。
// 使用 X509Certificate2,因为它包含更完整的信息
X509Certificate2 cert2 = new X509Certificate2(certificate);
// 使用自定义策略进行验证
bool isChainValid = customChain.Build(cert2);
// 如果自定义验证构建成功,说明在忽略吊销检查的前提下,证书是可信的
if (isChainValid)
{
return true;
}
}
// // 使用 X509Certificate2,因为它包含更完整的信息
// X509Certificate2 cert2 = new X509Certificate2(certificate);
// // 使用自定义策略进行验证
// bool isChainValid = customChain.Build(cert2);
// // 如果自定义验证构建成功,说明在忽略吊销检查的前提下,证书是可信的
// if (isChainValid)
// {
// return true;
// }
// }
// Case 3: 对于其他错误(如名称不匹配 RemoteCertificateNameMismatch)或自定义验证失败,
// 我们认为证书无效。
Debug.LogErrorFormat("证书验证失败. SslPolicyErrors: {0}", sslPolicyErrors);
return false;
// // Case 3: 对于其他错误(如名称不匹配 RemoteCertificateNameMismatch)或自定义验证失败,
// // 我们认为证书无效。
// Debug.LogErrorFormat("证书验证失败. SslPolicyErrors: {0}", sslPolicyErrors);
// return false;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment