forked from Facepunch/Rust.Community
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CommunityEntity.UI.ServerImage.cs
150 lines (124 loc) · 4.34 KB
/
CommunityEntity.UI.ServerImage.cs
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Facepunch.Extend;
using System.IO;
using MaskableGraphic = UnityEngine.UI.MaskableGraphic;
#if CLIENT
public partial class CommunityEntity
{
private static Dictionary<uint, List<UnityEngine.UI.MaskableGraphic>> requestingTextureImages = new Dictionary<uint, List<UnityEngine.UI.MaskableGraphic>>();
private static Dictionary<uint, CachedTexture> _textureCache = new Dictionary<uint, CachedTexture>();
private class CachedTexture
{
public Texture2D Texture;
public Sprite Sprite;
public void Destroy()
{
if ( Texture != null )
{
UnityEngine.Object.Destroy( Texture );
Texture = null;
}
if ( Sprite != null )
{
UnityEngine.Object.Destroy( Sprite );
Sprite = null;
}
}
}
[RPC_Client]
public void CL_ReceiveFilePng( BaseEntity.RPCMessage msg )
{
var textureID = msg.read.UInt32();
var bytes = msg.read.BytesWithSize();
if ( bytes == null ) return;
if ( FileStorage.client.Store( bytes, FileStorage.Type.png, net.ID ) != textureID )
{
Log( "Client/Server FileStorage CRC differs" );
}
var texture = StoreCachedTexture( textureID, bytes );
List<UnityEngine.UI.MaskableGraphic> components;
if ( requestingTextureImages.TryGetValue( textureID, out components ) )
{
requestingTextureImages.Remove( textureID );
foreach ( var c in components )
{
ApplyCachedTextureToImage( c, texture );
}
}
}
private static CachedTexture GetCachedTexture( uint textureId )
{
_textureCache.TryGetValue( textureId, out var texture );
return texture;
}
private CachedTexture StoreCachedTexture( uint textureId, byte[] bytes )
{
var texture = new CachedTexture()
{
Texture = new Texture2D( 1, 1, TextureFormat.RGBA32, false ),
};
texture.Texture.LoadImage( bytes );
// Check for duplicate textureId and unload old one ( dont think they will conflict but safety first)
if ( _textureCache.TryGetValue( textureId, out var oldTexture ) )
{
oldTexture.Destroy();
}
_textureCache[ textureId ] = texture;
return texture;
}
private void ApplyTextureToImage( UnityEngine.UI.MaskableGraphic component, uint textureID )
{
var texture = GetCachedTexture( textureID );
if ( texture == null )
{
var bytes = FileStorage.client.Get( textureID, FileStorage.Type.png, net.ID );
if ( bytes != null )
{
texture = StoreCachedTexture( textureID, bytes );
}
else
{
List<UnityEngine.UI.MaskableGraphic> components;
if ( !requestingTextureImages.TryGetValue( textureID, out components ) )
{
components = new List<UnityEngine.UI.MaskableGraphic>();
requestingTextureImages[ textureID ] = components;
RequestFileFromServer( textureID, FileStorage.Type.png, "CL_ReceiveFilePng" );
}
components.Add( component );
return;
}
}
ApplyCachedTextureToImage( component, texture );
}
private void ApplyCachedTextureToImage( UnityEngine.UI.MaskableGraphic component, CachedTexture texture )
{
var image = component as UnityEngine.UI.Image;
if ( image )
{
if ( texture.Sprite == null )
{
texture.Sprite = Sprite.Create( texture.Texture, new Rect( 0, 0, texture.Texture.width, texture.Texture.height ), new Vector2( 0.5f, 0.5f ) );
}
image.sprite = texture.Sprite;
return;
}
var rawImage = component as UnityEngine.UI.RawImage;
if ( rawImage )
{
rawImage.texture = texture.Texture;
}
}
private static void UnloadTextureCache()
{
foreach( var texture in _textureCache.Values )
{
texture.Destroy();
}
_textureCache.Clear();
}
}
#endif