Add hot-update boot pipeline, UI bundles/atlas assets, and design docs.
Ignore AIClient/Library and AIClient/HybridCLRData permanently; include HybridCLR/YooAsset project setup and UI tooling. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace HotUpdate.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏服 HTTP 鉴权:POST /register、POST /login → {token,pid}
|
||||
/// </summary>
|
||||
public static class AuthApi
|
||||
{
|
||||
public const string DefaultHttpBase = "https://game.xworld.ren";
|
||||
|
||||
[Serializable]
|
||||
class AuthBody
|
||||
{
|
||||
public string username;
|
||||
public string password;
|
||||
}
|
||||
|
||||
public static IEnumerator Register(string httpBase, string username, string password, Action<AuthResponse, string> onDone)
|
||||
{
|
||||
yield return PostJson(httpBase, "/register", username, password, onDone);
|
||||
}
|
||||
|
||||
public static IEnumerator Login(string httpBase, string username, string password, Action<AuthResponse, string> onDone)
|
||||
{
|
||||
yield return PostJson(httpBase, "/login", username, password, onDone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 优先登录;失败则注册再登录(编辑器/游客自动账号)。
|
||||
/// </summary>
|
||||
public static IEnumerator EnsureAccount(string httpBase, string username, string password, Action<AuthResponse, string> onDone)
|
||||
{
|
||||
AuthResponse loginOk = null;
|
||||
string loginErr = null;
|
||||
yield return Login(httpBase, username, password, (r, e) => { loginOk = r; loginErr = e; });
|
||||
if (loginOk != null && !string.IsNullOrEmpty(loginOk.token))
|
||||
{
|
||||
onDone?.Invoke(loginOk, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
AuthResponse regOk = null;
|
||||
string regErr = null;
|
||||
yield return Register(httpBase, username, password, (r, e) => { regOk = r; regErr = e; });
|
||||
if (regOk != null && !string.IsNullOrEmpty(regOk.token))
|
||||
{
|
||||
onDone?.Invoke(regOk, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 注册失败(例如已存在)再登录一次
|
||||
AuthResponse login2 = null;
|
||||
string login2Err = null;
|
||||
yield return Login(httpBase, username, password, (r, e) => { login2 = r; login2Err = e; });
|
||||
if (login2 != null && !string.IsNullOrEmpty(login2.token))
|
||||
{
|
||||
onDone?.Invoke(login2, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
onDone?.Invoke(null, $"auth failed login={loginErr}|{login2Err} register={regErr}");
|
||||
}
|
||||
|
||||
static IEnumerator PostJson(string httpBase, string path, string username, string password, Action<AuthResponse, string> onDone)
|
||||
{
|
||||
var url = (httpBase ?? DefaultHttpBase).TrimEnd('/') + path;
|
||||
var body = JsonUtility.ToJson(new AuthBody { username = username, password = password });
|
||||
var bytes = Encoding.UTF8.GetBytes(body);
|
||||
|
||||
using (var req = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
|
||||
{
|
||||
req.uploadHandler = new UploadHandlerRaw(bytes);
|
||||
req.downloadHandler = new DownloadHandlerBuffer();
|
||||
req.SetRequestHeader("Content-Type", "application/json");
|
||||
req.timeout = 15;
|
||||
yield return req.SendWebRequest();
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
bool failed = req.result != UnityWebRequest.Result.Success;
|
||||
#else
|
||||
bool failed = req.isNetworkError || req.isHttpError;
|
||||
#endif
|
||||
var text = req.downloadHandler?.text;
|
||||
if (failed)
|
||||
{
|
||||
string err = req.error;
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
try
|
||||
{
|
||||
var ae = JsonUtility.FromJson<AuthError>(text);
|
||||
if (!string.IsNullOrEmpty(ae?.error))
|
||||
err = ae.error;
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
}
|
||||
onDone?.Invoke(null, $"{(int)req.responseCode} {err}");
|
||||
yield break;
|
||||
}
|
||||
|
||||
AuthResponse resp = null;
|
||||
try { resp = JsonUtility.FromJson<AuthResponse>(text); }
|
||||
catch (Exception e)
|
||||
{
|
||||
onDone?.Invoke(null, $"parse auth: {e.Message}");
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (resp == null || string.IsNullOrEmpty(resp.token))
|
||||
{
|
||||
onDone?.Invoke(null, "auth response missing token");
|
||||
yield break;
|
||||
}
|
||||
|
||||
onDone?.Invoke(resp, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user