mirror of
https://git.aaro.dev/VRCBoard/vrcboard-udon.git
synced 2026-03-17 02:49:46 +00:00
Add new meta files and initial implementations for VRCBoard components and materials
This commit is contained in:
662
VRCBoardManager.cs
Normal file
662
VRCBoardManager.cs
Normal file
@@ -0,0 +1,662 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using VRC.SDK3.Data;
|
||||
using VRC.SDK3.Image;
|
||||
using VRC.SDK3.StringLoading;
|
||||
using VRC.SDKBase;
|
||||
using VRC.Udon.Common.Interfaces;
|
||||
using VRCBoard;
|
||||
using VRCBoard.Components;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace VRCBoard
|
||||
{
|
||||
|
||||
public enum IDType
|
||||
{
|
||||
Tier,
|
||||
Tag,
|
||||
Image
|
||||
}
|
||||
public class VRCBoardManager : UdonSharpBehaviour
|
||||
{
|
||||
public string vrcBoardDomain = "mydomain.vrcboard.app";
|
||||
public float periodicUpdateInterval = 60f;
|
||||
public string VrcBoardBaseUrl => "https://" + vrcBoardDomain + "/";
|
||||
|
||||
public VRCBoardBaseComponent[] vrcBoardComponents;
|
||||
|
||||
public VRCUrl[] atlasUrls;
|
||||
private VRCImageDownloader[] _imageDownloaders;
|
||||
private Texture2D[] _downloadedAtlasTextures;
|
||||
private float[] _atlasDownloadTimes;
|
||||
|
||||
public VRCUrl[] customModuleUrls;
|
||||
|
||||
public VRCUrl atlasInfoUrl;
|
||||
private DataDictionary _atlasInfo;
|
||||
|
||||
public VRCUrl supporterInfoUrl;
|
||||
private DataDictionary _supporterInfo;
|
||||
private DataDictionary _supporterInfoVrcLookup;
|
||||
private DataList _supporterList;
|
||||
private DataList _perkNodes;
|
||||
|
||||
|
||||
[UdonSynced, FieldChangeCallback(nameof(instanceOwnerOverride))]
|
||||
private string _instanceOwnerOverride = "";
|
||||
|
||||
public string instanceOwnerOverride
|
||||
{
|
||||
get => _instanceOwnerOverride;
|
||||
set
|
||||
{
|
||||
_instanceOwnerOverride = value;
|
||||
Networking.SetOwner(Networking.LocalPlayer, gameObject);
|
||||
RequestSerialization();
|
||||
Debug.Log("Instance owner override set to " + value);
|
||||
}
|
||||
}
|
||||
|
||||
[UdonSynced, FieldChangeCallback(nameof(instanceOwner))] private string _instanceOwner;
|
||||
public string[] imageIdDownloadQueue = new string[0];
|
||||
|
||||
public string instanceOwner
|
||||
{
|
||||
get {
|
||||
if (!string.IsNullOrWhiteSpace(instanceOwnerOverride)) return instanceOwnerOverride;
|
||||
return _instanceOwner;
|
||||
}
|
||||
set
|
||||
{
|
||||
_instanceOwner = value;
|
||||
Networking.SetOwner(Networking.LocalPlayer, gameObject);
|
||||
RequestSerialization();
|
||||
Debug.Log("Instance owner set to " + value);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveNullComponents()
|
||||
{
|
||||
int nullCount = 0;
|
||||
for (int i = 0; i < vrcBoardComponents.Length; i++)
|
||||
{
|
||||
if (vrcBoardComponents[i] == null)
|
||||
{
|
||||
nullCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nullCount == 0) return;
|
||||
VRCBoardBaseComponent[] newComponents = new VRCBoardBaseComponent[vrcBoardComponents.Length - nullCount];
|
||||
int newIndex = 0;
|
||||
for (int i = 0; i < vrcBoardComponents.Length; i++)
|
||||
{
|
||||
if (vrcBoardComponents[i] == null) continue;
|
||||
newComponents[newIndex] = vrcBoardComponents[i];
|
||||
newIndex++;
|
||||
}
|
||||
|
||||
vrcBoardComponents = newComponents;
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
int urlCount = atlasUrls.Length;
|
||||
_imageDownloaders = new VRCImageDownloader[urlCount];
|
||||
_downloadedAtlasTextures = new Texture2D[urlCount];
|
||||
_atlasDownloadTimes = new float[urlCount];
|
||||
for (int i = 0; i < atlasUrls.Length; i++)
|
||||
{
|
||||
_imageDownloaders[i] = new VRCImageDownloader();
|
||||
}
|
||||
|
||||
RemoveNullComponents();
|
||||
|
||||
foreach (var component in vrcBoardComponents)
|
||||
component._Register(this);
|
||||
_PeriodicUpdate();
|
||||
_TaskLoop();
|
||||
Debug.Log("VRCBoardManager started");
|
||||
}
|
||||
|
||||
public void _PeriodicUpdate()
|
||||
{
|
||||
//Debug.Log("Periodic update");
|
||||
if (Networking.LocalPlayer.isInstanceOwner) { instanceOwner = Networking.LocalPlayer.displayName; }
|
||||
_RequestAtlasInfoUpdate();
|
||||
_RequestSupporterInfoUpdate();
|
||||
SendCustomEventDelayedSeconds(nameof(_PeriodicUpdate), periodicUpdateInterval);
|
||||
}
|
||||
public void _TaskLoop()
|
||||
{
|
||||
//Debug.Log("Task loop");
|
||||
_TryUpdateAtlasInfo();
|
||||
_TryUpdateSupporterInfo();
|
||||
SendCustomEventDelayedSeconds(nameof(_TaskLoop), 1f);
|
||||
}
|
||||
|
||||
|
||||
private bool _shouldUpdateAtlasInfo = true;
|
||||
private bool _shouldUpdateSupporterInfo = true;
|
||||
private void _TryUpdateAtlasInfo()
|
||||
{
|
||||
if (!_shouldUpdateAtlasInfo) return;
|
||||
Debug.Log("Trying to update atlas info !");
|
||||
RequestUrlLoad(atlasInfoUrl);
|
||||
_shouldUpdateAtlasInfo = false;
|
||||
}
|
||||
private void _TryUpdateSupporterInfo()
|
||||
{
|
||||
if (!_shouldUpdateSupporterInfo) return;
|
||||
Debug.Log("Trying to update supporter info !");
|
||||
RequestUrlLoad(supporterInfoUrl);
|
||||
_shouldUpdateSupporterInfo = false;
|
||||
}
|
||||
|
||||
[PublicAPI] public void _RequestAtlasInfoUpdate()
|
||||
{
|
||||
_shouldUpdateAtlasInfo = true;
|
||||
}
|
||||
[PublicAPI] public void _RequestSupporterInfoUpdate()
|
||||
{
|
||||
_shouldUpdateSupporterInfo = true;
|
||||
}
|
||||
|
||||
|
||||
private VRCUrl[] _currentlyDownloadingUrls = new VRCUrl[0];
|
||||
private void RequestUrlLoad(VRCUrl url)
|
||||
{
|
||||
string urlStr = url.Get();
|
||||
for (int i = 0; i < _currentlyDownloadingUrls.Length; i++)
|
||||
{
|
||||
if (_currentlyDownloadingUrls[i].Get() == urlStr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VRCStringDownloader.LoadUrl(url, (IUdonEventReceiver)this);
|
||||
VRCUrl[] newUrls = new VRCUrl[_currentlyDownloadingUrls.Length + 1];
|
||||
for (int i = 0; i < _currentlyDownloadingUrls.Length; i++)
|
||||
{
|
||||
newUrls[i] = _currentlyDownloadingUrls[i];
|
||||
}
|
||||
newUrls[_currentlyDownloadingUrls.Length] = url;
|
||||
_currentlyDownloadingUrls = newUrls;
|
||||
}
|
||||
|
||||
|
||||
public override void OnStringLoadSuccess(IVRCStringDownload download)
|
||||
{
|
||||
string url = download.Url.Get();
|
||||
|
||||
VRCUrl[] newUrls = new VRCUrl[_currentlyDownloadingUrls.Length - 1];
|
||||
int newIndex = 0;
|
||||
for (int i = 0; i < _currentlyDownloadingUrls.Length; i++)
|
||||
{
|
||||
if (_currentlyDownloadingUrls[i].Get() == url)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newUrls[newIndex] = _currentlyDownloadingUrls[i];
|
||||
newIndex++;
|
||||
}
|
||||
_currentlyDownloadingUrls = newUrls;
|
||||
|
||||
//Debug.Log("String load success " + url);
|
||||
if (url == atlasInfoUrl.Get())
|
||||
{
|
||||
OnAtlasInfoDownload(download.Result);
|
||||
} else if (url == supporterInfoUrl.Get())
|
||||
{
|
||||
OnSupporterInfoDownload(download.Result);
|
||||
}
|
||||
}
|
||||
public override void OnStringLoadError(IVRCStringDownload result)
|
||||
{
|
||||
base.OnStringLoadError(result);
|
||||
Debug.LogWarning(result.Url.Get() + " : " + result.Error.ToString());
|
||||
}
|
||||
public DataDictionary _GetImageIdInfo(string imageId)
|
||||
{
|
||||
if (_atlasInfo == null) return null;
|
||||
if (!_atlasInfo.ContainsKey(imageId)) return null;
|
||||
DataToken token = _atlasInfo[imageId];
|
||||
if (token.TokenType != TokenType.DataDictionary) return null;
|
||||
return token.DataDictionary;
|
||||
}
|
||||
public bool _GetImageAtlasTexture(string imageId, string uploader, out int atlasIndex, out Texture2D texture, out int position, out int size, out string type)
|
||||
{
|
||||
texture = null;
|
||||
position = -1;
|
||||
size = -1;
|
||||
atlasIndex = -1;
|
||||
type = null;
|
||||
DataDictionary imageInfo = _GetImageIdInfo(imageId);
|
||||
if (imageInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool imageTypeSuccess = imageInfo.TryGetValue("type", out DataToken typeToken);
|
||||
bool uploadsSuccess = imageInfo.TryGetValue("uploads", out DataToken uploadsToken);
|
||||
bool atlasSizeSuccess = imageInfo.TryGetValue("size", out DataToken sizeToken);
|
||||
//Debug.Log("Get image atlas texture " + imageId + " success: " + imageTypeSuccess + " " + uploadsSuccess + " " + atlasSizeSuccess);
|
||||
if ((!imageTypeSuccess || !uploadsSuccess || !atlasSizeSuccess) ||
|
||||
(typeToken.TokenType != TokenType.String || uploadsToken.TokenType != TokenType.DataList || sizeToken.TokenType != TokenType.Double))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
type = typeToken.String;
|
||||
size = (int)sizeToken.Double;
|
||||
|
||||
bool isGlobal = type == "global";
|
||||
|
||||
DataList uploads = uploadsToken.DataList;
|
||||
int uploadCount = uploads.Count;
|
||||
if (uploadCount == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// find index of the uploader
|
||||
int uploaderIndex = 0;
|
||||
if (!isGlobal)
|
||||
{
|
||||
uploaderIndex = -1;
|
||||
if (uploader == null) return false;
|
||||
for (int i = 0; i < uploadCount; i++)
|
||||
{
|
||||
DataDictionary upload = uploads[i].DataDictionary;
|
||||
if (upload == null) continue;
|
||||
bool uploaderSuccess = upload.TryGetValue("a", out DataToken uploaderToken);
|
||||
//Debug.Log("Uploader success: " + uploaderSuccess);
|
||||
if (!uploaderSuccess) continue;
|
||||
if (uploaderToken.TokenType != TokenType.String) continue;
|
||||
string uploadUploader = uploaderToken.String;
|
||||
//Debug.Log("Comparing uploader " + uploadUploader + " to " + uploader);
|
||||
if (uploadUploader == uploader)
|
||||
{
|
||||
//Debug.Log("Match");
|
||||
uploaderIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Debug.Log("Uploader index: " + uploaderIndex);
|
||||
if (uploaderIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DataDictionary uploadInfo = uploads[uploaderIndex].DataDictionary;
|
||||
if (uploadInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool atlasIndexSuccess = uploadInfo.TryGetValue("i", out DataToken atlasIndexToken);
|
||||
if (!atlasIndexSuccess || atlasIndexToken.TokenType != TokenType.Double)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
atlasIndex = (int)atlasIndexToken.Double;
|
||||
texture = _downloadedAtlasTextures[atlasIndex];
|
||||
bool positionSuccess = uploadInfo.TryGetValue("p", out DataToken positionToken);
|
||||
if (!positionSuccess || positionToken.TokenType != TokenType.Double)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
position = (int)positionToken.Double;
|
||||
return true;
|
||||
}
|
||||
public void _RequestImageLoad(string imageId, string uploader, VRCBoardBaseComponent component)
|
||||
{
|
||||
//Debug.Log("Requesting image load " + imageId);
|
||||
if (string.IsNullOrEmpty(imageId)) return;
|
||||
string combinedId = $"{imageId}:{uploader}";
|
||||
if (HasImageInQueue(combinedId)) return;
|
||||
AddImageToQueue(combinedId);
|
||||
}
|
||||
private void TryDownloadImageId(string combinedImageId)
|
||||
{
|
||||
string[] split = combinedImageId.Split(':');
|
||||
if (split.Length != 2) return;
|
||||
string imageId = split[0];
|
||||
string uploader = split[1];
|
||||
bool success = _GetImageAtlasTexture(imageId, uploader, out int atlasIndex, out Texture2D texture,
|
||||
out int position, out int size, out string type);
|
||||
//Debug.Log("Try download image " + combinedImageId + " success: " + success);
|
||||
if (!success) return;
|
||||
DownloadAtlas(atlasIndex);
|
||||
|
||||
}
|
||||
|
||||
private void OnSupporterInfoDownload(string data)
|
||||
{
|
||||
Debug.Log("Supporter info download success");
|
||||
if (VRCJson.TryDeserializeFromJson(data, out DataToken result))
|
||||
{
|
||||
if (result.TokenType != TokenType.DataDictionary) return;
|
||||
SetSupporterInfo(result.DataDictionary);
|
||||
OnSupporterInfoUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Failed to deserialize supporter info");
|
||||
}
|
||||
}
|
||||
private void SetSupporterInfo(DataDictionary value)
|
||||
{
|
||||
_supporterInfo = value;
|
||||
if (_supporterInfo == null) return;
|
||||
bool vrcsuccess = _supporterInfo.TryGetValue("vrclookup", out DataToken vrcToken);
|
||||
bool supporterSuccess = _supporterInfo.TryGetValue("supporters", out DataToken supporterToken);
|
||||
bool perkSuccess = _supporterInfo.TryGetValue("perkNodes", out DataToken perkToken);
|
||||
if (vrcsuccess && vrcToken.TokenType == TokenType.DataDictionary)
|
||||
{
|
||||
_supporterInfoVrcLookup = vrcToken.DataDictionary;
|
||||
}
|
||||
if (supporterSuccess && supporterToken.TokenType == TokenType.DataList)
|
||||
{
|
||||
_supporterList = supporterToken.DataList;
|
||||
}
|
||||
if (perkSuccess && perkToken.TokenType == TokenType.DataList)
|
||||
{
|
||||
_perkNodes = perkToken.DataList;
|
||||
}
|
||||
Debug.Log("Set supporter info "+vrcsuccess+" "+supporterSuccess+" "+perkSuccess);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public bool PlayerHasTag(VRCPlayerApi player, string tag)
|
||||
{
|
||||
return PlayerHasTag(player.displayName, tag);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public bool PlayerHasTag(string displayName, string tag)
|
||||
{
|
||||
DataDictionary supporterData = GetSupporterDataFromPlayer(displayName);
|
||||
if (supporterData == null) return false;
|
||||
bool perkNodesSuccess = supporterData.TryGetValue("pn", out DataToken perkNodesToken);
|
||||
if (!perkNodesSuccess || perkNodesToken.TokenType != TokenType.DataList) return false;
|
||||
DataList perkNodes = perkNodesToken.DataList;
|
||||
for (int i = 0; i < perkNodes.Count; i++)
|
||||
{
|
||||
DataToken perkNode = perkNodes[i];
|
||||
if (perkNode.TokenType != TokenType.String) continue;
|
||||
if (perkNode.String == tag) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public int SupporterCount => _supporterList.Count;
|
||||
[PublicAPI]
|
||||
public DataDictionary GetSupporterData(int index)
|
||||
{
|
||||
DataToken token = _supporterList[index];
|
||||
if (token.TokenType != TokenType.DataDictionary) return null;
|
||||
DataDictionary supporterData = token.DataDictionary;
|
||||
string perkNodesKey = "pn";
|
||||
bool perkNodesSuccess = supporterData.TryGetValue(perkNodesKey, out DataToken pnToken);
|
||||
if (!perkNodesSuccess || pnToken.TokenType != TokenType.DataList) return supporterData;
|
||||
DataList perkNodes = pnToken.DataList;
|
||||
for (int i = 0; i < perkNodes.Count; i++)
|
||||
{
|
||||
DataToken perkNodeToken = perkNodes[i];
|
||||
if (perkNodeToken.TokenType != TokenType.Double) continue;
|
||||
int perkIndex = (int)perkNodeToken.Double;
|
||||
if (perkIndex < 0 || perkIndex >= _perkNodes.Count) continue;
|
||||
DataToken perkNode = _perkNodes[perkIndex];
|
||||
if (perkNode.TokenType != TokenType.DataDictionary) continue;
|
||||
bool perkNameSuccess = perkNode.DataDictionary.TryGetValue("id", out DataToken perkNameToken);
|
||||
if (!perkNameSuccess || perkNameToken.TokenType != TokenType.String) continue;
|
||||
perkNodes[i] = perkNameToken;
|
||||
}
|
||||
supporterData[perkNodesKey] = perkNodes;
|
||||
return supporterData;
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public DataDictionary GetSupporterDataFromPlayer(string vrcName)
|
||||
{
|
||||
if (_supporterInfoVrcLookup == null) return null;
|
||||
if (!_supporterInfoVrcLookup.ContainsKey(vrcName)) return null;
|
||||
DataToken token = _supporterInfoVrcLookup[vrcName];
|
||||
if (token.TokenType != TokenType.Double) return null;
|
||||
int index = (int)token.Double;
|
||||
return GetSupporterData(index);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public DataDictionary GetSupporterDataFromPlayer(VRCPlayerApi player)
|
||||
{
|
||||
return GetSupporterDataFromPlayer(player.displayName);
|
||||
}
|
||||
|
||||
private void OnSupporterInfoUpdate()
|
||||
{
|
||||
Debug.Log("Supporter info updated");
|
||||
foreach (var component in vrcBoardComponents)
|
||||
component._OnSupporterDataUpdate();
|
||||
}
|
||||
|
||||
private void OnAtlasInfoDownload(string data)
|
||||
{
|
||||
//Debug.Log("Atlas info download success");
|
||||
if (VRCJson.TryDeserializeFromJson(data, out DataToken result))
|
||||
{
|
||||
if (result.TokenType != TokenType.DataDictionary) return;
|
||||
_atlasInfo = result.DataDictionary;
|
||||
OnAtlasInfoUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Failed to deserialize atlas info");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void OnAtlasInfoUpdate()
|
||||
{
|
||||
//Debug.Log("Atlas info updated");
|
||||
if (_atlasInfo == null) return;
|
||||
while (true)
|
||||
{
|
||||
string combinedImageId = GetNextImageInQueue();
|
||||
if (combinedImageId == null) break;
|
||||
TryDownloadImageId(combinedImageId);
|
||||
}
|
||||
|
||||
foreach (var component in vrcBoardComponents)
|
||||
component._OnImageInfoUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void DownloadAtlas(int index)
|
||||
{
|
||||
//Debug.Log("Downloading atlas " + index);
|
||||
if (index < 0 || index >= atlasUrls.Length) return;
|
||||
VRCUrl url = GetAtlasUrlFromIndex(index);
|
||||
VRCImageDownloader imageDownloader = _imageDownloaders[index];
|
||||
imageDownloader.Dispose();
|
||||
|
||||
if (url == null) return;
|
||||
TextureInfo textureInfo = new TextureInfo();
|
||||
textureInfo.FilterMode = FilterMode.Bilinear;
|
||||
textureInfo.WrapModeU = TextureWrapMode.Clamp;
|
||||
textureInfo.WrapModeV = TextureWrapMode.Clamp;
|
||||
textureInfo.WrapModeW = TextureWrapMode.Clamp;
|
||||
IVRCImageDownload download =
|
||||
imageDownloader.DownloadImage(url, null, (IUdonEventReceiver)this, textureInfo);
|
||||
}
|
||||
|
||||
public override void OnImageLoadSuccess(IVRCImageDownload result)
|
||||
{
|
||||
string url = result.Url.Get();
|
||||
Debug.Log("Image load success " + url);
|
||||
Texture2D texture = result.Result;
|
||||
int index = GetAtlasIndexFromUrl(url);
|
||||
if (index == -1) return;
|
||||
_downloadedAtlasTextures[index] = result.Result;
|
||||
_atlasDownloadTimes[index] = Time.time;
|
||||
Debug.Log("Downloaded atlas texture " + index);
|
||||
foreach (var component in vrcBoardComponents)
|
||||
component._OnImageLoaded(index);
|
||||
}
|
||||
|
||||
public override void OnImageLoadError(IVRCImageDownload result)
|
||||
{
|
||||
base.OnImageLoadError(result);
|
||||
Debug.LogWarning(result.Url.Get() + " : " + result.Error.ToString());
|
||||
}
|
||||
private int GetAtlasIndexFromUrl(string url)
|
||||
{
|
||||
for (int i = 0; i < atlasUrls.Length; i++)
|
||||
{
|
||||
if (atlasUrls[i].Get() == url) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
[PublicAPI] public VRCUrl GetAtlasUrlFromIndex(int index)
|
||||
{
|
||||
if (index < 0 || index >= atlasUrls.Length || atlasUrls[index] == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return atlasUrls[index];
|
||||
}
|
||||
|
||||
#region Queue Functions
|
||||
|
||||
private void AddImageToQueue(string imageId)
|
||||
{
|
||||
string[] newQueue = new string[imageIdDownloadQueue.Length + 1];
|
||||
for (int i = 0; i < imageIdDownloadQueue.Length; i++)
|
||||
{
|
||||
newQueue[i] = imageIdDownloadQueue[i];
|
||||
}
|
||||
|
||||
newQueue[imageIdDownloadQueue.Length] = imageId;
|
||||
imageIdDownloadQueue = newQueue;
|
||||
_RequestAtlasInfoUpdate();
|
||||
}
|
||||
|
||||
private bool HasImageInQueue(string imageId)
|
||||
{
|
||||
for (int i = 0; i < imageIdDownloadQueue.Length; i++)
|
||||
{
|
||||
if (imageIdDownloadQueue[i] == imageId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetNextImageInQueue()
|
||||
{
|
||||
if (imageIdDownloadQueue.Length == 0) return null;
|
||||
string imageId = imageIdDownloadQueue[0];
|
||||
string[] newQueue = new string[imageIdDownloadQueue.Length - 1];
|
||||
for (int i = 1; i < imageIdDownloadQueue.Length; i++)
|
||||
{
|
||||
newQueue[i - 1] = imageIdDownloadQueue[i];
|
||||
}
|
||||
|
||||
imageIdDownloadQueue = newQueue;
|
||||
return imageId;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR && !UDONSHARP_COMPILER
|
||||
namespace VRCBoard
|
||||
{
|
||||
[CustomEditor(typeof(VRCBoardManager))]
|
||||
public class VrcBoardManagerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//base.OnInspectorGUI();
|
||||
VRCBoardManager manager = target as VRCBoardManager;
|
||||
if (manager == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("This script is not attached to a VRCBoardManager object", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// draw a header
|
||||
EditorGUILayout.HelpBox("VRCBoard Manager", MessageType.Info);
|
||||
string domainInput = EditorGUILayout.TextField("Your VRCBoard Domain", manager.vrcBoardDomain);
|
||||
bool changed = domainInput != manager.vrcBoardDomain;
|
||||
if (changed)
|
||||
{
|
||||
domainInput = domainInput.Trim();
|
||||
domainInput = domainInput.Replace("http://", "");
|
||||
domainInput = domainInput.Replace("https://", "");
|
||||
domainInput = domainInput.Replace("/", "");
|
||||
manager.vrcBoardDomain = domainInput;
|
||||
|
||||
string baseUrl = manager.VrcBoardBaseUrl;
|
||||
// update the urls
|
||||
const int urlCount = 100;
|
||||
manager.atlasUrls = new VRCUrl[urlCount];
|
||||
for (int i = 0; i < urlCount; i++)
|
||||
{
|
||||
manager.atlasUrls[i] = new VRCUrl(baseUrl + "atlas/" + i);
|
||||
}
|
||||
|
||||
const string apiPath = "api/data/v1/";
|
||||
|
||||
manager.atlasInfoUrl = new VRCUrl(baseUrl + apiPath + "atlas");
|
||||
manager.supporterInfoUrl = new VRCUrl(baseUrl + apiPath + "supporters");
|
||||
EditorUtility.SetDirty(manager);
|
||||
}
|
||||
|
||||
|
||||
float selectedInterval = EditorGUILayout.FloatField("Periodic Update Interval", manager.periodicUpdateInterval);
|
||||
manager.periodicUpdateInterval = Mathf.Clamp(selectedInterval, 5f, 600f);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
SerializedProperty vrcBoardComponents = serializedObject.FindProperty("vrcBoardComponents");
|
||||
EditorGUILayout.PropertyField(vrcBoardComponents);
|
||||
|
||||
if (GUILayout.Button("Link all VRCBoard components"))
|
||||
{
|
||||
VRCBoardBaseComponent[] components = FindObjectsOfType<VRCBoardBaseComponent>();
|
||||
manager.vrcBoardComponents = components;
|
||||
// mark the object as dirty
|
||||
EditorUtility.SetDirty(manager);
|
||||
}
|
||||
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
//DrawDefaultInspector();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user