From 81ca92fe403c11d3100d03459e9fd80b4f9951cb Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 19 Aug 2026 00:56:37 +0200 Subject: [PATCH] Keep CultCache readers on one committed generation --- .../DirectoryMessagePackBackingStore.cs | 133 ++++++++++-------- .../BackingStoreTests.cs | 97 +++++++++++++ .../Plugins/GameCult.Caching.MessagePack.dll | Bin 47104 -> 47616 bytes .../Plugins/GameCult.Caching.MessagePack.pdb | Bin 20852 -> 21032 bytes .../Runtime/Plugins/GameCult.Caching.dll | Bin 86016 -> 86016 bytes .../Runtime/Plugins/GameCult.Caching.pdb | Bin 30208 -> 30208 bytes .../Runtime/Plugins/GameCult.Logging.dll | Bin 6656 -> 6656 bytes .../Runtime/Plugins/GameCult.Logging.pdb | Bin 9544 -> 9544 bytes .../Plugins/GameCult.Mesh.Quic.Native.dll | Bin 15872 -> 15872 bytes .../Plugins/GameCult.Mesh.Quic.Native.pdb | Bin 12316 -> 12316 bytes .../Runtime/Plugins/GameCult.Mesh.dll | Bin 695296 -> 695296 bytes .../Runtime/Plugins/GameCult.Mesh.pdb | Bin 205548 -> 205548 bytes .../GameCult.Networking.WebSockets.dll | Bin 14848 -> 14848 bytes .../Runtime/Plugins/GameCult.Networking.dll | Bin 510976 -> 510976 bytes .../Runtime/Plugins/GameCult.Networking.pdb | Bin 246920 -> 246920 bytes unity/org.gamecult.cultlib/package.json | 2 +- 16 files changed, 174 insertions(+), 58 deletions(-) diff --git a/src/GameCult.Caching.MessagePack/DirectoryMessagePackBackingStore.cs b/src/GameCult.Caching.MessagePack/DirectoryMessagePackBackingStore.cs index 0c980c61..4f1a2521 100644 --- a/src/GameCult.Caching.MessagePack/DirectoryMessagePackBackingStore.cs +++ b/src/GameCult.Caching.MessagePack/DirectoryMessagePackBackingStore.cs @@ -21,6 +21,8 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore public const string BeforeRecordPageWriteStage = "before-record-page-write"; /// Fault-probe stage emitted after all pages exist and before manifest finality. public const string BeforeManifestCommitStage = "before-manifest-commit"; + /// Read-probe stage emitted while the selected manifest generation is leased. + public const string AfterManifestReadStage = "after-manifest-read"; private const string LegacyIndexedFormatVersion = "cultcache.store.v2.directory-indexed"; private const string LegacyMetadataPageFormatVersion = "cultcache.store.v3.directory-immutable-pages"; private const string IndexedFormatVersion = "cultcache.store.v4.directory-content-addressed-pages"; @@ -46,6 +48,9 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore /// Optional deterministic fault/progress hook for durability tests and host diagnostics. public Action? FlushStageProbe { get; set; } + /// Optional deterministic read hook for generation-consistency tests and host diagnostics. + public Action? ReadStageProbe { get; set; } + /// /// Creates a paged MessagePack backing store. /// @@ -86,46 +91,50 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore startupPhase.Restart(); } - _recordDirectory.Refresh(); - if (!File.Exists(_manifestFile.FullName) && !_recordDirectory.Exists) - { - SetLastSchemaMigrationReports(Array.Empty()); - IsDirty = false; - return; - } - - var manifest = ReadManifest(); - Trace($"manifest records={manifest.Records.Length}"); - _durableCatalog = manifest.SchemaCatalog; var reports = new List(); var loaded = new Dictionary(StringComparer.Ordinal); - var indexed = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal) || - string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal) || - string.Equals(manifest.FormatVersion, LegacyIndexedFormatVersion, StringComparison.Ordinal); - if (indexed) + using (AcquireCommitLease()) { - _manifestUsesImmutablePages = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal); - _manifestUsesMetadataPages = string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal); - _needsIndexUpgrade = !_manifestUsesImmutablePages; - _durableIndex = manifest.Records - .Where(record => !string.IsNullOrWhiteSpace(record.Key)) - .GroupBy(record => record.Key, StringComparer.Ordinal) - .ToDictionary(group => group.Key, group => group.Last(), StringComparer.Ordinal); + _recordDirectory.Refresh(); + if (!File.Exists(_manifestFile.FullName) && !_recordDirectory.Exists) + { + SetLastSchemaMigrationReports(Array.Empty()); + IsDirty = false; + return; + } - LoadIndexedRecords(manifest, loaded, reports); - Trace($"indexed-pages loaded={loaded.Count}"); - } - else - { - // V1 manifests have no page index. Hydrate once to discover the durable keys; - // the next flush replaces this compatibility path with the indexed manifest. - _needsIndexUpgrade = true; - var legacyRecords = LoadLegacyRecords(manifest, loaded, reports); - _durableIndex = legacyRecords - .Where(record => !string.IsNullOrWhiteSpace(record.Key)) - .GroupBy(record => record.Key, StringComparer.Ordinal) - .ToDictionary(group => group.Key, group => ToIndexRecord(group.Last()), StringComparer.Ordinal); - Trace($"legacy-pages loaded={loaded.Count}"); + var manifest = ReadManifest(); + ReadStageProbe?.Invoke(AfterManifestReadStage); + Trace($"manifest records={manifest.Records.Length}"); + _durableCatalog = manifest.SchemaCatalog; + var indexed = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal) || + string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal) || + string.Equals(manifest.FormatVersion, LegacyIndexedFormatVersion, StringComparison.Ordinal); + if (indexed) + { + _manifestUsesImmutablePages = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal); + _manifestUsesMetadataPages = string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal); + _needsIndexUpgrade = !_manifestUsesImmutablePages; + _durableIndex = manifest.Records + .Where(record => !string.IsNullOrWhiteSpace(record.Key)) + .GroupBy(record => record.Key, StringComparer.Ordinal) + .ToDictionary(group => group.Key, group => group.Last(), StringComparer.Ordinal); + + LoadIndexedRecords(manifest, loaded, reports); + Trace($"indexed-pages loaded={loaded.Count}"); + } + else + { + // V1 manifests have no page index. Hydrate once to discover the durable keys; + // the next flush replaces this compatibility path with the indexed manifest. + _needsIndexUpgrade = true; + var legacyRecords = LoadLegacyRecords(manifest, loaded, reports); + _durableIndex = legacyRecords + .Where(record => !string.IsNullOrWhiteSpace(record.Key)) + .GroupBy(record => record.Key, StringComparer.Ordinal) + .ToDictionary(group => group.Key, group => ToIndexRecord(group.Last()), StringComparer.Ordinal); + Trace($"legacy-pages loaded={loaded.Count}"); + } } foreach (var pair in loaded) @@ -175,30 +184,39 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore private void PullSelectedCore(Func selector) { if (selector == null) throw new ArgumentNullException(nameof(selector)); - var manifest = ReadManifest(); - if (!string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal) && - !string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal) && - !string.Equals(manifest.FormatVersion, LegacyIndexedFormatVersion, StringComparison.Ordinal)) + var fallbackToFullPull = false; + CultPersistedRecord[] selected = Array.Empty(); + var loaded = new Dictionary(StringComparer.Ordinal); + var reports = new List(); + using (AcquireCommitLease()) + { + var manifest = ReadManifest(); + ReadStageProbe?.Invoke(AfterManifestReadStage); + fallbackToFullPull = !string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal) && + !string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal) && + !string.Equals(manifest.FormatVersion, LegacyIndexedFormatVersion, StringComparison.Ordinal); + if (!fallbackToFullPull) + { + _manifestUsesImmutablePages = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal); + _manifestUsesMetadataPages = string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal); + _needsIndexUpgrade = !_manifestUsesImmutablePages; + _durableCatalog = manifest.SchemaCatalog; + _durableIndex = manifest.Records + .Where(record => !string.IsNullOrWhiteSpace(record.Key)) + .GroupBy(record => record.Key, StringComparer.Ordinal) + .ToDictionary(group => group.Key, group => group.Last(), StringComparer.Ordinal); + selected = manifest.Records + .Where(record => selector(ToMetadata(record))) + .OrderBy(record => record.Key, StringComparer.Ordinal) + .ToArray(); + LoadRecordPages(selected, manifest.SchemaCatalog, loaded, reports); + } + } + if (fallbackToFullPull) { PullAllCore(); return; } - - _manifestUsesImmutablePages = string.Equals(manifest.FormatVersion, IndexedFormatVersion, StringComparison.Ordinal); - _manifestUsesMetadataPages = string.Equals(manifest.FormatVersion, LegacyMetadataPageFormatVersion, StringComparison.Ordinal); - _needsIndexUpgrade = !_manifestUsesImmutablePages; - _durableCatalog = manifest.SchemaCatalog; - _durableIndex = manifest.Records - .Where(record => !string.IsNullOrWhiteSpace(record.Key)) - .GroupBy(record => record.Key, StringComparer.Ordinal) - .ToDictionary(group => group.Key, group => group.Last(), StringComparer.Ordinal); - var selected = manifest.Records - .Where(record => selector(ToMetadata(record))) - .OrderBy(record => record.Key, StringComparer.Ordinal) - .ToArray(); - var loaded = new Dictionary(StringComparer.Ordinal); - var reports = new List(); - LoadRecordPages(selected, manifest.SchemaCatalog, loaded, reports); PublishSelected(loaded, selected.Select(record => record.Key).ToHashSet(StringComparer.Ordinal)); SetLastSchemaMigrationReports(reports); IsDirty = !_dirtyKeys.IsEmpty || !_deletedKeys.IsEmpty; @@ -438,7 +456,7 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore ? MetadataRecordPath(metadata) : LegacyRecordPath(metadata.Key); if (!File.Exists(path)) - return; + throw new InvalidDataException($"Committed record page '{path}' is missing from the selected manifest generation."); var pagePayload = ReadAllBytesShared(path); if (_manifestUsesImmutablePages && !HashPayload(pagePayload).SequenceEqual(metadata.Payload)) @@ -788,6 +806,7 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore private FileStream AcquireCommitLease() { + Directory.CreateDirectory(_recordDirectory.FullName); var lockPath = Path.Combine(_recordDirectory.FullName, ".commit.lock"); var started = Stopwatch.StartNew(); while (true) diff --git a/tests/GameCult.Caching.Tests/BackingStoreTests.cs b/tests/GameCult.Caching.Tests/BackingStoreTests.cs index e43fa7b6..ee833f17 100644 --- a/tests/GameCult.Caching.Tests/BackingStoreTests.cs +++ b/tests/GameCult.Caching.Tests/BackingStoreTests.cs @@ -839,6 +839,103 @@ namespace GameCult.Caching.Tests } } + [Test] + public async Task DirectoryMessagePackBackingStore_ReaderLeasesManifestUntilEveryReferencedPageIsHydrated() + { + var filePath = Path.Combine(Path.GetTempPath(), $"cultlib-tests-{Guid.NewGuid():N}.cc"); + var recordsPath = DirectoryMessagePackBackingStore.DefaultRecordDirectoryPath(filePath); + try + { + var key = new CultRecordKey("record:reader-generation"); + var writerStore = new DirectoryMessagePackBackingStore(filePath, recordsPath); + var writerCache = new CultCache(); + writerCache.AddBackingStore(writerStore); + await writerCache.UpsertAsync( + new NamedTestEntry { Name = "generation", Value = "old" }, + new CultRecordHandle(key)); + writerStore.PushAll(); + + var readerStore = new DirectoryMessagePackBackingStore(filePath, recordsPath); + var readerCache = new CultCache(); + readerCache.AddBackingStore(readerStore); + using var manifestRead = new ManualResetEventSlim(); + using var releaseReader = new ManualResetEventSlim(); + readerStore.ReadStageProbe = stage => + { + if (!string.Equals(stage, DirectoryMessagePackBackingStore.AfterManifestReadStage, StringComparison.Ordinal)) + return; + manifestRead.Set(); + Assert.That(releaseReader.Wait(TimeSpan.FromSeconds(5)), Is.True); + }; + + var read = Task.Run(() => readerStore.PullAll()); + Assert.That(manifestRead.Wait(TimeSpan.FromSeconds(5)), Is.True); + await writerCache.UpsertAsync( + new NamedTestEntry { Name = "generation", Value = "new" }, + new CultRecordHandle(key)); + var write = Task.Run(() => writerStore.PushAll()); + Assert.That(write.Wait(TimeSpan.FromMilliseconds(100)), Is.False, + "writer must wait while a reader hydrates its selected manifest generation"); + + releaseReader.Set(); + await Task.WhenAll(read, write); + Assert.That(readerCache.Get(key)?.Value, Is.EqualTo("old")); + + using var reopened = await CultCacheMessagePack.OpenAsync( + filePath, + new CultCacheOpenOptions { UseDirectoryStore = true }); + Assert.That(reopened.Get(key)?.Value, Is.EqualTo("new")); + } + finally + { + if (File.Exists(filePath)) File.Delete(filePath); + if (Directory.Exists(recordsPath)) Directory.Delete(recordsPath, recursive: true); + } + } + + [Test] + public async Task DirectoryMessagePackBackingStore_ReleasesGenerationLeaseBeforePublishingObservers() + { + var filePath = Path.Combine(Path.GetTempPath(), $"cultlib-tests-{Guid.NewGuid():N}.cc"); + var recordsPath = DirectoryMessagePackBackingStore.DefaultRecordDirectoryPath(filePath); + try + { + var writerStore = new DirectoryMessagePackBackingStore(filePath, recordsPath); + var writerCache = new CultCache(); + writerCache.AddBackingStore(writerStore); + await writerCache.UpsertAsync(new NamedTestEntry { Name = "source", Value = "one" }); + writerStore.PushAll(); + + var readerStore = new DirectoryMessagePackBackingStore(filePath, recordsPath); + var readerCache = new CultCache(); + readerCache.AddBackingStore(readerStore); + var observerRan = false; + using var subscription = readerStore.EntryAdded.Subscribe(_ => + { + if (observerRan) + return; + observerRan = true; + readerCache.UpsertAsync(new NamedTestEntry { Name = "observer", Value = "two" }) + .GetAwaiter() + .GetResult(); + readerStore.PushAll(); + }); + + Assert.That(() => readerStore.PullAll(), Throws.Nothing); + Assert.That(observerRan, Is.True); + using var reopened = await CultCacheMessagePack.OpenAsync( + filePath, + new CultCacheOpenOptions { UseDirectoryStore = true }); + Assert.That(reopened.GetAll().Select(value => value.Name), + Is.EquivalentTo(new[] { "source", "observer" })); + } + finally + { + if (File.Exists(filePath)) File.Delete(filePath); + if (Directory.Exists(recordsPath)) Directory.Delete(recordsPath, recursive: true); + } + } + [Test] public async Task DirectoryMessagePackBackingStore_PullsOnlyExternalRecordDeltas() { diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll index b279cd097384209b114e381122167efe477e350e..1deb800477b19261d5e7ac968d3cda450b042687 100644 GIT binary patch delta 22197 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 delta 637 zcmV-@0)qX3>;Zu60g!wYsFi+q{&)3Cpxke0Ex z5=E#D;Q{e5UXSe&>m6%%Oyp1EH~2ENE<_0z$w=7;OWrwi&e7S?r0LOK&*4Fu!X zPevi98o#o5Kv%$;t%aPxN>Jc(!=^PoXmbEh8}UIBF4Mnw-gh*I2VG!S!F?Z;nv31v z;9Mp@iNgnq&hsL5?V{}Yg0{j4pdY0>pps-E*s>CvPie?{X_*-RdP9?jxPuDaMI zZj0-VEMcJkA!>WiRjpej-@m~vDZ+|e7~aQ-dnk$zk#rBQ(wq^q+R$!be-S>(a5gZ4X&fP2E diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll index be0edb36bdd2b942c5c65bce2fe6491e7effc4e5..bc67fc77ad5d50d767e73d7960b8ba01bd556024 100644 GIT binary patch delta 290 zcmZoLX)u}4!SZ}ha_7b#Ck{r_&F49OvIw|eh+2L5SCHe%S5`$cS_Kq0-{5Uvv@q5) zU|=v|WY9O%Gte_N)=o`Lv@kNUurN2bOffODG&Hs}PfRs1w@6J*GfhcMO)*I}OG&aw zPMJJ`{|?I{iwA9!3j_iL4n8z9(J5i`=<{WKemG7`bn*p(Mg^!KhaXfBsG4oNy5W}z zfo6v+%O`x^Tqr2Z$Z5*Jz`zK^rkke=9cE-S-W)Ab%@}OVpv{m9goz9m3`PtlK+=N2 z90)BLQh+=&AZ^HC3?$8gDpDB?fV2fzeHw!)Pz6W~q%Ik#GKC=tD3{ETGFem16li?B H*g|Fi-6c{a delta 290 zcmZoLX)u}4!IF06$gGV$P8^ITo6mFnWD%IcyqqOM=C%8@9EFzary_T6zQNnTXknyh zz`$U_$e?eiXP{?lq-~LCWMG_ZXl9z0YLS?fnrND6X_lB~l4xO`WME-oWNc}aoRpeo zWHEUH{~Z=L*=3t27YGCh82TH(__6V?`|fwIcW!<8vvBeSfkp+WAiFhG5UAStH+PBR zuB7a}OH(eM*jy+m%gAZMz`(!=#3q}k3ms-;G};_3Qq34_#GuV!!H~#c#9+W+%#h4r z$Y91`%8MelK2&l^vNG1bCQi1YD3>K3$ N#Y}<5$BQjw1^@=dS!n?ZB}_ z4tpPYT|KtwyB5WJ7k?vL9ABV;&Nl@B0IihIY8x>S#_xf=!{Ad(lU=8AVmk?i)Fq*i zK!{WKP6W~4kn-s?I%$aA>DR{XIc zM*)TOyY*pOPZfVhP+k)}V}xx06dfRl_clwR+wet&&QJvLASttCOHgA63foA)PWcc> z2^3V}H}(P0X?SL9p&+n63UIllNktoNju2=ozLtcm{4X`{+nU3JHnKCY?4nS8xx39C zskEeoy}L}IUob|h3)@}%8IWE7yj%FXLDyZ21TI>kSEGNL1XVy`HG2JZFvXQ@+LYy8 zkM&5FFw*~knl7-ZqzC!_0{0{cD{^t&ALZTV(uX)4{ehwi-27JIlIzA2G`2Mc3!9p5 zO!AbSP$*Fmls>?swQ|SBaJ3t@w4xAq)lRZ;c6OSLhjTu<(uaEOE82en-w@&K?PNBa zPUm`ZK0kjsollX*(-~2DrjhhSo$F$z^l;sW;B~9|ZMemnk`3A2#-ZV?Cl*V4A+7e{ zXqqLBf;(f{_{icz_bJ%X5sWI4CSK&ZVX4|8Q@+lB6`l7-Vg2%N`@c~7Bkq^)TeccL z2Nqg*O*a8eO-?{rj4?}jKL7y(fT(*SWN%}2ZDo^b2XiQ8WnnlnG&ndnH#uZ9HaRgf fIX7WtFgG}5Wo9*GVP#}AV>V=BIAdh91PDYO{TUXg delta 593 zcmV-X0$$b*`Ef=arn9k--2{JOx?7TpiFA*=)GNN{ z6z%fKJE$<4AfsYjsh*g8uIYz?&Nl@B0IihIYTPgo#_xf=!?358Huh%IO`Sg!(k%&v z1WGp99!d`*c`Ogel99#@ex$xepR8!NUA%1rF05{nW`5uB%}9BEwAXcbkmqoTo%ka| zjsgmm@79NDJ=A|3LHm;62_tL+K=pti-rFpNZo?NfIzth}gQU!gEkT1lXzU^ZJMBXt zEug5zZ|no0E8&T)1w~+e6yR!0lbSZ#93jwFd@Tu=`9Esjw>5_cU1Voq*+-$~Vt1R} zQ)NjDdv}pSzhI2iDBGX^9gto9x?A|BMb}@61Xi8Ui%EY&f;ynEp1k}zn&K)pUCQ!q zz`7?(80mjNZ6DawGJyQ}4tFF7D{^t&AMM@d(uX)6{ehwm-2PGFlAG2Nw6-$_l}$}I zCV9$EC{(BkDj#6cS-E93UhSGKttiA@wc~7>&1czkJm;gUd}!9bqJ0kds=(RwL?55d zD=JVC&hdZj6stE_yj9bpn4O%>w4!QOjMx1XeA($?8*Z?nWJ7klacDg2fyL5ZNUJ?K znr5j)!JRQ}ePr>We++i=8YZ0W@R{GVr5}9 fVL3KoW;9_qH)1e2I5IOiGGk(8W->Ul1PDYOxuhN5 diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll index 477716731b9682725ad61241d001cf31b06c6be3..96f9481b7cfcfe45c8b580726362f6404eedbaa0 100644 GIT binary patch delta 316 zcmZpuX{edd!Lr6*?ZU<$14%~H$$KSL8BI4omi#Fsuv9qvA?Nke4(*8t{&{YFQ?U7s z&LS2&V?6@~1`|dGeM3D1JyT=t)YL=^BNGb?b92iS6EjOgV@vbIR0DI1)YLT7l*H5& zlVr1$B#Yz}1_n7s2Fc0uOe8lyHGIyB$$20|ch|i#_(4Y~$HD=VDUEeXW+s z1}2jgpn@|GLIpvpHH=pHp6Z-%eG%KVJDVSytY+jiWnf@n1Y*<8)6Jxr7>ze?wph&= zY|Nm|kP3u}3>FMV3?@L*g25aJEg4dPJTo9|$Y2a4&4DUX84Q551z3F=gDFr2NDQPd j8K^RaAqgm#%#bp9qm?PEF@qk1!Dc}lF~-e|Hvbs`H#1>B delta 316 zcmZpuX{edd!SXrO=Ih2D14%}c$$KSL8BI1nmi#Fs;CREjiu3my?~V3vmxv_v-rD>| zXAz5?k)8nqg9#&pzM-Cho~e!g?W;Jg@uu^ zrBQNHYMPM+1A`nRgXH9SCX$<<8a`)aIl?r5)#MAt0Rlgj9wg-4zUHuAH~EyCXT|Kv z1}2jgpn?-%fwACVr8VQBwVNNCtY+jiVPIfj1Y(oT)6Jxr7>zb>wph&= zY{a0=V8M{cV8md+V9b!rV8~#`V9JojkO~$}0@8^X7UN8lJV}9^(PC)dDum36*UPbxatD74DG0}L#`bT++vAzN zXJ8C-kk8vj=Qk0(jz9x;OR(yJ_Id>X0IgKpYTG~%eGm8_20bODSvidp+es*-E(wLY zw7Iwsr4OUskufs0n?Fl&EEPzMy&+0nP1SzO6go2tCq z;JPPE80mkAmR;bgmJO00-(gOIupk%v{%G%3mp;VZsozo5ftTA353`Rb{7f*9pIg>2 zYpu*F)({A-aFZJD9BJ_ZN+00Kv2?u&FEs^lBvH^A3DU`zX*?saPoRInT*F%GrE|bo=wL{!|{ZuJU2*Y zq%TY{(PnquPr;j3Z}#mD8%lYq6sSt^s#Vy#lRmOo+Arl|4;iO%G$^<==}RA3eCVEn z&0axPi!9@1o>we&TPW?D{I~l&Jw9;J3--(7ZgU)wr8P5uc-yiy@FlR&%p1B5ST*DX zw8a=zs{09(8VY|XWo2PFGBh|iH#a$CG&VUgGdVY5WiU55Wo2eHWMO4wG-EboVmM=D zv%w0e0vNS%*qH#p0RT}jq8)Rxqe_$m#*!jT(RGu74J{ZKYfOm%fB*m##Pf4!=D0zz zY`V=K*2SumfejrVWNd5z00BbBs;B@U0RYhY5Olu2Q$vAEm5eCs*Z`9O4i^~bykm&~ zfB*nT&|0h0`cgru>N;|mg%BZ=Fb)(L#ym3H000XB!ReIawq8?1v{UlqXBcbOlUxoO l7)vsk`~W}*00kPrmpQ^EtatD7v0OVB!B1VuI4Sk?$ zJV_>Je?4ZC|BbyjCH2PrtC3KF_Id>X0IgKpYTG~%eK+_Y20bODSvgLfDi;c=OG2P7 zZ7%LZ>BDF>k_J}0W_OgJPwH><%gV~Fv1tn`cpn7Po;l~}%rI$syw@`xr72utEAF@= zOCE)axBbU>9&3LNpj|=mf&n%F$U8s~=ZuQb4SZgsttfyvkXTu=A!x7zjcp)ctDX0x z1#+tKnVko;1-!5^kP{de1i0L=Nlj~Q4&Z4c-b=z&`WMgpj%GY+1KSE7x**hC?!Kyf zDh+92XD=i4D~3Q#Zn}#<0qXkK-P|=RwB5Cc=e!jV^ z8C>wW^08VY|XIAJm{Gh;C}HD+ZvVPa)rHDNh6VP-U8I5%Q2I5;vhIWl8nWo9xs zv%w0e0vN8@hM)kz0RV{C#vIKwOGTR(lW)#k;scX`4J{Zs^kts_fB*o{+n5nVm8?mJ zVqX@?YgFQsfejrVWNd5z00GN61=|210RWD}XKW?++(nqfZj;KkHe-_k4i^|^)Wn(q zfB*oL1E&O79P3AxY#@Z!%2~UUFb)(L+B06m000XBXXy7{J*{;?xrBxe1(J2vlUxoO l7ToB%)w0LW1F4t6gULX-21co3Izhm!#h6tkiZdLj4AYR~`x diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll index 6d06333d04a1f77851a053138468757cde03b199..65f566e9d3683aff583d28438c5dc911cf8f16f2 100644 GIT binary patch delta 384 zcmZqJq1CWMYeEOhF&m@XjXkYBjIBLPtv$@GJuIy~tgSt4TYK1l)G?Y)Z>?wdmo;TT z0Hgf~HY1Q}I{jlkyELO|J8uI!5OZwjZQ$I_EO7AUl*ilRf}OVne|nrQk$rvpm1fR; z_biO{3>X+p7#Z{p^$he(jkQx#6D^EPEG*2;EmKU)EDen<%@b1%%q>z=(@awmQ&UWm z%~Fyql2f*yO5)PfW6AonX5sWd6Sx8dUaK9Dxu2}%ut47beD(WXYo^CcMHie6BF ziUQRuzRZ2I>>@w=>)qnaI@`Zb?wdmo;HP z0Hgf~HY1Q}GW}ycyELOoJ8uI!5OZwjZQ$I_ERg=qfrW*Uv87RR zQfiu!#r9K4TzYyecWi_AP5(22D?osG|C2m5jYRKlvx;vW=`@%#J!T?TwE|Q$y9_D{ zRBzY$rK!5xe@Srb>s!*>zfa_v&cq4w57_P7r%&M$W@0qjzIqy0GGnk2gEoT&Ln4C_ zg8_pvLo$OQgBgPn6Y)-(xC3pdU}qd+)leYW%FBfsnP30qtvlhe|5W7)19u zjQfp{-G)i7yF- z)FmNMLrGHiq4Z(2JCe4ncFoSHL7&v$=$DmMTw~J~RO)>YX!p!HXU`6kWv2&S!$Fq8 zH8$c;OL7!YNWbYe<9e!p41@BT;29aV0LWWF5btdop7mXPURh}LZ|WhFZ#Kfc3~1Yt#vyZ2Gvy&U?${i)v(t6$g^~mUYw_+{@1;Cg%5S-6Ybv!Pl#~(dOV#@CNn+0oSmJ|CP<^n zl&HASNP4U;bv{+PzwU?Nb)$CQZy< zyn>_>S@S&0N+VU1r^?saFUMK@yf=9#*bR%j-N6;d%JT6RZDXv4Pr(Q+yr$cLWlc^% zS!7OQ-A}iVZUHogC}m|~I5IRiI5#&rWHdH8F*7+gVP!BkIAvvKHDqCBWHe(oWMVjD zWVh?|0kr}cwQ<;)0KfqNQ81z%bF!mKlmo_+B23YBm;Ltv9hcSj0T37$YfOm%fB*m# z#Pf4!=D0zzY`V=K*2Suq{r3SQe?rHqr~n`V0MPmnbiTe*LxD?`j412a07qeMWkYpr zbS_M9XJ=_{XD(!HYybcO=e%Qy0Du4hN6=cU)A~|Dsp>j%n1v7_M`3McLv?I)E>2~1 zcW-iQX>MmOWNd5z00B!fnEU`h2ml2d)Gj7&u1lBqiY)j{Ww}XnZ*XsDhoATXx1aa| FO)5Qbg0=tv delta 827 zcmV-B1H}C7#SHAl43K;j1Ha^MCMaP`wwiO=#ECGR+&xpifsnP30qtvl@aUaTq&t_P8BB< zQkR564JAq4hth}9Y9wvhi`f}9=#%;z{j#!(Yi!zrO1%#P?VdU3?Ac+m?DU{(Jjyb- z##a1kO^yNzm9P8FxE>pS&7gcq@PrIo02Cb{i1#Lq&@Ft?psR^NJV>mpv>~wAfx?yv zv{OC=QUV1v_)Yr&=t_9f#y~+}JPYV*%O(vyYiou;Tk&2JuCqUQK6EtWQOnxZ@X)c4 zz1sgx@2N7RM093A$*7juK0Mf-0bBl^lN=%;G9t zx3S8*9j<#agiQZJwC;kg8`&ZG@g0^V2rF{jzmM|n`OpU*PW_fx1-;&Pc$6$!BTM3D z4yESJb_s#dh_(clxPcM{3uNlmS=-k17mY@k9JdUW4{(Q;7OhF(WIT%Pk_fDW|4K?Y zIUa2DRvTJT;Qb(f&(cXco2HZD*L~+IA8hXv&EE)5a-2@i)!D_Yq8tmt8D3ss^%C<} z#U#(C=a*AeP&Lhm>wXBnY}M}jZE}$`#yp(pQH!Dfr&%2!%h-Og2lhI9?OBTt-N#^( z7mzd}Yo2FWt)*#;RC$~Ia-7A_dtLN`{jj*(9b9p&EFaz$wAz&LDQKaEFX=X5ZOI8J zgUo5H`w6#?ZUHogC^%sV@F|aWkYpr zbS_M9XJ=_{XD(!HYybcOX4J%*0Du4hlmn*(SRCs|mTVw|*UDMDM`3McLv?I)E>2~1 zcW-iQX>MmOWNd5z00B7-X`BE+2mr`X^$vC~6+)BqjCc^2a)(KCZ*XsDhoATXx1aa| FO)3U$g^d6J diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll index 3b4141647f2625001e3f7284147352ff46905243..7cfbbf1329f9fc6a106ab8aff8cb25109f1391ed 100644 GIT binary patch delta 306 zcmZoDX(*Y{!4l0nZNtW%90^9#$v-7j8BI6KODggUY;bMg`A5~tb3%+oQ0D)oYc~gI z2(wxk>lrXGm@qQv8|oS8nHp=SrY2e#nOInun_H%sm{}ScTbd`P8kk$8rly&uB&MdA zB%7rqStO@yo~qo2MIbGcg)(UTkunG1!XH5Lz;%0C{FW+K|B*NSXsxq%s%)X$!FWGzL?k3Xm8`T{2K*3PTc5E}0=^ Z@=-HWR$~S|27}Fl7EFwr87=-Z0s!UmT$}&^ delta 306 zcmXYoF-yZx6ou~#tsn(Wafy_of`U*?UT$8}n@u+nECnasUP3bIR#(kfp@TG_gE;9b zRNgKs6cH@>0d*D~`~kY?Q_AI>%l*!|Stsk9c1y1}GyU7%zQsiTWvwuw7Uq{`&Go6; z_1SZ_*&Du(5AOz_s=Yc_CbT(#VBokmw|#7oMDE3I;HL@6D3QJl1DOg*&4?4B7h)VG zDU!Nas~V-{m~606wIU{L@Hpsc#9P=2CN^ouCPk?vozW bU!nF`lSJnTln(>Hj9>#-RWg`j^uvAu5T;q3 diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll index a6163a0a9f8604ad0c972867f36d0aab151753bc..40d4ec74585ecf0077d40ae478ebdbeed3720d96 100644 GIT binary patch delta 361 zcmZpeA>S}VenJO}x6zD0jXkYBjIBLPtv$?JdsvpeU^Ja>{F22LNL9XM(Fam1!BqRr zmn_?FzGSVh6=0RRqNkR(&U^azE}b7fsXMo4q_dgU*%|8@Fff=fGUyxX8R(fBYp13r zS{RvFSeTnzrkI#n8X8-gC#D*hTcoC@nWiMBrkEs~r6gG-r!X)`Ffs^FH{8uCy#3u% zwyp~-AAapWJ-ucddw_s2?~XMAY^U5dEh|f&7%c8K{mwS_b_JNI5mXeY-n*#nPc&1; zzapR1=X16#GG~Ql)jJ=&P*qA|^Ar%M{87vr#7)*eq z1%o*dS~8>nd1gS`kii&8ngdm&G8h193$Xe$22-F4kQhi^GEij-LlRIfnIUC*=m~aH XR$~S|27~Q_r`U@aw=Z3}fQVQZyU0e$JcuCq92M5JbD2TJXghX9C_<^mhNQp=WK_ne? z6Tv|c(Z0b=L`o+oq2QzlX3@dAs?So6yC3(v|5fXmYCUtXCs~QrFgaDp&m(d0-KSf2%LA}wGAqYCgVDULQc84-IJWB%3NVTw6>7J!6#sY|*ngCMCNA&7 zQUe!~pC{63rPG-|y0{vAc~axya|8S1JzGxq?0>$fEKRyojrG#(*frnfcqkD!004gg3;bkOy1jsVE}8EHNEn aTyZBr!^I{xV+3SS`A7>F5l1cji~azLj&X+o diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb index 5e79480f43ace503c5386c5c7996034e19403c3b..e1aa9f03792f573dfed8ec058fba2760cdd7a35a 100644 GIT binary patch delta 744 zcmVD%+i#5QXmpd56JQEsb}b#)*Ft z3aLv%p$R2U(~HuJS?$?fQLVH{voZTfeT_a@(WW(af4~9jLZH!^?+ha`X*%5NIy^{I zy5Lsau!MzYLH?!>#&utR=|IZmpcMyN3n=S|Nt`oDl&dbWWzXi$Vue*h-8@Ao0h}T&wcrmDdA*?)$R)d#ccc$1v zmu<{)c7t^X0}gl&sOh{eE7^ej_)a$vrU%&2zmIbE>C*YIJNg}h^1At>!bNN37BZ(L zRO@j>l`gAc17A2_vsIuPA#fSnTsTi9*9d8Vf5dalue8AfeAqTWPDaV;Niy1<^WOG# z#Tc9a0bc<;eLbFkPA8LDK0ccrpUftV(PRn~r#T}ZtFt_ts(g3fkKX02+I*F3t`VD; z+(K5)f77D2Qo~EUis?8GR>hyQr zY1}^OtT*h(!S&{7ii6{3`L@+2r_Wvs7B0t?=dy+sQiekWNMhbkhsHDkx5hLAor@@C zWnnlnG&ndnH#uZ9HaRgfIX7WtFgG}5Wo9*GVP#}AV>V=BIAdhDi@*Y^0vNS%*qH#p z0RT}jq8)Rxqe_$m#*!jT(RG*pxB?xQYQq8$7#C|yi2#5A02IXYb7$tbL9uMQ%^%jq zs+az_0v(sH!vY2vLdUA803ZPX(E1Q`zP?jKflHN)DC^h&m(9Zh7Z~TfV~GHO002kO aTC3CgQbDQeI&zqW5Fv;B!vdH5!vl<#>SSgB delta 744 zcmVQr$; zA$3UzG@-<)dni4ORwHTXYFF%xV)RITjXqgfr!{u}fCJvc!p?s4`-a(N(sa1jb$F1b zaDkorVMUGtDiv>6!MGlOY8EiQAXuWnS^#+u2^_8XwsQKv%$$t%aPxdQsqVP1Bm5yjdX7+I(dR7wJE0-gj#b4?1C2!Mqox z=6w5@+*4`ED0_DvrC(5ln%wr&zXi$Vue+IVT6F!TYT&$6dNF8!NYMmTHiMU6cc!?K zt1f1Fx52t6ODOalP}>KtYTbbR_zt(E2n%wudLQH6)1?oxJNi9|3Ecis;jFWIM>>T$ znJ&-~)LhlWmO|-6gU%2%B!X3JbLj(A*pQ?`;gOzWe#Mp+6lB}{I2k3AaWdMSbK_QZ z#TeTE0bgY}9-WwfUGn=n+jSa=- zC3mDtAHK1xcE>%iTG|(Ev4_6K4_2V!*57Ttu=>z{3U+V=gIcwfX_{87b(bf`H|g)X z)3|-$d}X*A2iKdUDGrX?`MZv70iOda&3r*u0jq|bg0UzBlEl29hsHDkx5hLAor@?q zVKOi?V=*>0W@R{GVr5}9VL3KoW;9_qH)1e2I5IOiGGk(8W->Upi@*Y^0vN8@hM)kz z0RV{C#vIKwOGTR(lW)#k;scldxB?xQYQq8$7&-K1p8$XW0MOf*5k!@&Nrz%z7RhT= z;+Ouo0v(sH!vY2v%Q*$x03ZPXj>BhcCHLG#n8R+9%CqnMsAcWV-S-Xe)!vdH5!vl;v`C#|} diff --git a/unity/org.gamecult.cultlib/package.json b/unity/org.gamecult.cultlib/package.json index ad99d1ba..b441d31b 100644 --- a/unity/org.gamecult.cultlib/package.json +++ b/unity/org.gamecult.cultlib/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.cultlib", "displayName": "CultLib", - "version": "1.0.52", + "version": "1.0.53", "unity": "2021.3", "description": "CultCache, CultNet, and CultMesh managed runtime assemblies for Unity.", "license": "MIT",