Files
BlockSpace-v1.5.0b/Assets/Scripts/Assembly-CSharp/BlockSpace/Worlds/WorldBackendClient.cs
T
2026-06-01 17:19:55 +02:00

391 lines
9.1 KiB
C#

using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace BlockSpace.Worlds
{
public sealed class WorldBackendClient
{
[Serializable]
public sealed class ResolveWorldResponse
{
public bool ok;
public bool exists;
public string worldId;
public string name;
public string visibility;
public bool isCreator;
public string updatedAt;
public string error;
}
[Serializable]
public sealed class LobbyTargetResponse
{
public bool ok;
public string worldName;
public string worldId;
public string worldVersion;
public string roomName;
public string action;
public bool exists;
public int roomsSeen;
public string error;
}
[Serializable]
public sealed class VisitResponse
{
public bool ok;
public int visits;
public string error;
}
[Serializable]
public sealed class BroadcastReloadResponse
{
public bool ok;
public int targets;
public string error;
}
[Serializable]
public sealed class UploadGroupsResponse
{
public bool ok;
public bool saved;
public int bytes;
public string updatedAt;
public string error;
}
[Serializable]
private sealed class BroadcastReloadRequest
{
public string playerId;
public string worldName;
}
private readonly string baseUrl;
public WorldBackendClient(string baseUrl)
{
this.baseUrl = (baseUrl ?? string.Empty).Trim().TrimEnd('/');
}
public IEnumerator ResolveLobbyTarget(string worldName, int maxPlayers, Action<LobbyTargetResponse> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(new LobbyTargetResponse
{
ok = false,
error = "No base URL set."
});
yield break;
}
string text = (worldName ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text))
{
onDone?.Invoke(new LobbyTargetResponse
{
ok = false,
error = "World name is required."
});
yield break;
}
string uri = baseUrl + "/api/worlds/lobby-target?name=" + UnityWebRequest.EscapeURL(text) + "&maxPlayers=" + Mathf.Clamp(maxPlayers, 1, 255);
using UnityWebRequest request = UnityWebRequest.Get(uri);
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
LobbyTargetResponse lobbyTargetResponse = null;
if (request.result == UnityWebRequest.Result.Success)
{
try
{
lobbyTargetResponse = JsonUtility.FromJson<LobbyTargetResponse>(request.downloadHandler.text);
}
catch
{
}
}
if (lobbyTargetResponse == null)
{
lobbyTargetResponse = new LobbyTargetResponse
{
ok = false,
error = request.error
};
}
onDone?.Invoke(lobbyTargetResponse);
}
public IEnumerator ResolveWorld(string roomName, string playerId, Action<ResolveWorldResponse> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(new ResolveWorldResponse
{
ok = false,
exists = false,
error = "No base URL set."
});
yield break;
}
string text = (roomName ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text))
{
onDone?.Invoke(new ResolveWorldResponse
{
ok = false,
exists = false,
error = "Room name is required."
});
yield break;
}
string uri = baseUrl + "/api/worlds/resolve?name=" + UnityWebRequest.EscapeURL(text) + "&playerId=" + UnityWebRequest.EscapeURL(playerId ?? string.Empty);
using UnityWebRequest request = UnityWebRequest.Get(uri);
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
ResolveWorldResponse resolveWorldResponse = null;
if (request.result == UnityWebRequest.Result.Success)
{
try
{
resolveWorldResponse = JsonUtility.FromJson<ResolveWorldResponse>(request.downloadHandler.text);
}
catch
{
}
}
if (resolveWorldResponse == null)
{
resolveWorldResponse = new ResolveWorldResponse
{
ok = false,
exists = false,
error = request.error
};
}
onDone?.Invoke(resolveWorldResponse);
}
public IEnumerator DownloadGroups(string worldId, Action<byte[]> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(Array.Empty<byte>());
yield break;
}
string text = (worldId ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text))
{
onDone?.Invoke(Array.Empty<byte>());
yield break;
}
string uri = baseUrl + "/api/worlds/" + UnityWebRequest.EscapeURL(text) + "/groups";
using UnityWebRequest request = UnityWebRequest.Get(uri);
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
onDone?.Invoke(Array.Empty<byte>());
yield break;
}
onDone?.Invoke(request.downloadHandler.data ?? Array.Empty<byte>());
}
public IEnumerator UploadGroups(string worldId, byte[] gzipBytes, string playerId, Action<UploadGroupsResponse> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(new UploadGroupsResponse
{
ok = false,
saved = false,
bytes = 0,
error = "No base URL set."
});
yield break;
}
string text = (worldId ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text))
{
onDone?.Invoke(new UploadGroupsResponse
{
ok = false,
saved = false,
bytes = 0,
error = "worldId is required."
});
yield break;
}
string text2 = (playerId ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text2))
{
onDone?.Invoke(new UploadGroupsResponse
{
ok = false,
saved = false,
bytes = 0,
error = "playerId is required."
});
yield break;
}
string url = baseUrl + "/api/worlds/" + UnityWebRequest.EscapeURL(text) + "/groups?playerId=" + UnityWebRequest.EscapeURL(text2);
byte[] data = gzipBytes ?? Array.Empty<byte>();
using UnityWebRequest request = new UnityWebRequest(url, "PUT");
request.uploadHandler = new UploadHandlerRaw(data);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/octet-stream");
yield return request.SendWebRequest();
UploadGroupsResponse uploadGroupsResponse = null;
if (request.result == UnityWebRequest.Result.Success)
{
try
{
uploadGroupsResponse = JsonUtility.FromJson<UploadGroupsResponse>(request.downloadHandler.text);
}
catch
{
}
}
if (uploadGroupsResponse == null)
{
uploadGroupsResponse = new UploadGroupsResponse
{
ok = false,
saved = false,
bytes = 0,
error = request.error
};
}
onDone?.Invoke(uploadGroupsResponse);
}
public IEnumerator IncrementVisit(string worldId, Action<VisitResponse> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(new VisitResponse
{
ok = false,
visits = 0,
error = "No base URL set."
});
yield break;
}
string text = (worldId ?? string.Empty).Trim();
if (string.IsNullOrEmpty(text))
{
onDone?.Invoke(new VisitResponse
{
ok = false,
visits = 0,
error = "worldId is required."
});
yield break;
}
string url = baseUrl + "/api/worlds/" + UnityWebRequest.EscapeURL(text) + "/visit";
using UnityWebRequest request = new UnityWebRequest(url, "POST");
request.uploadHandler = new UploadHandlerRaw(Array.Empty<byte>());
request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
VisitResponse visitResponse = null;
if (request.result == UnityWebRequest.Result.Success)
{
try
{
visitResponse = JsonUtility.FromJson<VisitResponse>(request.downloadHandler.text);
}
catch
{
}
}
if (visitResponse == null)
{
visitResponse = new VisitResponse
{
ok = false,
visits = 0,
error = request.error
};
}
onDone?.Invoke(visitResponse);
}
public IEnumerator BroadcastReload(string playerId, string worldName, Action<BroadcastReloadResponse> onDone)
{
if (string.IsNullOrEmpty(baseUrl))
{
onDone?.Invoke(new BroadcastReloadResponse
{
ok = false,
targets = 0,
error = "No base URL set."
});
yield break;
}
string url = baseUrl + "/api/worlds/broadcast-reload";
string s = JsonUtility.ToJson(new BroadcastReloadRequest
{
playerId = (playerId ?? ""),
worldName = (worldName ?? "")
});
using UnityWebRequest request = new UnityWebRequest(url, "POST");
byte[] bytes = Encoding.UTF8.GetBytes(s);
request.uploadHandler = new UploadHandlerRaw(bytes);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
BroadcastReloadResponse broadcastReloadResponse = null;
if (request.result == UnityWebRequest.Result.Success)
{
try
{
broadcastReloadResponse = JsonUtility.FromJson<BroadcastReloadResponse>(request.downloadHandler.text);
}
catch
{
}
}
if (broadcastReloadResponse == null)
{
broadcastReloadResponse = new BroadcastReloadResponse
{
ok = false,
targets = 0,
error = request.error
};
}
onDone?.Invoke(broadcastReloadResponse);
}
}
}