crowdypy 0.28.0.dev1__tar.gz → 0.30.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (634) hide show
  1. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/AGENTS.md +11 -1
  2. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/MIGRATION.md +48 -0
  3. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/PKG-INFO +5 -1
  4. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/README.md +4 -0
  5. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/docs/compatibility.md +1 -1
  6. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/docs/parity-matrix.md +8 -3
  7. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/replication.hpp +4 -0
  8. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/session_binding.cpp +68 -14
  9. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/pyproject.toml +8 -8
  10. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/schema.gql +23 -1
  11. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_generated/enums.py +1 -1
  12. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_generated/inputs.py +1 -1
  13. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_generated/operations.py +1 -1
  14. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/stores.py +365 -53
  15. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_version.py +1 -1
  16. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/schemas.v1.json +2 -2
  17. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/replication.py +8 -1
  18. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/stores.py +385 -52
  19. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/wire.py +11 -0
  20. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/player-host.v1.json +2 -2
  21. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_durable_stores.py +81 -1
  22. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_replication.py +58 -0
  23. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_wire.py +7 -1
  24. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_world_session.py +33 -9
  25. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/uv.lock +1 -1
  26. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/CMakeLists.txt +1 -1
  27. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/PROVENANCE.md +1 -1
  28. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/enums.hpp +1 -1
  29. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/operations.hpp +1 -1
  30. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/connection.hpp +6 -0
  31. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/types.hpp +4 -0
  32. crowdypy-0.30.0.dev1/vendor/CrowdyCPP/include/crowdy/session/chunk_store.hpp +739 -0
  33. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/world_session.hpp +5 -0
  34. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/codec.hpp +51 -7
  35. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/protocol.hpp +24 -3
  36. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/package.json +6 -6
  37. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/replication/connection.cpp +54 -3
  38. crowdypy-0.30.0.dev1/vendor/CrowdyCPP/src/session/chunk_store.cpp +1381 -0
  39. crowdypy-0.30.0.dev1/vendor/CrowdyCPP/src/session/world_session.cpp +197 -0
  40. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdy-studio-diagnostics.v1.json +2 -2
  41. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdyjs-studio-layout.v1.json +2 -2
  42. crowdypy-0.28.0.dev1/vendor/CrowdyCPP/include/crowdy/session/chunk_store.hpp +0 -592
  43. crowdypy-0.28.0.dev1/vendor/CrowdyCPP/src/session/world_session.cpp +0 -446
  44. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/.gitattributes +0 -0
  45. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/.gitignore +0 -0
  46. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/.gitleaks.toml +0 -0
  47. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/CMakeLists.txt +0 -0
  48. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/LICENSE +0 -0
  49. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/SECURITY.md +0 -0
  50. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/benchmarks/README.md +0 -0
  51. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/benchmarks/bench_replication.py +0 -0
  52. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/docs/e2e-coverage.md +0 -0
  53. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/licenses/OpenSSL-LICENSE.txt +0 -0
  54. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/common.hpp +0 -0
  55. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/module.cpp +0 -0
  56. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/replication_binding.cpp +0 -0
  57. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/voice_binding.cpp +0 -0
  58. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/native/wire_binding.cpp +0 -0
  59. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/Actor.graphql +0 -0
  60. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/Actors.graphql +0 -0
  61. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/BatchLookupActors.graphql +0 -0
  62. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/CreateActor.graphql +0 -0
  63. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/DeleteActor.graphql +0 -0
  64. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/UpdateActor.graphql +0 -0
  65. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/actors/UpdateActorState.graphql +0 -0
  66. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/AppAccessTiers.graphql +0 -0
  67. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/AppFeatures.graphql +0 -0
  68. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/AppGrantMemberCandidates.graphql +0 -0
  69. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/AppUserAccessByApp.graphql +0 -0
  70. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/ArchiveAccessTier.graphql +0 -0
  71. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/ClaimFreeAppAccess.graphql +0 -0
  72. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/CreateAccessTier.graphql +0 -0
  73. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/DefineAppFeature.graphql +0 -0
  74. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/GrantAppAccess.graphql +0 -0
  75. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/GrantMyAppAccess.graphql +0 -0
  76. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/GrantTierFeature.graphql +0 -0
  77. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/MyAppAccess.graphql +0 -0
  78. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/RevokeAppAccess.graphql +0 -0
  79. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/RevokeTierFeature.graphql +0 -0
  80. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/RuntimePermissions.graphql +0 -0
  81. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/SuspendAppAccess.graphql +0 -0
  82. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/TierFeatures.graphql +0 -0
  83. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/appAccess/UpdateAccessTier.graphql +0 -0
  84. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/App.graphql +0 -0
  85. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/AppBySlug.graphql +0 -0
  86. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/AppDiscovery.graphql +0 -0
  87. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/AppRecording.graphql +0 -0
  88. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/AppsForOrg.graphql +0 -0
  89. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/ArchiveApp.graphql +0 -0
  90. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/CodeAdmissions.graphql +0 -0
  91. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/CreateApp.graphql +0 -0
  92. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/MarketplaceApps.graphql +0 -0
  93. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/MyApps.graphql +0 -0
  94. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/PlaceableDatacenters.graphql +0 -0
  95. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/SetAppRequiredDocuments.graphql +0 -0
  96. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/apps/UpdateApp.graphql +0 -0
  97. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/auth/Logout.graphql +0 -0
  98. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/auth/LogoutAllDevices.graphql +0 -0
  99. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/avatars/Avatars.graphql +0 -0
  100. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/billing/AppBudget.graphql +0 -0
  101. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/billing/AppBudgets.graphql +0 -0
  102. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/billing/SetAppBudget.graphql +0 -0
  103. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/billing/WalletBalance.graphql +0 -0
  104. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/billing/WalletTransactions.graphql +0 -0
  105. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/AddChannelMember.graphql +0 -0
  106. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/BanChannelMember.graphql +0 -0
  107. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/Channel.graphql +0 -0
  108. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/ChannelMembers.graphql +0 -0
  109. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/ChannelPolicy.graphql +0 -0
  110. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/ChannelRoles.graphql +0 -0
  111. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/Channels.graphql +0 -0
  112. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/CreateChannel.graphql +0 -0
  113. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/CreateChannelRole.graphql +0 -0
  114. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/DeleteChannel.graphql +0 -0
  115. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/DeleteChannelRole.graphql +0 -0
  116. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/JoinChannel.graphql +0 -0
  117. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/LeaveChannel.graphql +0 -0
  118. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/MyChannels.graphql +0 -0
  119. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/RemoveChannelMember.graphql +0 -0
  120. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/RequestToJoinChannel.graphql +0 -0
  121. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/SetChannelMemberRoles.graphql +0 -0
  122. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/SetChannelPolicy.graphql +0 -0
  123. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/UnbanChannelMember.graphql +0 -0
  124. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/UpdateChannel.graphql +0 -0
  125. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/channels/UpdateChannelRole.graphql +0 -0
  126. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/GetChunk.graphql +0 -0
  127. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/GetChunkLods.graphql +0 -0
  128. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/GetChunksByDistance.graphql +0 -0
  129. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/GetVoxelList.graphql +0 -0
  130. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/UpdateChunk.graphql +0 -0
  131. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/UpdateChunkLods.graphql +0 -0
  132. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/chunks/UpdateChunkState.graphql +0 -0
  133. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/crowdyStudio/CrowdyStudio.graphql +0 -0
  134. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/exec/Exec.graphql +0 -0
  135. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/gameApps/GameApps.graphql +0 -0
  136. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/grids/CreateGridChannel.graphql +0 -0
  137. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/grids/GridChannels.graphql +0 -0
  138. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/grids/MintGridToken.graphql +0 -0
  139. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/host/Host.graphql +0 -0
  140. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/inputLog/InputLogMessages.graphql +0 -0
  141. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/inputLog/InputLogSessions.graphql +0 -0
  142. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/AppManagedPlayerMods.graphql +0 -0
  143. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/DeleteManagedPlayer.graphql +0 -0
  144. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/EndManagedPlayerSessions.graphql +0 -0
  145. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/ManagedPlayer.graphql +0 -0
  146. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/ManagedPlayerFields.graphql +0 -0
  147. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/ManagedPlayers.graphql +0 -0
  148. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/OrgManagedPlayerSettings.graphql +0 -0
  149. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/OrgSigningKeyFields.graphql +0 -0
  150. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/OrgSigningKeys.graphql +0 -0
  151. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/ProvisionManagedPlayers.graphql +0 -0
  152. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/RegisterOrgSigningKey.graphql +0 -0
  153. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/RevokeOrgSigningKey.graphql +0 -0
  154. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/SetAppManagedPlayerMods.graphql +0 -0
  155. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/managedPlayers/UpdateManagedPlayer.graphql +0 -0
  156. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/marketplace/Marketplace.graphql +0 -0
  157. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/moderation/EscalateSafetyReport.graphql +0 -0
  158. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/moderation/ResolveSafetyReport.graphql +0 -0
  159. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/moderation/SafetyReportFields.graphql +0 -0
  160. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/moderation/SafetyReports.graphql +0 -0
  161. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/CreateOrgRole.graphql +0 -0
  162. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/CreateOrgToken.graphql +0 -0
  163. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/CreateOrganization.graphql +0 -0
  164. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/DeleteOrgRole.graphql +0 -0
  165. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/InviteOrgMember.graphql +0 -0
  166. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/MemberRoles.graphql +0 -0
  167. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/MyOrganizations.graphql +0 -0
  168. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/OrgMembers.graphql +0 -0
  169. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/OrgPermissions.graphql +0 -0
  170. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/OrgRoles.graphql +0 -0
  171. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/OrgTokens.graphql +0 -0
  172. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/Organization.graphql +0 -0
  173. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/OrganizationBySlug.graphql +0 -0
  174. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/RemoveOrgMember.graphql +0 -0
  175. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/RevokeOrgToken.graphql +0 -0
  176. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/UpdateOrgMemberRoles.graphql +0 -0
  177. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/UpdateOrgRole.graphql +0 -0
  178. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/organizations/UpdateOrgToken.graphql +0 -0
  179. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/payments/CapturePaypalCheckout.graphql +0 -0
  180. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/payments/CreateCheckout.graphql +0 -0
  181. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/payments/MyCheckouts.graphql +0 -0
  182. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/platform/PlatformConfig.graphql +0 -0
  183. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/platform/TerritoryPolicies.graphql +0 -0
  184. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/playerWallet/PlayerWallet.graphql +0 -0
  185. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/quotas/DeleteQuota.graphql +0 -0
  186. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/quotas/EffectiveQuota.graphql +0 -0
  187. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/quotas/QuotasForApp.graphql +0 -0
  188. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/quotas/QuotasForOrg.graphql +0 -0
  189. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/quotas/SetQuota.graphql +0 -0
  190. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/AcceptContact.graphql +0 -0
  191. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/BlockPlayer.graphql +0 -0
  192. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/CommSettingsFields.graphql +0 -0
  193. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/ContactRequests.graphql +0 -0
  194. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/FileSafetyReport.graphql +0 -0
  195. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/MyBlocks.graphql +0 -0
  196. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/MyCommSettings.graphql +0 -0
  197. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/MyContacts.graphql +0 -0
  198. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/PlayerContactFields.graphql +0 -0
  199. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/RemoveContact.graphql +0 -0
  200. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/RequestContact.graphql +0 -0
  201. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/RequestParentalConsent.graphql +0 -0
  202. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/SetMyCommSettings.graphql +0 -0
  203. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/safety/UnblockPlayer.graphql +0 -0
  204. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/serverStatus/ActiveGraphQLServers.graphql +0 -0
  205. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/serverStatus/GameClientBootstrap.graphql +0 -0
  206. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/serverStatus/GraphqlServers.graphql +0 -0
  207. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/serverStatus/ServerWithLeastClients.graphql +0 -0
  208. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/serverStatus/VersionInfo.graphql +0 -0
  209. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/sharedEnvironment/SharedEnvironment.graphql +0 -0
  210. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/state/DeleteUserAppState.graphql +0 -0
  211. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/state/UpdateUserAppState.graphql +0 -0
  212. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/state/UserAppState.graphql +0 -0
  213. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/state/UserAppStates.graphql +0 -0
  214. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/AddTeamMember.graphql +0 -0
  215. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/BanTeamMember.graphql +0 -0
  216. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/CreateTeam.graphql +0 -0
  217. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/CreateTeamRole.graphql +0 -0
  218. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/DeleteTeam.graphql +0 -0
  219. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/DeleteTeamRole.graphql +0 -0
  220. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/JoinTeam.graphql +0 -0
  221. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/LeaveTeam.graphql +0 -0
  222. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/MyTeams.graphql +0 -0
  223. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/RemoveTeamMember.graphql +0 -0
  224. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/RequestToJoinTeam.graphql +0 -0
  225. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/SetTeamMemberRoles.graphql +0 -0
  226. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/SetTeamPolicy.graphql +0 -0
  227. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/Team.graphql +0 -0
  228. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/TeamMembers.graphql +0 -0
  229. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/TeamPolicy.graphql +0 -0
  230. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/TeamRoles.graphql +0 -0
  231. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/Teams.graphql +0 -0
  232. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/UnbanTeamMember.graphql +0 -0
  233. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/UpdateTeam.graphql +0 -0
  234. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teams/UpdateTeamRole.graphql +0 -0
  235. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/teleport/TeleportRequest.graphql +0 -0
  236. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/usage/AppGraphqlOperations.graphql +0 -0
  237. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/usage/AppUsageSummary.graphql +0 -0
  238. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/usage/PlayerPulse.graphql +0 -0
  239. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/DeleteMyAccount.graphql +0 -0
  240. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/FreePlayWindow.graphql +0 -0
  241. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/Me.graphql +0 -0
  242. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/PlayerProfile.graphql +0 -0
  243. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/UpdateGamertag.graphql +0 -0
  244. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/UpdateUserState.graphql +0 -0
  245. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/users/User.graphql +0 -0
  246. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/voxels/ListVoxelUpdatesByDistance.graphql +0 -0
  247. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/voxels/ListVoxels.graphql +0 -0
  248. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/voxels/RollbackVoxelUpdates.graphql +0 -0
  249. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/voxels/UpdateVoxel.graphql +0 -0
  250. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/operations/voxels/VoxelUpdateHistory.graphql +0 -0
  251. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/_pins.py +0 -0
  252. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/assert_default_origin.py +0 -0
  253. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/build_openssl.sh +0 -0
  254. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/check_content_policy.py +0 -0
  255. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/check_pin_tiers.py +0 -0
  256. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/cibw_before_all_linux.sh +0 -0
  257. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/resolve-release-tier.sh +0 -0
  258. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/resolve-release-tier.test.sh +0 -0
  259. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/resolve_pypi_version.py +0 -0
  260. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/stamp_version.py +0 -0
  261. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/ci/verify_artifacts.py +0 -0
  262. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/codegen.py +0 -0
  263. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/schema_drift.py +0 -0
  264. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/schema_sync.py +0 -0
  265. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/unasync.py +0 -0
  266. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/scripts/vendor_crowdycpp.py +0 -0
  267. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/__init__.py +0 -0
  268. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_concurrency.py +0 -0
  269. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_default_origin.py +0 -0
  270. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_generated/__init__.py +0 -0
  271. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_grid.py +0 -0
  272. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_native.pyi +0 -0
  273. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_operation.py +0 -0
  274. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/__init__.py +0 -0
  275. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/client.py +0 -0
  276. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/__init__.py +0 -0
  277. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/_base.py +0 -0
  278. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/actors.py +0 -0
  279. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/admin.py +0 -0
  280. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/app_access.py +0 -0
  281. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/apps.py +0 -0
  282. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/auth.py +0 -0
  283. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/avatars.py +0 -0
  284. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/billing.py +0 -0
  285. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/channels.py +0 -0
  286. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/chunks.py +0 -0
  287. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio.py +0 -0
  288. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_agent.py +0 -0
  289. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_github.py +0 -0
  290. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/discovery.py +0 -0
  291. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/exec.py +0 -0
  292. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/game_apps.py +0 -0
  293. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/grids.py +0 -0
  294. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/host.py +0 -0
  295. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/input_log.py +0 -0
  296. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/managed_players.py +0 -0
  297. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/marketplace.py +0 -0
  298. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/moderation.py +0 -0
  299. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/organizations.py +0 -0
  300. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/payments.py +0 -0
  301. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/platform.py +0 -0
  302. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/player_wallet.py +0 -0
  303. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/portal.py +0 -0
  304. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/quotas.py +0 -0
  305. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/safety.py +0 -0
  306. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/server_status.py +0 -0
  307. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/shared_environment.py +0 -0
  308. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/state.py +0 -0
  309. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/teams.py +0 -0
  310. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/teleport.py +0 -0
  311. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/udp.py +0 -0
  312. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/usage.py +0 -0
  313. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/users.py +0 -0
  314. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/domains/voxels.py +0 -0
  315. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/graphql.py +0 -0
  316. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/grid_scope.py +0 -0
  317. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/__init__.py +0 -0
  318. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/actions.py +0 -0
  319. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/kit.py +0 -0
  320. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/mirror.py +0 -0
  321. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/__init__.py +0 -0
  322. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/arenas.py +0 -0
  323. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/encounters.py +0 -0
  324. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/instances.py +0 -0
  325. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/leaderboards.py +0 -0
  326. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/market.py +0 -0
  327. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/matchmaking.py +0 -0
  328. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/minigames.py +0 -0
  329. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/npcs.py +0 -0
  330. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/player.py +0 -0
  331. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/presence.py +0 -0
  332. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/racing.py +0 -0
  333. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/sessions.py +0 -0
  334. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/tables.py +0 -0
  335. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/tactics.py +0 -0
  336. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/territory.py +0 -0
  337. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/modules/world.py +0 -0
  338. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/protocol.py +0 -0
  339. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/realtime.py +0 -0
  340. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/runtime.py +0 -0
  341. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/social.py +0 -0
  342. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/store.py +0 -0
  343. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/topology.py +0 -0
  344. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/kit/wire.py +0 -0
  345. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/rediscover.py +0 -0
  346. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/_sync/world.py +0 -0
  347. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/auth_state.py +0 -0
  348. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/client.py +0 -0
  349. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/codecs.py +0 -0
  350. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/datacenter_redirect.py +0 -0
  351. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/__init__.py +0 -0
  352. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/_base.py +0 -0
  353. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/actors.py +0 -0
  354. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/admin.py +0 -0
  355. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/app_access.py +0 -0
  356. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/apps.py +0 -0
  357. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/auth.py +0 -0
  358. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/avatars.py +0 -0
  359. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/billing.py +0 -0
  360. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/channels.py +0 -0
  361. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/chunks.py +0 -0
  362. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/crowdy_studio.py +0 -0
  363. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/crowdy_studio_agent.py +0 -0
  364. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/crowdy_studio_github.py +0 -0
  365. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/discovery.py +0 -0
  366. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/exec.py +0 -0
  367. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/game_apps.py +0 -0
  368. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/grids.py +0 -0
  369. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/host.py +0 -0
  370. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/input_log.py +0 -0
  371. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/managed_players.py +0 -0
  372. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/marketplace.py +0 -0
  373. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/moderation.py +0 -0
  374. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/organizations.py +0 -0
  375. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/payments.py +0 -0
  376. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/platform.py +0 -0
  377. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/player_wallet.py +0 -0
  378. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/portal.py +0 -0
  379. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/quotas.py +0 -0
  380. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/safety.py +0 -0
  381. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/server_status.py +0 -0
  382. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/shared_environment.py +0 -0
  383. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/state.py +0 -0
  384. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/teams.py +0 -0
  385. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/teleport.py +0 -0
  386. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/udp.py +0 -0
  387. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/usage.py +0 -0
  388. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/users.py +0 -0
  389. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/domains/voxels.py +0 -0
  390. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/enums.py +0 -0
  391. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/errors.py +0 -0
  392. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/estate.py +0 -0
  393. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/exec_gateway.py +0 -0
  394. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/graphql.py +0 -0
  395. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/grid_scope.py +0 -0
  396. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/inputs.py +0 -0
  397. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/__init__.py +0 -0
  398. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/actions.py +0 -0
  399. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/kit.py +0 -0
  400. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/mirror.py +0 -0
  401. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/__init__.py +0 -0
  402. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/arenas.py +0 -0
  403. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/encounters.py +0 -0
  404. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/instances.py +0 -0
  405. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/leaderboards.py +0 -0
  406. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/market.py +0 -0
  407. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/matchmaking.py +0 -0
  408. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/minigames.py +0 -0
  409. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/npcs.py +0 -0
  410. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/player.py +0 -0
  411. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/presence.py +0 -0
  412. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/racing.py +0 -0
  413. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/sessions.py +0 -0
  414. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/tables.py +0 -0
  415. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/tactics.py +0 -0
  416. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/territory.py +0 -0
  417. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/modules/world.py +0 -0
  418. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/protocol.py +0 -0
  419. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/realtime.py +0 -0
  420. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/runtime.py +0 -0
  421. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/social.py +0 -0
  422. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/store.py +0 -0
  423. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/topology.py +0 -0
  424. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/kit/wire.py +0 -0
  425. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/lb_cookie.py +0 -0
  426. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/media.py +0 -0
  427. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/pkce.py +0 -0
  428. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/__init__.py +0 -0
  429. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/agent_errors.py +0 -0
  430. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/agent_types.py +0 -0
  431. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/json_schema.py +0 -0
  432. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/schemas.py +0 -0
  433. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/player_host/types.py +0 -0
  434. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/py.typed +0 -0
  435. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/rediscover.py +0 -0
  436. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/session.py +0 -0
  437. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/__init__.py +0 -0
  438. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/client_tick_interval.py +0 -0
  439. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/controller.py +0 -0
  440. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/diagnostics.py +0 -0
  441. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/draft.py +0 -0
  442. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/github_draft_store.py +0 -0
  443. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/github_new_repo.py +0 -0
  444. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/layout.py +0 -0
  445. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/models.py +0 -0
  446. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/studio/starter_projects.py +0 -0
  447. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/subscriptions.py +0 -0
  448. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/sync.py +0 -0
  449. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/utils.py +0 -0
  450. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/src/crowdypy/world.py +0 -0
  451. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/conftest.py +0 -0
  452. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/__init__.py +0 -0
  453. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/conftest.py +0 -0
  454. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_identity.py +0 -0
  455. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_idle_release.py +0 -0
  456. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_input_log.py +0 -0
  457. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_open_grid_exec_gateway.py +0 -0
  458. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_ranged_channel.py +0 -0
  459. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_replication.py +0 -0
  460. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_studio.py +0 -0
  461. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_teen_safety.py +0 -0
  462. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_world.py +0 -0
  463. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/e2e/test_e2e_world_data.py +0 -0
  464. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/README.md +0 -0
  465. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/binary-wire-fixtures.json +0 -0
  466. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/exec-client-frames.json +0 -0
  467. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/kit-protocol.json +0 -0
  468. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/fixtures/voice-frames.json +0 -0
  469. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/__init__.py +0 -0
  470. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/__init__.py +0 -0
  471. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_crowdycpp_roots.py +0 -0
  472. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_input_log_reads.py +0 -0
  473. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_managed_players.py +0 -0
  474. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_org_domains.py +0 -0
  475. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_safety_domains.py +0 -0
  476. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_social_domains.py +0 -0
  477. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_studio_exec_domains.py +0 -0
  478. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/domains/test_world_domains.py +0 -0
  479. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_check_pin_tiers.py +0 -0
  480. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_core.py +0 -0
  481. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_estate_moves.py +0 -0
  482. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_exec_gateway.py +0 -0
  483. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_fixture_provenance.py +0 -0
  484. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_github_draft_store.py +0 -0
  485. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_grid_scope.py +0 -0
  486. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_kit.py +0 -0
  487. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_kit_protocol.py +0 -0
  488. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_lazy_exports.py +0 -0
  489. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_lb_cookie.py +0 -0
  490. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_player_host.py +0 -0
  491. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_refusals.py +0 -0
  492. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_release_versions.py +0 -0
  493. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_sdk_audience.py +0 -0
  494. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_studio_controller.py +0 -0
  495. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_studio_diagnostics.py +0 -0
  496. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_studio_game_editor.py +0 -0
  497. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_studio_layout.py +0 -0
  498. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_subscriptions.py +0 -0
  499. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_transport.py +0 -0
  500. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_udp_api.py +0 -0
  501. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_udp_first_send_retry.py +0 -0
  502. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tests/unit/test_voice_frames.py +0 -0
  503. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tools/e2e/provision.py +0 -0
  504. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tools/fixtures/player_host.mjs +0 -0
  505. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tools/parity/classifications.toml +0 -0
  506. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/tools/parity/parity.py +0 -0
  507. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/LICENSE +0 -0
  508. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/cmake/CheckPublicHeaders.cmake +0 -0
  509. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/cmake/CrowdyCPPConfig.cmake.in +0 -0
  510. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/cmake/CrowdyFindOpus.cmake +0 -0
  511. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/cmake/studio_layout_fixture.hpp.in +0 -0
  512. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/client.hpp +0 -0
  513. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/base64.hpp +0 -0
  514. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/bytes.hpp +0 -0
  515. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/clock.hpp +0 -0
  516. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/crypto.hpp +0 -0
  517. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/logger.hpp +0 -0
  518. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/result.hpp +0 -0
  519. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/spsc.hpp +0 -0
  520. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/uuid.hpp +0 -0
  521. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/crowdy.hpp +0 -0
  522. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/default_origin.hpp +0 -0
  523. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/admin.hpp +0 -0
  524. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/auth.hpp +0 -0
  525. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio.hpp +0 -0
  526. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_agent.hpp +0 -0
  527. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_github.hpp +0 -0
  528. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/discovery.hpp +0 -0
  529. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/domain_base.hpp +0 -0
  530. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/exec.hpp +0 -0
  531. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/game_apps.hpp +0 -0
  532. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/grids.hpp +0 -0
  533. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/groups.hpp +0 -0
  534. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/marketplace.hpp +0 -0
  535. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/player_wallet.hpp +0 -0
  536. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/portal.hpp +0 -0
  537. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/realtime_control.hpp +0 -0
  538. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/safety.hpp +0 -0
  539. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/server_status.hpp +0 -0
  540. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/types.hpp +0 -0
  541. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/users.hpp +0 -0
  542. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/world_data.hpp +0 -0
  543. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/game_session.hpp +0 -0
  544. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/async_scope.hpp +0 -0
  545. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/auth_state.hpp +0 -0
  546. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/cancel.hpp +0 -0
  547. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/datacenter_redirect.hpp +0 -0
  548. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/dispatcher.hpp +0 -0
  549. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/errors.hpp +0 -0
  550. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/estate.hpp +0 -0
  551. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/graphql_client.hpp +0 -0
  552. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/http.hpp +0 -0
  553. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/json.hpp +0 -0
  554. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/rediscover.hpp +0 -0
  555. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/subscription_client.hpp +0 -0
  556. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/websocket.hpp +0 -0
  557. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/actions.hpp +0 -0
  558. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/economy.hpp +0 -0
  559. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/genres.hpp +0 -0
  560. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/kit.hpp +0 -0
  561. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/mirror.hpp +0 -0
  562. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/modules.hpp +0 -0
  563. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/protocol.hpp +0 -0
  564. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/realtime.hpp +0 -0
  565. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/runtime.hpp +0 -0
  566. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/social.hpp +0 -0
  567. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/topology.hpp +0 -0
  568. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/wire.hpp +0 -0
  569. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/opus.hpp +0 -0
  570. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/video_frames.hpp +0 -0
  571. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/voice_frames.hpp +0 -0
  572. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/adapter.hpp +0 -0
  573. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/player_host.hpp +0 -0
  574. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/schemas.hpp +0 -0
  575. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/types.hpp +0 -0
  576. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/session_provider.hpp +0 -0
  577. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/udp_socket.hpp +0 -0
  578. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/codec.hpp +0 -0
  579. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/durable.hpp +0 -0
  580. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/keys.hpp +0 -0
  581. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/stores.hpp +0 -0
  582. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/controller.hpp +0 -0
  583. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/diagnostics.hpp +0 -0
  584. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/editor.hpp +0 -0
  585. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github.hpp +0 -0
  586. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github_layout.hpp +0 -0
  587. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/integration.hpp +0 -0
  588. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/layout.hpp +0 -0
  589. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/models.hpp +0 -0
  590. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/runtime.hpp +0 -0
  591. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/include/crowdy/world.hpp +0 -0
  592. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/client.cpp +0 -0
  593. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/base64.cpp +0 -0
  594. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/clock.cpp +0 -0
  595. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/crypto_default_unavailable.cpp +0 -0
  596. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/crypto_openssl.cpp +0 -0
  597. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/crypto_unavailable.cpp +0 -0
  598. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/logger.cpp +0 -0
  599. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/core/uuid.cpp +0 -0
  600. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/domains/exec.cpp +0 -0
  601. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/game_session.cpp +0 -0
  602. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/async_transport.cpp +0 -0
  603. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/auth_state.cpp +0 -0
  604. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/error_extensions.hpp +0 -0
  605. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/errors.cpp +0 -0
  606. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/graphql_client.cpp +0 -0
  607. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/http_curl.cpp +0 -0
  608. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/http_none.cpp +0 -0
  609. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/json.cpp +0 -0
  610. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/subscription_client.cpp +0 -0
  611. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_curl.cpp +0 -0
  612. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_none.cpp +0 -0
  613. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/economy.cpp +0 -0
  614. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/genres.cpp +0 -0
  615. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/mirror.cpp +0 -0
  616. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/modules.cpp +0 -0
  617. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/protocol.cpp +0 -0
  618. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/runtime.cpp +0 -0
  619. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/kit/topology.cpp +0 -0
  620. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/media/opus.cpp +0 -0
  621. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/player_host/schemas.cpp +0 -0
  622. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/player_host/types.cpp +0 -0
  623. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/replication/socket_errors.hpp +0 -0
  624. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/replication/udp_socket.cpp +0 -0
  625. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/studio/diagnostics.cpp +0 -0
  626. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/studio/editor.cpp +0 -0
  627. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/src/studio/integration.cpp +0 -0
  628. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/LICENSE +0 -0
  629. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.c +0 -0
  630. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.h +0 -0
  631. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-client-frames.json +0 -0
  632. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-gateway-cases.json +0 -0
  633. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/kit-protocol.json +0 -0
  634. {crowdypy-0.28.0.dev1 → crowdypy-0.30.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/voice-frames.json +0 -0
@@ -131,7 +131,10 @@ idle timeout, with `COMMAND_SESSION_RELEASED` reason 5. CrowdyCPP verifies and h
131
131
  connection reports `ConnState.INACTIVE` (6), which nothing reconnects; a game calls
132
132
  `client.udp.connect()` on the player's next input. Status rows carry the state as a number, so
133
133
  `ConnState` must name every value CrowdyCPP's `replication::ConnState` has or `ConnState(...)`
134
- raises. Since 0.27.0 (CrowdyCPP 0.79.0) an idle release within `idle_release_guard_ms` (60 s) of
134
+ raises. Since 0.29.0 (CrowdyCPP 0.81.0) a capabilities message carries the assignment's control
135
+ nonce and a v0.45.0 server sends the bound 44/45 forms: a test that wants a final bound release reads
136
+ the nonce from the client's CLIENT_CAPABILITIES (`test_replication.py`, `bound_release`). Since
137
+ 0.27.0 (CrowdyCPP 0.79.0) an idle release within `idle_release_guard_ms` (60 s) of
135
138
  the client's own gameplay input reconnects instead (a captured release frame verifies again);
136
139
  a test that wants a final release teaches the fake server the address with a heartbeat, not an
137
140
  actor update.
@@ -243,6 +246,13 @@ The replication system saturates the local network stack, so the binding
243
246
  16x16x16 one-byte grid cannot hold goes to `ChunkData::overlay`.
244
247
  - Do not write voxel types or states into the dense grid from Python. That bypasses the
245
248
  overlay, and the echo matching of local edits.
249
+ - Since 0.30.0 (CrowdyCPP 0.82.0) the native store paces and undoes edits; the binding turns its
250
+ own I/O thread, reloads and reconnect catch-up off (`ioThread`, `reloadReplacedChunks`,
251
+ `catchUpOnReconnect` false), because the facade reads the durable store itself and runs
252
+ `catch_up` and the reload of a replaced chunk. A refused, unsent or timed-out edit reaches the
253
+ facade as an `EDIT_REFUSED` event row (`a` packs x/y/z as 16-bit fields, `c` the result,
254
+ `restored` and the error code, `epochMs` the edit id). Read a chunk through `forEachState`,
255
+ `forEachOverlay` and `grid()`: `ChunkData` keeps no public maps any more.
246
256
  - The voice helpers (`native/voice_binding.cpp`) bind CrowdyCPP's `voice_frames.hpp`.
247
257
  `crowdypy.media` checks every argument as CrowdyJS does first, because CrowdyCPP clamps the
248
258
  options CrowdyJS refuses.
@@ -3,6 +3,54 @@
3
3
  CrowdyPy is pre-1.0. Within a minor line, patch releases keep source compatibility; each
4
4
  new minor may change the API. Read the section for every minor you skip.
5
5
 
6
+ ## 0.30.0
7
+
8
+ CrowdyJS 18.30.0 and CrowdyCPP 0.82.0 (the ChunkStore rework). Box reads and `since` need ck-api
9
+ v2.67.0. **Breaking** for code that keeps `set_voxel()`'s return value or relies on a realtime
10
+ edit being written back.
11
+
12
+ - **`ensure_around` reads only what the store does not hold**, as boxes (`lowChunk`/`highChunk`)
13
+ read in pages of the size the server applied; a chunk two pages return is applied once
14
+ (`duplicate_page_chunks`). A step along one axis at range 8 reads the 289 chunks it uncovers.
15
+ Range 0 reads one chunk. `CachedChunk` has `voxel_states_truncated` and `stored_at`.
16
+ - **`set_voxel()` returns an edit id, is paced, and is not written back.** At most
17
+ `max_edits_in_flight` (128) are unanswered and `max_edits_per_second` (250) go out a second
18
+ (`chunk_options`); the rest wait, already shown (`queued_edits`, `edits_in_flight`). The server
19
+ records realtime edits, so the chunk is no longer queued for write-back (it was, whole).
20
+ - **A refused edit is undone.** One the server refuses, the connection does not take, or whose
21
+ echo does not come back within `edit_timeout_ms` (10 s) puts the voxel back and reaches
22
+ `on_edit_refused` as a `VoxelEditRefusal` (`reason` `refused`, `not_sent` or `timeout`,
23
+ `restored`, `error_code`, `edit_id`).
24
+ - **A replaced chunk is read again** (`chunk_changed`, `reload_replaced_chunks`), and a seed queued
25
+ for write-back gives way to it. **After the connection comes back**, `catch_up(since)` reads the
26
+ last area's rewritten chunks and those with edits since 30 s before the drop
27
+ (`catch_up_on_reconnect`).
28
+ - A hydration replaces the chunk's states and overlay with the stored copy's and keeps this
29
+ client's unanswered edits over it (the native store's rule since CrowdyCPP 0.82.0).
30
+
31
+ ## 0.29.0
32
+
33
+ CrowdyJS 18.29.0 and CrowdyCPP 0.81.0. It needs nothing new on the tier; the bound frames and
34
+ `chunk_changed` come from replication servers v0.45.0.
35
+
36
+ - **A server's reconnect command is honoured.** The native verifier had computed the HMAC of
37
+ `COMMAND_RECONNECT` (22) over the type byte and the game token, while the replication servers
38
+ sign the type byte alone, so no reconnect command ever verified: each counted in
39
+ `stats()["hmac_failures"]` and the client stayed until its watchdog moved it.
40
+ `wire.verify_command_reconnect` checks the servers' form.
41
+ - **Reconnect and release frames are bound to the assignment.** Each assignment draws a random
42
+ 8-byte nonce, which the capabilities message carries; a v0.45.0 server sends
43
+ `COMMAND_RECONNECT_BOUND` (44) and `COMMAND_SESSION_RELEASED_BOUND` (45) with it inside the
44
+ HMAC. One carrying another assignment's nonce, captured earlier and sent again, is dropped and
45
+ counted in `stats()["stale_bound_control"]`. A verified bound idle release is final at once;
46
+ `idle_release_guard_ms` applies only to the legacy 28, which older servers and the Game API's
47
+ relay still send (the client cannot tell an older server from a replay, so it still accepts
48
+ them).
49
+ - **`chunk_changed`** (handler name, `MessageType.CHUNK_CHANGED_NOTIFICATION`, 146): a chunk near
50
+ the player was replaced as a whole by a hub's or mod's `world.set_chunk`;
51
+ `notification.updated_at_ms` is its new `updatedAt`. Read it again. It arrives with or without a
52
+ world session attached.
53
+
6
54
  ## 0.28.0
7
55
 
8
56
  CrowdyJS 18.28.0 and CrowdyCPP 0.80.0. **It needs ck-api v2.67.0**: `game_apps.nearby_grids()`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crowdypy
3
- Version: 0.28.0.dev1
3
+ Version: 0.30.0.dev1
4
4
  Summary: Official Python SDK for Crowded Kingdoms: typed GraphQL clients and a native UDP replication core
5
5
  Keywords: crowded-kingdoms,multiplayer,replication,graphql,sdk,udp
6
6
  Author: Crowded Kingdoms
@@ -51,6 +51,10 @@ CrowdyPy follows the [CrowdyJS](https://github.com/CrowdedKingdoms/CrowdyJS) API
51
51
  client, bound with [nanobind](https://github.com/wjakob/nanobind) and shipped inside the
52
52
  wheel. Python never touches a datagram.
53
53
 
54
+ **v0.30.0: the ChunkStore rework.** `ensure_around` reads only what is missing, as boxes, paged; `set_voxel` is paced and returns an edit id, and an edit the server refuses or never echoes is undone (`on_edit_refused`); a replaced chunk is read again and a reconnect catches up; realtime edits are no longer written back. CrowdyJS 18.30.0 and CrowdyCPP 0.82.0. See [MIGRATION.md](MIGRATION.md).
55
+
56
+ **v0.29.0: reconnect commands verify, bound control frames, and `chunk_changed`.** A server's `COMMAND_RECONNECT` verifies again; against replication servers v0.45.0 the reconnect and release frames carry a per-assignment nonce under their HMAC, so one captured earlier is refused (`stats()["stale_bound_control"]`); `chunk_changed` reports a chunk a hub's or mod's `world.set_chunk` replaced. CrowdyJS 18.29.0 and CrowdyCPP 0.81.0. See [MIGRATION.md](MIGRATION.md).
57
+
54
58
  **v0.28.0: region reads.** `chunks.by_distance()` and `voxels.list_by_distance()` take a box (`lowChunk`, `highChunk`) as well as a cube, pages are stable and answer the paging applied, `since` filters a chunk read, `voxels.list()` pages, and `game_apps.nearby_grids()` returns your own `permissionKeys`. Needs ck-api v2.67.0. CrowdyJS 18.28.0 and CrowdyCPP 0.80.0. See [MIGRATION.md](MIGRATION.md).
55
59
 
56
60
  **v0.27.0: a replayed idle release cannot end a playing player's session.** An idle release that arrives within a minute of this client's own gameplay input reconnects instead of going `ConnState.INACTIVE` (`idle_release_guard_ms`, counted in `stats()["idle_releases_after_input"]`), and a reassignment left over from the session that ended no longer reassigns the next one. The native chunk store keeps unechoed local edits over a stored copy. CrowdyJS 18.27.0 and CrowdyCPP 0.79.0. See [MIGRATION.md](MIGRATION.md).
@@ -11,6 +11,10 @@ CrowdyPy follows the [CrowdyJS](https://github.com/CrowdedKingdoms/CrowdyJS) API
11
11
  client, bound with [nanobind](https://github.com/wjakob/nanobind) and shipped inside the
12
12
  wheel. Python never touches a datagram.
13
13
 
14
+ **v0.30.0: the ChunkStore rework.** `ensure_around` reads only what is missing, as boxes, paged; `set_voxel` is paced and returns an edit id, and an edit the server refuses or never echoes is undone (`on_edit_refused`); a replaced chunk is read again and a reconnect catches up; realtime edits are no longer written back. CrowdyJS 18.30.0 and CrowdyCPP 0.82.0. See [MIGRATION.md](MIGRATION.md).
15
+
16
+ **v0.29.0: reconnect commands verify, bound control frames, and `chunk_changed`.** A server's `COMMAND_RECONNECT` verifies again; against replication servers v0.45.0 the reconnect and release frames carry a per-assignment nonce under their HMAC, so one captured earlier is refused (`stats()["stale_bound_control"]`); `chunk_changed` reports a chunk a hub's or mod's `world.set_chunk` replaced. CrowdyJS 18.29.0 and CrowdyCPP 0.81.0. See [MIGRATION.md](MIGRATION.md).
17
+
14
18
  **v0.28.0: region reads.** `chunks.by_distance()` and `voxels.list_by_distance()` take a box (`lowChunk`, `highChunk`) as well as a cube, pages are stable and answer the paging applied, `since` filters a chunk read, `voxels.list()` pages, and `game_apps.nearby_grids()` returns your own `permissionKeys`. Needs ck-api v2.67.0. CrowdyJS 18.28.0 and CrowdyCPP 0.80.0. See [MIGRATION.md](MIGRATION.md).
15
19
 
16
20
  **v0.27.0: a replayed idle release cannot end a playing player's session.** An idle release that arrives within a minute of this client's own gameplay input reconnects instead of going `ConnState.INACTIVE` (`idle_release_guard_ms`, counted in `stats()["idle_releases_after_input"]`), and a reassignment left over from the session that ended no longer reassigns the next one. The native chunk store keeps unechoed local edits over a stored copy. CrowdyJS 18.27.0 and CrowdyCPP 0.79.0. See [MIGRATION.md](MIGRATION.md).
@@ -5,7 +5,7 @@ are in `pyproject.toml` (`[project].version`, `[tool.crowdypy.crowdyjs]`,
5
5
  `[tool.crowdypy.crowdycpp]`); `tests/unit/test_release_versions.py` refuses this page when
6
6
  its version disagrees.
7
7
 
8
- - CrowdyPy `0.28.0`
8
+ - CrowdyPy `0.30.0`
9
9
  - API surface: CrowdyJS (the pinned version and commit in `pyproject.toml`); the generated
10
10
  `docs/parity-matrix.md` lists every covered method, every native equivalent and every
11
11
  browser exclusion with its reason. The gate is strict: there are no portable gaps, and a
@@ -4,14 +4,14 @@ Generated by `tools/parity/parity.py`; do not edit by hand. Classifications live
4
4
 
5
5
  ## Target
6
6
 
7
- - CrowdyJS: `18.28.0` at `bc8b2b0737c0caf1486358c721123fa72fc1b955`
8
- - CrowdyCPP (native core): `0.80.0` at `d0d95975d6a6bcf1e08c3fd1cbde4a8be433b062`
7
+ - CrowdyJS: `18.30.0` at `4840d76029ffb15a6de6232dab9336f2e9ab6514`
8
+ - CrowdyCPP (native core): `0.82.0` at `c6875412bcea97120b4540b80d9b34504c29acf9`
9
9
  - schema.gql identical to CrowdyJS's: yes
10
10
  - Gate mode: strict portable parity (every portable gap is release-blocking)
11
11
 
12
12
  ## Summary
13
13
 
14
- - Covered: 1475
14
+ - Covered: 1480
15
15
  - Portable gap: 0
16
16
  - Native equivalent: 47
17
17
  - Browser exclusion: 128
@@ -792,6 +792,9 @@ Generated by `tools/parity/parity.py`; do not edit by hand. Classifications live
792
792
  | `ChannelsAPI.unban` | covered |
793
793
  | `ChannelsAPI.update` | covered |
794
794
  | `ChannelsAPI.updateRole` | covered |
795
+ | `ChunkStore.catchUp` | covered |
796
+ | `ChunkStore.duplicatePageChunks` | covered |
797
+ | `ChunkStore.editsInFlight` | covered |
795
798
  | `ChunkStore.ensureAround` | covered |
796
799
  | `ChunkStore.flush` | covered |
797
800
  | `ChunkStore.get` | covered |
@@ -799,9 +802,11 @@ Generated by `tools/parity/parity.py`; do not edit by hand. Classifications live
799
802
  | `ChunkStore.list` | covered |
800
803
  | `ChunkStore.markDirty` | covered |
801
804
  | `ChunkStore.onChunkChanged` | covered |
805
+ | `ChunkStore.onEditRefused` | covered |
802
806
  | `ChunkStore.onWriteBackFailed` | covered |
803
807
  | `ChunkStore.pendingWriteBacks` | covered |
804
808
  | `ChunkStore.pruneBeyond` | covered |
809
+ | `ChunkStore.queuedEdits` | covered |
805
810
  | `ChunkStore.revision` | covered |
806
811
  | `ChunkStore.seed` | covered |
807
812
  | `ChunkStore.setVoxel` | covered |
@@ -738,6 +738,7 @@ class PyConnection {
738
738
  d["ring_dropped"] = s.ringDropped;
739
739
  d["reconnects"] = s.reconnects;
740
740
  d["idle_releases_after_input"] = s.idleReleasesAfterInput;
741
+ d["stale_bound_control"] = s.staleBoundControl;
741
742
  d["last_server_epoch_ms"] = s.lastServerEpochMs;
742
743
  nb::dict sentByType;
743
744
  nb::dict receivedByType;
@@ -797,6 +798,9 @@ class PyConnection {
797
798
  h.actorLeft = [this](const replication::SpatialNotification& n, std::uint8_t reason) {
798
799
  rows_.spatial(n, {reason, 0, 0, 0}, n.payload);
799
800
  };
801
+ h.chunkChanged = [this](const replication::SpatialNotification& n, std::int64_t updatedAtMs) {
802
+ rows_.spatial(n, {updatedAtMs, 0, 0, 0}, n.payload);
803
+ };
800
804
  auto event = [this](const replication::SpatialNotification& n, const wire::EventPayloadView& e) {
801
805
  rows_.spatial(n, {e.eventType, 0, 0, 0}, e.state);
802
806
  };
@@ -51,6 +51,10 @@ struct SessionEvent {
51
51
  kDirectMessage,
52
52
  kEvent,
53
53
  kActorLeft,
54
+ /// An edit undone or not sent (CrowdyCPP 0.82.0): `chunk`; `a` the voxel (x, y, z as
55
+ /// 16-bit fields); `b` its type; `c` the result | restored << 8 | error code << 16;
56
+ /// `epochMs` the edit id.
57
+ kEditRefused,
54
58
  };
55
59
  int kind = 0;
56
60
  std::string lane; // "" for the default lane
@@ -141,7 +145,8 @@ class PySession {
141
145
  PySession(PyConnection& conn, const std::string& appId, const std::string& actorUuid,
142
146
  int sendHz, std::int64_t keyframeIntervalMs, std::int64_t heartbeatIntervalMs,
143
147
  int distance, int decay, std::int64_t staleAfterMs, int historySize,
144
- std::int64_t reapIntervalMs, int voxelSendDistance)
148
+ std::int64_t reapIntervalMs, int voxelSendDistance, int maxEditsInFlight,
149
+ int maxEditsPerSecond, std::int64_t editTimeoutMs)
145
150
  : conn_(conn) {
146
151
  session::WorldSessionConfig config;
147
152
  config.appId = appId;
@@ -155,6 +160,13 @@ class PySession {
155
160
  config.actors.historySize = historySize;
156
161
  config.chunks.writeBackIntervalMs = 0; // durable write-back is the facade's
157
162
  config.chunks.voxelSendDistance = distance_arg(voxelSendDistance);
163
+ // The facade loads, re-reads and catches up itself; its staged source answers inline.
164
+ config.chunks.ioThread = false;
165
+ config.chunks.reloadReplacedChunks = false;
166
+ config.chunks.catchUpOnReconnect = false;
167
+ config.chunks.maxEditsInFlight = maxEditsInFlight;
168
+ config.chunks.maxEditsPerSecond = maxEditsPerSecond;
169
+ config.chunks.editTimeoutMs = editTimeoutMs;
158
170
  config.hostHeartbeatIntervalMs = 0; // host election is the facade's
159
171
  config.reapIntervalMs = reapIntervalMs;
160
172
  auto forward = [this](const replication::SpatialNotification& n) {
@@ -178,6 +190,13 @@ class PySession {
178
190
  e.a = reason;
179
191
  events_.push_back(std::move(e));
180
192
  };
193
+ // The same row the connection's own handler gives, so `chunk_changed` reaches subscribers
194
+ // whether or not a session is attached.
195
+ config.onChunkChanged = [this, app = std::strtoll(appId.c_str(), nullptr, 10)](
196
+ const wire::ChunkCoord& chunk, std::int64_t updatedAtMs) {
197
+ conn_.rowsLocked().push(static_cast<std::uint8_t>(wire::MessageType::ChunkChangedNotification),
198
+ app, chunk, nullptr, 0, 0, {updatedAtMs, 0, 0, 0}, {});
199
+ };
181
200
  {
182
201
  std::lock_guard lock(conn_.consumerMutex());
183
202
  session::WorldSessionServices services;
@@ -187,6 +206,20 @@ class PySession {
187
206
  }
188
207
  conn_.attachSession(true);
189
208
  watchLane("");
209
+ session_->chunks().onEditRefused([this](const session::EditOutcome& o) {
210
+ SessionEvent e;
211
+ e.kind = SessionEvent::kEditRefused;
212
+ e.hasUuid = false;
213
+ e.chunk = o.coord;
214
+ e.a = (static_cast<std::int64_t>(static_cast<std::uint16_t>(o.x)) << 32) |
215
+ (static_cast<std::int64_t>(static_cast<std::uint16_t>(o.y)) << 16) |
216
+ static_cast<std::int64_t>(static_cast<std::uint16_t>(o.z));
217
+ e.b = o.voxelType;
218
+ e.c = static_cast<std::int64_t>(o.result) | (o.restored ? 1 << 8 : 0) |
219
+ (static_cast<std::int64_t>(o.errorCode) << 16);
220
+ e.epochMs = static_cast<std::int64_t>(o.editId);
221
+ events_.push_back(std::move(e));
222
+ });
190
223
  session_->chunks().onChunkChanged([this](const session::ChunkData& chunk) {
191
224
  if (!watchChunks_) return;
192
225
  SessionEvent e;
@@ -457,14 +490,15 @@ class PySession {
457
490
  const session::ChunkData* c = live().chunks().find(coord_of(x, y, z));
458
491
  if (!c) return std::nullopt;
459
492
  nb::dict states;
460
- for (const auto& [index, state] : c->voxelStates)
493
+ c->forEachState([&](int index, const session::VoxelStateView& state) {
461
494
  states[nb::int_(index)] = nb::make_tuple(state.voxelType, blob(state.state));
495
+ });
462
496
  nb::list overlay;
463
- for (const auto& [key, wide] : c->overlay)
464
- overlay.append(
465
- nb::make_tuple(wide.x, wide.y, wide.z, wide.voxel.voxelType, blob(wide.voxel.state)));
497
+ c->forEachOverlay([&](const session::OverlayVoxel& wide) {
498
+ overlay.append(nb::make_tuple(wide.x, wide.y, wide.z, wide.voxelType, blob(wide.state)));
499
+ });
466
500
  return nb::make_tuple(
467
- nb::bytes(reinterpret_cast<const char*>(c->voxels.data()), c->voxels.size()), states,
501
+ nb::bytes(reinterpret_cast<const char*>(c->grid()), session::kChunkVolume), states,
468
502
  c->hydratedAtMs, overlay);
469
503
  }
470
504
 
@@ -512,25 +546,40 @@ class PySession {
512
546
  std::optional<nb::tuple> voxelStateAt(std::int64_t x, std::int64_t y, std::int64_t z, int vx,
513
547
  int vy, int vz) {
514
548
  std::lock_guard lock(conn_.consumerMutex());
515
- const session::VoxelState* s = live().chunks().voxelStateAt(coord_of(x, y, z), vx, vy, vz);
549
+ const auto s = live().chunks().voxelStateAt(coord_of(x, y, z), vx, vy, vz);
516
550
  if (!s) return std::nullopt;
517
551
  return nb::make_tuple(s->voxelType, blob(s->state));
518
552
  }
519
553
 
520
- int setVoxel(std::int64_t x, std::int64_t y, std::int64_t z, int vx, int vy, int vz,
521
- int voxelType, nb::handle state, bool optimistic) {
554
+ /// Returns (edit id, the sequence number it went out with, or -1 while it waits its turn).
555
+ nb::tuple setVoxel(std::int64_t x, std::int64_t y, std::int64_t z, int vx, int vy, int vz,
556
+ int voxelType, nb::handle state, bool optimistic) {
522
557
  BufferView body(state);
523
558
  const std::int16_t type = i16_arg(voxelType, "voxel type");
524
- Result<std::uint8_t> result = Errc::InvalidArgument;
559
+ Result<std::uint64_t> result = Errc::InvalidArgument;
560
+ int sequence = -1;
525
561
  {
526
562
  nb::gil_scoped_release release;
527
563
  std::lock_guard lock(conn_.consumerMutex());
528
564
  auto& s = live();
529
565
  result = s.chunks().setVoxel(coord_of(x, y, z), vx, vy, vz, type, body.bytes(), s.actorUuid(),
530
566
  optimistic);
531
- if (result.ok()) s.errors().recordSend(result.value(), session::SendKind::VoxelUpdate, s.actorUuid());
567
+ if (result.ok()) {
568
+ if (auto seq = s.chunks().sequenceOf(result.value())) sequence = *seq;
569
+ }
532
570
  }
533
- return sent(result, "setVoxel");
571
+ if (!result.ok()) raise(result.error(), "setVoxel");
572
+ return nb::make_tuple(result.value(), sequence);
573
+ }
574
+
575
+ std::size_t editsInFlight() {
576
+ std::lock_guard lock(conn_.consumerMutex());
577
+ return live().chunks().editsInFlight();
578
+ }
579
+
580
+ std::size_t queuedEdits() {
581
+ std::lock_guard lock(conn_.consumerMutex());
582
+ return live().chunks().queuedEdits();
534
583
  }
535
584
 
536
585
  /// Insert a chunk the facade loaded from the durable store, or generated.
@@ -729,6 +778,7 @@ void register_session(nb::module_& m) {
729
778
  m.attr("DIRECT_MESSAGE") = static_cast<int>(SessionEvent::kDirectMessage);
730
779
  m.attr("EVENT") = static_cast<int>(SessionEvent::kEvent);
731
780
  m.attr("ACTOR_LEFT") = static_cast<int>(SessionEvent::kActorLeft);
781
+ m.attr("EDIT_REFUSED") = static_cast<int>(SessionEvent::kEditRefused);
732
782
  m.attr("MAX_STATE_BYTES") = session::kMaxStateBytes;
733
783
  m.attr("CHUNK_VOLUME") = session::kChunkVolume;
734
784
 
@@ -755,13 +805,15 @@ void register_session(nb::module_& m) {
755
805
 
756
806
  nb::class_<PySession>(m, "WorldSession")
757
807
  .def(nb::init<PyConnection&, const std::string&, const std::string&, int, std::int64_t,
758
- std::int64_t, int, int, std::int64_t, int, std::int64_t, int>(),
808
+ std::int64_t, int, int, std::int64_t, int, std::int64_t, int, int, int,
809
+ std::int64_t>(),
759
810
  nb::arg("connection"), nb::arg("app_id"), nb::arg("actor_uuid") = "",
760
811
  nb::arg("send_hz") = 5, nb::arg("keyframe_interval_ms") = 3000,
761
812
  nb::arg("heartbeat_interval_ms") = 2000, nb::arg("distance") = 8, nb::arg("decay") = 1,
762
813
  nb::arg("stale_after_ms") = 12000, nb::arg("history_size") = 2,
763
814
  nb::arg("reap_interval_ms") = 1000, nb::arg("voxel_send_distance") = 8,
764
- nb::keep_alive<1, 2>())
815
+ nb::arg("max_edits_in_flight") = 128, nb::arg("max_edits_per_second") = 250,
816
+ nb::arg("edit_timeout_ms") = 10000, nb::keep_alive<1, 2>())
765
817
  .def("close", &PySession::close)
766
818
  .def("tick", &PySession::tick)
767
819
  .def("drain_events", &PySession::drainEvents)
@@ -808,6 +860,8 @@ void register_session(nb::module_& m) {
808
860
  nb::arg("distance"))
809
861
  .def("chunk_revision", &PySession::chunkRevision)
810
862
  .def("chunk_count", &PySession::chunkCount)
863
+ .def("edits_in_flight", &PySession::editsInFlight)
864
+ .def("queued_edits", &PySession::queuedEdits)
811
865
  .def("recent_errors", &PySession::recentErrors, nb::arg("limit") = SIZE_MAX)
812
866
  .def("error_total", &PySession::errorTotal)
813
867
  .def("clear_errors", &PySession::clearErrors)
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "crowdypy"
7
- version = "0.28.0.dev1"
7
+ version = "0.30.0.dev1"
8
8
  description = "Official Python SDK for Crowded Kingdoms: typed GraphQL clients and a native UDP replication core"
9
9
  readme = "README.md"
10
10
  license = "MIT AND Apache-2.0"
@@ -119,19 +119,19 @@ environment = { OPENSSL_ROOT_DIR = "C:/vcpkg/installed/x64-windows-static-md" }
119
119
  # --------------------------------------------------------------------------------------
120
120
 
121
121
  [tool.crowdypy.crowdyjs]
122
- version = "18.28.0"
123
- commit = "bc8b2b0737c0caf1486358c721123fa72fc1b955"
122
+ version = "18.30.0"
123
+ commit = "4840d76029ffb15a6de6232dab9336f2e9ab6514"
124
124
 
125
125
  [tool.crowdypy.crowdycpp]
126
- version = "0.80.0"
127
- tag = "dev/v0.80.0"
128
- commit = "d0d95975d6a6bcf1e08c3fd1cbde4a8be433b062"
129
- tree-sha256 = "c59afbf19dbc517590ec3d98a018daae8d583125a6dcc135055e172c16b753d6"
126
+ version = "0.82.0"
127
+ tag = "dev/v0.82.0"
128
+ commit = "c6875412bcea97120b4540b80d9b34504c29acf9"
129
+ tree-sha256 = "44dca0b0bd34d575808e5bf7a1ca6944ce779a790b9187894761541623a0f3ec"
130
130
 
131
131
  # schema.gql and operations/ are CrowdyJS's, copied from the commit pinned above by
132
132
  # scripts/schema_sync.py, which records these hashes and re-derives them in CI.
133
133
  [tool.crowdypy.graphql]
134
- schema-sha256 = "77a5f321148142940ecc2f1d0b52a0b30d4e3d5918db5b19d1e978f688cd0c0c"
134
+ schema-sha256 = "60a0a7a81bd90cb0b5decd62dc58736d037e61043a64f93b6f94a35311f0c7a1"
135
135
  operations-sha256 = "f2d61b107673668b345b29551c1979bbf93e34d5122c68cbd8a0d63ac59c25f9"
136
136
 
137
137
  # The SDL the docs site publishes. scripts/schema_drift.py compares the snapshot against it
@@ -14019,7 +14019,7 @@ type Subscription {
14019
14019
  """
14020
14020
  All game-server messages delivered over the UDP proxy as GraphQL payloads. Subscribe to udpNotifications before or with sending mutations so responses and GenericErrorResponse (correlate via sequenceNumber) are not missed. NOTE: the ActorUpdateResponse and VoxelUpdateResponse members are LEGACY and never emitted (applied updates arrive as your own *Notification self-echo; failures as GenericErrorResponse) — they remain in the union for backward compatibility and will be removed in a future major version.
14021
14021
  """
14022
- union UdpNotification = ActorUpdateResponse | ActorUpdateNotification | VoxelUpdateResponse | VoxelUpdateNotification | ClientAudioNotification | ClientVideoNotification | ActorLeftNotification | ClientTextNotification | ClientEventNotification | ServerEventNotification | SingleActorMessageNotification | ChannelMessageNotification | ChannelAudioNotification | GenericErrorResponse | RealtimeConnectionEvent
14022
+ union UdpNotification = ActorUpdateResponse | ActorUpdateNotification | VoxelUpdateResponse | VoxelUpdateNotification | ClientAudioNotification | ClientVideoNotification | ActorLeftNotification | ChunkChangedNotification | ClientTextNotification | ClientEventNotification | ServerEventNotification | SingleActorMessageNotification | ChannelMessageNotification | ChannelAudioNotification | GenericErrorResponse | RealtimeConnectionEvent
14023
14023
 
14024
14024
  """
14025
14025
  LEGACY — never emitted. The game server retired the dedicated actor-update response opcode (129); an applied update now arrives as your own ActorUpdateNotification (the sender is included in the chunk fan-out) and failures arrive as GenericErrorResponse. This type remains in the UdpNotification union for backward compatibility only — do not select it in new code; it will be removed in a future major version.
@@ -14219,6 +14219,28 @@ type ActorLeftNotification {
14219
14219
  epochMillis: BigInt!
14220
14220
  }
14221
14221
 
14222
+ """
14223
+ A chunk near you was replaced as a whole (a hub's or mod's world.set_chunk; Buddy v0.45.0): read it again with getChunk, or getChunksByDistance with since. It comes instead of a voxel update per voxel. Received via the udpNotifications subscription.
14224
+ """
14225
+ type ChunkChangedNotification {
14226
+ """The ID of the app the chunk is in."""
14227
+ appId: BigInt!
14228
+ """The X coordinate of the replaced chunk."""
14229
+ chunkX: BigInt!
14230
+ """The Y coordinate of the replaced chunk."""
14231
+ chunkY: BigInt!
14232
+ """The Z coordinate of the replaced chunk."""
14233
+ chunkZ: BigInt!
14234
+ """Chunk replication distance (0-8) the notification was fanned out over."""
14235
+ distance: Int!
14236
+ """
14237
+ The stored chunk's new updatedAt, in epoch milliseconds: a copy at least this new is current.
14238
+ """
14239
+ updatedAtMs: BigInt!
14240
+ """Correlation byte from the datagram tail (always 0 today)."""
14241
+ sequenceNumber: Int!
14242
+ }
14243
+
14222
14244
  """
14223
14245
  Notification received when another client sends a text message (chat). Received via the udpNotifications subscription.
14224
14246
  """
@@ -1,6 +1,6 @@
1
1
  """GENERATED by scripts/codegen.py from schema.gql. Do not edit.
2
2
 
3
- schema.gql sha256: 77a5f321148142940ecc2f1d0b52a0b30d4e3d5918db5b19d1e978f688cd0c0c
3
+ schema.gql sha256: 60a0a7a81bd90cb0b5decd62dc58736d037e61043a64f93b6f94a35311f0c7a1
4
4
  """
5
5
 
6
6
  from enum import StrEnum
@@ -4,7 +4,7 @@ Every GraphQL input object as a msgspec Struct. Attributes are snake_case and en
4
4
  under their GraphQL names; an attribute left at UNSET is omitted from the request,
5
5
  which is how the API tells 'not provided' from an explicit null.
6
6
 
7
- schema.gql sha256: 77a5f321148142940ecc2f1d0b52a0b30d4e3d5918db5b19d1e978f688cd0c0c
7
+ schema.gql sha256: 60a0a7a81bd90cb0b5decd62dc58736d037e61043a64f93b6f94a35311f0c7a1
8
8
  """
9
9
 
10
10
  from __future__ import annotations
@@ -1,6 +1,6 @@
1
1
  """GENERATED by scripts/codegen.py from schema.gql and operations/. Do not edit.
2
2
 
3
- schema.gql sha256: 77a5f321148142940ecc2f1d0b52a0b30d4e3d5918db5b19d1e978f688cd0c0c
3
+ schema.gql sha256: 60a0a7a81bd90cb0b5decd62dc58736d037e61043a64f93b6f94a35311f0c7a1
4
4
  operations/ sha256: f2d61b107673668b345b29551c1979bbf93e34d5122c68cbd8a0d63ac59c25f9
5
5
  """
6
6