-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRawActiveEntity.cs
More file actions
125 lines (116 loc) · 4.76 KB
/
Copy pathRawActiveEntity.cs
File metadata and controls
125 lines (116 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using System;
using System.Linq;
namespace Data
{
/// <summary>
/// Used when decoding base64 entities from the Builder.
/// Has a different shape than ActiveEntity (e.g. contents is {key, url} objects instead of strings).
/// </summary>
[Serializable]
public class RawActiveEntity
{
public string id;
public Data data;
public string thumbnail;
public Translation[] i18n;
public Data emoteDataADR74;
// JsonUtility does not support null for custom classes, so we check category
public bool IsEmote => string.IsNullOrEmpty(data.category);
[Serializable]
public class Data
{
public string category;
public Representation[] representations;
public string[] hides = Array.Empty<string>();
public string[] replaces = Array.Empty<string>();
public string[] removesDefaultHiding = Array.Empty<string>();
public bool loop; // For emotes only
}
[Serializable]
public class Representation
{
public string[] bodyShapes;
public string mainFile;
public Contents[] contents;
public string[] overrideHides = Array.Empty<string>();
public string[] overrideReplaces = Array.Empty<string>();
[Serializable]
public class Contents
{
public string key;
public string url;
}
}
[Serializable]
public class Translation
{
public string code;
public string text;
}
static string ExtractHashFromUrl(string url)
{
if (string.IsNullOrEmpty(url)) return null;
var trimmed = url.TrimEnd('/');
var slash = trimmed.LastIndexOf('/');
return slash >= 0 && slash + 1 < trimmed.Length ? trimmed[(slash + 1)..] : null;
}
public ActiveEntity ToActiveEntity()
{
var reps = IsEmote ? emoteDataADR74.representations : data.representations;
return new ActiveEntity
{
pointers = new[] { id },
type = IsEmote ? "emote" : "wearable",
content = reps
.SelectMany(r => r.contents
.Select(c => new ActiveEntity.Content
{
file = c.key,
url = c.url,
// Spring-bone metadata keys models by content hash (CID). The CID is the
// last path segment of the builder-api URL — extract it so the lookup works.
hash = ExtractHashFromUrl(c.url),
}))
.GroupBy(c => c.file)
.Select(g => g.First())
.ToArray(),
metadata = new ActiveEntity.Metadata
{
id = id,
thumbnail = thumbnail,
data = IsEmote
? new ActiveEntity.Metadata.Data()
: new ActiveEntity.Metadata.Data
{
category = data.category,
hides = data.hides,
replaces = data.replaces,
removesDefaultHiding = data.removesDefaultHiding,
representations = data.representations.Select(r => new ActiveEntity.Metadata.Representation
{
bodyShapes = r.bodyShapes,
mainFile = r.mainFile,
overrideHides = r.overrideHides,
overrideReplaces = r.overrideReplaces,
contents = r.contents.Select(c => c.key).ToArray()
}).ToArray()
},
emoteDataADR74 = !IsEmote
? new ActiveEntity.Metadata.Data()
: new ActiveEntity.Metadata.Data
{
category = emoteDataADR74.category,
loop = emoteDataADR74.loop,
representations = emoteDataADR74.representations.Select(r =>
new ActiveEntity.Metadata.Representation
{
bodyShapes = r.bodyShapes,
mainFile = r.mainFile,
contents = r.contents.Select(c => c.key).ToArray()
}).ToArray()
}
}
};
}
}
}