using System.Collections; using UnityEngine; using UnityEngine.UI; using System.Xml; using System.Globalization; using UnityEngine.Networking; using System.Text; using Random=UnityEngine.Random; using TMPro; [RequireComponent(typeof(Button))] public class Load_WEB : MonoBehaviour { public Text output; public XmlDocument xmlDoc = null; public void Webload() { GameObject.Find("HIDER").transform.Find("LOADpnl").gameObject.SetActive(false); GameObject OpenWebpnl=Get.o2("HIDER","OpenWebpnl");//GameObject.Find("HIDER").transform.Find("OpenWebpnl").gameObject.SetActive(true); OpenWebpnl.SetActive(true); Set.alpha(OpenWebpnl,true); } // Nettoie un nom de fichier avant de le coller dans une URL. Un InputField Unity laisse un espace // de largeur nulle (U+200B) dans son Text, et un nom collé peut transporter un BOM, une espace // insécable ou un retour de ligne : invisibles, mais ils passent le test IsNullOrEmpty et // produisent ensuite une URL — donc une requête — invalide. Les accents sont conservés. static string CleanFileName(string name) { if (string.IsNullOrEmpty(name)) return ""; StringBuilder sb = new StringBuilder(); foreach (char c in name) { if (char.IsControl(c)) continue; // \n, \r, \t... int u = c; if (u == 0x200B || u == 0x200C || u == 0x200D // largeur nulle || u == 0x200E || u == 0x200F // marques de sens || u == 0xFEFF || u == 0x00A0) continue; // BOM, espace insécable sb.Append(c); } return sb.ToString().Trim(); } public void OKWeb() { _G.FileName = CleanFileName(GameObject.Find("InputOpenName").transform.Find("Text").gameObject.GetComponent().text); GameObject.Find("HIDER").transform.Find("OpenWebpnl").GetComponent().alpha = 0; if (string.IsNullOrEmpty(_G.FileName)) { return; } string path = ThisOnly.geturlLoadweb() + _G.FileName + ".udt"+"?"+Random.value.ToString(); //StartCoroutine(LoadfromServer(path)); StaticCoroutine.Start(LoadfromServer(path)); } static IEnumerator LoadfromServer(string url) { UnityWebRequest.ClearCookieCache(); UnityWebRequest webRequest = UnityWebRequest.Get(url); // Anti-cache. AVANT : SetRequestHeader("If-Modified-Since", url) -> cet en-tête attend une DATE // HTTP, pas une URL ; il n'a donc jamais rien empêché de mettre en cache, et il levait // InvalidOperationException ("Header value contains invalid characters") dès que le nom de // fichier contenait un caractère non ASCII, ce qui tuait la coroutine avant l'envoi. // Le cache est déjà cassé par le "?{Random.value}" ajouté à l'URL ; ces deux en-têtes le disent // explicitement aux proxies et ne dépendent d'aucune donnée utilisateur. webRequest.SetRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate"); webRequest.SetRequestHeader("Pragma", "no-cache"); yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ConnectionError) { Debug.Log(webRequest.error); _M.PH(36, 230, "ffffff", 1, 1); LoadXML.openLoadPnl(); WaitCircle.Setting(false, TRANS.This("M_Download")); } else { //Debug.Log(webRequest.downloadHandler.text);// if (webRequest.downloadHandler.text.IndexOf("//IETF//DTD HTML 2.0//EN") == -1) { string load = Encoding.UTF8.GetString(webRequest.downloadHandler.data); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(load); //Invoke(nameof(LoadFile), 2); GameObject.Find("HIDER").transform.Find("LOADpnl").GetComponent().alpha = 0; WaitCircle.Setting(true, TRANS.This("M_Download")); Get.o4("Canvas", "Panel_SCENE", "DASH", "FN").GetComponent().text = _G.FileName; UnityWebRequest.ClearCookieCache(); Autosaving.StartAuto(); yield return new WaitForSeconds(2); LoadFile(xmlDoc); } else { _M.PH(36, 230, "ffffff", 1, 1); LoadXML.openLoadPnl(); } } yield break; } public static void LoadFile(XmlDocument xmlDoc) { // Passer le nom du fichier ouvert pour que FlieCategory soit recalculé (sinon la catégorie // "ai" d'une session précédente persiste et relance AiProcess sur un fichier sauvegardé). LoadXML.SetGLOBAL(xmlDoc, _G.FileName); } public static void OpenFileMT(string url) { //https://ukitchenit.com/free/soft/?free //https://ukitchenit.com/free/soft/?free?mt_hb@test.ca if(url.Split("?mt_").Length>1){ _G.FileName=CleanFileName(url.Split("?mt_")[1]); Get.o2("Canvas", "PATH").GetComponent().text =_G.FileName; }//https://ukitchenit.com/free/?mt__hb@test.ca if (string.IsNullOrEmpty(_G.FileName) || _G.FileName=="FN" ) { return; } string path = ThisOnly.geturlLoadweb() +"mt_"+ _G.FileName + ".udt"+"?"+Random.value.ToString(); StaticCoroutine.Start(LoadfromServer(path)); } // Ouvre automatiquement le fichier sauvegardé par l'AI ({email}_savefromai) depuis le lien email. // URL : https://ukitchenit.com/3d?{PATH}?{email}_savefromai -> nom = dernier segment séparé par '?'. // Le fichier est dans {PATH}/cloud/ (sans préfixe), donc on charge comme une sauvegarde cloud normale. public static void OpenFileSaveFromAI(string url) { string[] parts = url.Split('?'); _G.FileName = CleanFileName(parts[parts.Length - 1].TrimEnd('/')); Get.o2("Canvas", "PATH").GetComponent().text = _G.FileName; if (string.IsNullOrEmpty(_G.FileName) || _G.FileName == "FN") return; string path = ThisOnly.geturlLoadweb() + _G.FileName + ".udt" + "?" + Random.value.ToString(); StaticCoroutine.Start(LoadfromServer(path)); } public static void OpenFileAI(string url) { //https://ukitchenit.com/free/soft/?free //https://ukitchenit.com/free/soft/?free?mt_hb@test.ca if(url.Split("?ai_").Length>1){ _G.FileName=CleanFileName(url.Split("?ai_")[1]); Get.o2("Canvas", "PATH").GetComponent().text =_G.FileName; }//https://ukitchenit.com/free/?mt__hb@test.ca if (string.IsNullOrEmpty(_G.FileName) || _G.FileName=="FN" ) { return; } string path = ThisOnly.geturlLoadweb() +"ai_"+ _G.FileName + ".udt"+"?"+Random.value.ToString(); StaticCoroutine.Start(LoadfromServer(path)); } }