|
5 | 5 | using Robust.Shared.ContentPack; |
6 | 6 | using Robust.Shared.Network; |
7 | 7 | using Robust.Shared.Utility; |
| 8 | +using System.Linq; |
| 9 | +using SpaceWizards.Sodium; |
8 | 10 |
|
9 | 11 | namespace OpenDreamClient.Resources; |
10 | 12 |
|
@@ -69,21 +71,32 @@ private void EnsureCacheDirectory() { |
69 | 71 | } |
70 | 72 |
|
71 | 73 | private void RxBrowseResource(MsgBrowseResource message) { |
72 | | - _sawmill.Debug($"Received cache check for {message.Filename}"); |
| 74 | + _sawmill.Debug($"Received cache check for {message.Filename} hash: {BitConverter.ToString(message.DataHash)}"); |
73 | 75 | EnsureCacheDirectory(); |
74 | | - if(_resourceManager.UserData.Exists(GetCacheFilePath(message.Filename))){ //TODO CHECK HASH |
| 76 | + if(_resourceManager.UserData.Exists(GetCacheFilePath(message.Filename)) && GetFileHash(GetCacheFilePath(message.Filename)).SequenceEqual(message.DataHash)){ |
75 | 77 | _sawmill.Debug($"Cache hit for {message.Filename}"); |
76 | 78 | } else { |
77 | 79 | if(_activeBrowseRscRequests.Contains(message.Filename)) //we've already requested it, don't need to do it again |
78 | 80 | return; |
79 | | - _sawmill.Debug($"Cache miss for {message.Filename}, requesting from server."); |
| 81 | + if (_resourceManager.UserData.Exists(GetCacheFilePath(message.Filename))) { |
| 82 | + _sawmill.Debug($"Cache hit for {message.Filename} but hashes did not match (hash: {BitConverter.ToString(GetFileHash(GetCacheFilePath(message.Filename)))}). Re-requesting!"); |
| 83 | + _resourceManager.UserData.Delete(GetCacheFilePath(message.Filename)); |
| 84 | + } else |
| 85 | + _sawmill.Debug($"Cache miss for {message.Filename}, requesting from server."); |
80 | 86 | _activeBrowseRscRequests.Add(message.Filename); |
81 | 87 | _netManager.ServerChannel?.SendMessage(new MsgBrowseResourceRequest(){ Filename = message.Filename}); |
82 | 88 | } |
83 | 89 | } |
84 | 90 |
|
| 91 | + private byte[] GetFileHash(ResPath path) { |
| 92 | + var stream = _resourceManager.UserData.OpenRead(path); |
| 93 | + Span<byte> filebytes = new(new byte[stream.Length]); |
| 94 | + stream.ReadToEnd(filebytes); |
| 95 | + return CryptoGenericHashBlake2B.Hash(32, filebytes, ReadOnlySpan<byte>.Empty); |
| 96 | + } |
| 97 | + |
85 | 98 | private void RxBrowseResourceResponse(MsgBrowseResourceResponse message) { |
86 | | - if(_activeBrowseRscRequests.Contains(message.Filename)) { |
| 99 | + if (_activeBrowseRscRequests.Contains(message.Filename)) { |
87 | 100 | _activeBrowseRscRequests.Remove(message.Filename); |
88 | 101 | EnsureCacheDirectory(); |
89 | 102 | CreateCacheFile(message.Filename, message.Data); |
@@ -227,7 +240,7 @@ public bool EnsureCacheFile(string filename, int timeoutSeconds = 5) { |
227 | 240 |
|
228 | 241 | return _resourceManager.UserData.Exists(actualPath); |
229 | 242 | } else { |
230 | | - _sawmill.Error("Cache was ensured for a file that does not exist in cache and is not requested. Probably somebody called browse() without browse_rsc() first."); |
| 243 | + _sawmill.Error($"Cache was ensured for a file ({filename}) that does not exist in cache and is not requested. Probably somebody called browse() without browse_rsc() first."); |
231 | 244 | return false; |
232 | 245 | } |
233 | 246 | } |
|
0 commit comments