391 lines
9.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|