crowdypy 0.6.0.dev1__tar.gz → 0.8.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 (510) hide show
  1. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/AGENTS.md +22 -1
  2. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/CMakeLists.txt +1 -0
  3. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/MIGRATION.md +131 -0
  4. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/PKG-INFO +72 -9
  5. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/README.md +71 -8
  6. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/benchmarks/README.md +20 -0
  7. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/docs/compatibility.md +10 -1
  8. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/docs/e2e-coverage.md +9 -0
  9. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/docs/parity-matrix.md +69 -5
  10. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/common.hpp +1 -0
  11. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/module.cpp +3 -2
  12. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/replication.hpp +25 -5
  13. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/replication_binding.cpp +2 -0
  14. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/session_binding.cpp +90 -7
  15. crowdypy-0.8.0.dev1/native/voice_binding.cpp +177 -0
  16. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/native/wire_binding.cpp +23 -5
  17. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/AppUserAccessByApp.graphql +2 -0
  18. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/ClaimFreeAppAccess.graphql +1 -0
  19. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/GrantAppAccess.graphql +1 -0
  20. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/GrantMyAppAccess.graphql +1 -0
  21. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/MyAppAccess.graphql +1 -0
  22. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/RevokeAppAccess.graphql +1 -0
  23. crowdypy-0.8.0.dev1/operations/appAccess/SuspendAppAccess.graphql +45 -0
  24. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/App.graphql +2 -0
  25. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/AppBySlug.graphql +1 -0
  26. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/AppsForOrg.graphql +1 -0
  27. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/CreateApp.graphql +1 -0
  28. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/MyApps.graphql +1 -0
  29. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/UpdateApp.graphql +2 -0
  30. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/GetChunk.graphql +1 -0
  31. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/GetChunksByDistance.graphql +1 -0
  32. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/exec/Exec.graphql +13 -0
  33. crowdypy-0.8.0.dev1/operations/inputLog/InputLogMessages.graphql +43 -0
  34. crowdypy-0.8.0.dev1/operations/inputLog/InputLogSessions.graphql +32 -0
  35. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/serverStatus/GameClientBootstrap.graphql +5 -0
  36. crowdypy-0.8.0.dev1/operations/users/PlayerProfile.graphql +15 -0
  37. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/pyproject.toml +11 -9
  38. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/schema.gql +792 -66
  39. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/__init__.py +56 -0
  40. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_generated/enums.py +33 -1
  41. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_generated/inputs.py +43 -6
  42. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_generated/operations.py +93 -21
  43. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/client.py +2 -0
  44. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/app_access.py +60 -2
  45. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/apps.py +4 -1
  46. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/channels.py +3 -1
  47. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/chunks.py +6 -2
  48. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/exec.py +16 -1
  49. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/grids.py +2 -1
  50. crowdypy-0.8.0.dev1/src/crowdypy/_sync/domains/input_log.py +80 -0
  51. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/portal.py +6 -2
  52. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/server_status.py +7 -1
  53. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/udp.py +13 -0
  54. crowdypy-0.8.0.dev1/src/crowdypy/_sync/domains/users.py +75 -0
  55. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/grid_scope.py +10 -0
  56. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/stores.py +123 -43
  57. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_version.py +1 -1
  58. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/client.py +2 -0
  59. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/app_access.py +60 -2
  60. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/apps.py +4 -1
  61. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/channels.py +3 -1
  62. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/chunks.py +6 -2
  63. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/exec.py +37 -1
  64. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/grids.py +2 -1
  65. crowdypy-0.8.0.dev1/src/crowdypy/domains/input_log.py +79 -0
  66. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/portal.py +19 -1
  67. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/server_status.py +7 -1
  68. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/udp.py +13 -0
  69. crowdypy-0.8.0.dev1/src/crowdypy/domains/users.py +74 -0
  70. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/errors.py +114 -0
  71. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/grid_scope.py +10 -0
  72. crowdypy-0.8.0.dev1/src/crowdypy/media.py +527 -0
  73. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/schemas.v1.json +2 -2
  74. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/replication.py +34 -4
  75. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/stores.py +138 -43
  76. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/wire.py +70 -1
  77. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/conftest.py +46 -0
  78. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/fixtures/README.md +1 -0
  79. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/fixtures/player-host.v1.json +2 -2
  80. crowdypy-0.8.0.dev1/tests/fixtures/voice-frames.json +941 -0
  81. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/test_org_domains.py +49 -0
  82. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/test_studio_exec_domains.py +20 -1
  83. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/test_world_domains.py +21 -0
  84. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_durable_stores.py +64 -0
  85. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_fixture_provenance.py +5 -5
  86. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_grid_scope.py +4 -0
  87. crowdypy-0.8.0.dev1/tests/unit/test_refusals.py +155 -0
  88. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_replication.py +80 -0
  89. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_sdk_audience.py +6 -0
  90. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_udp_api.py +50 -1
  91. crowdypy-0.8.0.dev1/tests/unit/test_voice_frames.py +284 -0
  92. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_wire.py +77 -0
  93. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_world_session.py +172 -1
  94. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tools/e2e/provision.py +32 -1
  95. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tools/parity/classifications.toml +17 -0
  96. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/uv.lock +1 -1
  97. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/CMakeLists.txt +35 -1
  98. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/PROVENANCE.md +1 -1
  99. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/cmake/CrowdyCPPConfig.cmake.in +26 -0
  100. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/cmake/CrowdyFindOpus.cmake +36 -0
  101. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/client.hpp +3 -0
  102. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/admin.hpp +58 -0
  103. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/exec.hpp +10 -2
  104. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/grids.hpp +16 -5
  105. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/groups.hpp +4 -0
  106. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/portal.hpp +7 -7
  107. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/types.hpp +27 -0
  108. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/include/crowdy/domains/users.hpp +154 -0
  109. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/world_data.hpp +70 -0
  110. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/enums.hpp +90 -2
  111. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/operations.hpp +371 -2
  112. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/errors.hpp +68 -0
  113. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/include/crowdy/media/opus.hpp +90 -0
  114. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/include/crowdy/media/voice_frames.hpp +470 -0
  115. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/connection.hpp +13 -0
  116. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/types.hpp +3 -0
  117. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/chunk_store.hpp +201 -29
  118. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/stores.hpp +3 -0
  119. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/world_session.hpp +13 -0
  120. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/codec.hpp +27 -4
  121. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/protocol.hpp +14 -0
  122. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/package.json +6 -6
  123. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/client.cpp +2 -0
  124. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/domains/exec.cpp +14 -0
  125. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/error_extensions.hpp +4 -0
  126. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/src/media/opus.cpp +119 -0
  127. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/replication/connection.cpp +22 -7
  128. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/session/world_session.cpp +6 -10
  129. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdy-studio-diagnostics.v1.json +2 -2
  130. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdyjs-studio-layout.v1.json +2 -2
  131. crowdypy-0.8.0.dev1/vendor/CrowdyCPP/tools/parity/fixtures/voice-frames.json +941 -0
  132. crowdypy-0.6.0.dev1/src/crowdypy/_sync/domains/users.py +0 -45
  133. crowdypy-0.6.0.dev1/src/crowdypy/domains/users.py +0 -44
  134. crowdypy-0.6.0.dev1/src/crowdypy/media.py +0 -140
  135. crowdypy-0.6.0.dev1/vendor/CrowdyCPP/cmake/CrowdyCPPConfig.cmake.in +0 -15
  136. crowdypy-0.6.0.dev1/vendor/CrowdyCPP/include/crowdy/domains/users.hpp +0 -83
  137. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/.gitattributes +0 -0
  138. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/.gitignore +0 -0
  139. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/.gitleaks.toml +0 -0
  140. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/LICENSE +0 -0
  141. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/SECURITY.md +0 -0
  142. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/benchmarks/bench_replication.py +0 -0
  143. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/licenses/OpenSSL-LICENSE.txt +0 -0
  144. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/Actor.graphql +0 -0
  145. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/Actors.graphql +0 -0
  146. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/BatchLookupActors.graphql +0 -0
  147. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/CreateActor.graphql +0 -0
  148. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/DeleteActor.graphql +0 -0
  149. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/UpdateActor.graphql +0 -0
  150. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/actors/UpdateActorState.graphql +0 -0
  151. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/AppAccessTiers.graphql +0 -0
  152. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/AppFeatures.graphql +0 -0
  153. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/AppGrantMemberCandidates.graphql +0 -0
  154. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/ArchiveAccessTier.graphql +0 -0
  155. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/CreateAccessTier.graphql +0 -0
  156. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/DefineAppFeature.graphql +0 -0
  157. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/GrantTierFeature.graphql +0 -0
  158. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/RevokeTierFeature.graphql +0 -0
  159. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/RuntimePermissions.graphql +0 -0
  160. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/TierFeatures.graphql +0 -0
  161. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/appAccess/UpdateAccessTier.graphql +0 -0
  162. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/AppDiscovery.graphql +0 -0
  163. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/ArchiveApp.graphql +0 -0
  164. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/CodeAdmissions.graphql +0 -0
  165. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/MarketplaceApps.graphql +0 -0
  166. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/apps/PlaceableDatacenters.graphql +0 -0
  167. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/auth/Logout.graphql +0 -0
  168. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/auth/LogoutAllDevices.graphql +0 -0
  169. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/avatars/Avatars.graphql +0 -0
  170. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/billing/AppBudget.graphql +0 -0
  171. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/billing/AppBudgets.graphql +0 -0
  172. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/billing/SetAppBudget.graphql +0 -0
  173. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/billing/WalletBalance.graphql +0 -0
  174. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/billing/WalletTransactions.graphql +0 -0
  175. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/AddChannelMember.graphql +0 -0
  176. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/Channel.graphql +0 -0
  177. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/ChannelMembers.graphql +0 -0
  178. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/ChannelPolicy.graphql +0 -0
  179. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/ChannelRoles.graphql +0 -0
  180. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/Channels.graphql +0 -0
  181. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/CreateChannel.graphql +0 -0
  182. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/CreateChannelRole.graphql +0 -0
  183. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/DeleteChannel.graphql +0 -0
  184. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/DeleteChannelRole.graphql +0 -0
  185. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/JoinChannel.graphql +0 -0
  186. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/LeaveChannel.graphql +0 -0
  187. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/MyChannels.graphql +0 -0
  188. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/RemoveChannelMember.graphql +0 -0
  189. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/RequestToJoinChannel.graphql +0 -0
  190. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/SetChannelMemberRoles.graphql +0 -0
  191. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/SetChannelPolicy.graphql +0 -0
  192. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/UpdateChannel.graphql +0 -0
  193. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/channels/UpdateChannelRole.graphql +0 -0
  194. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/GetChunkLods.graphql +0 -0
  195. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/GetVoxelList.graphql +0 -0
  196. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/UpdateChunk.graphql +0 -0
  197. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/UpdateChunkLods.graphql +0 -0
  198. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/chunks/UpdateChunkState.graphql +0 -0
  199. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/crowdyStudio/CrowdyStudio.graphql +0 -0
  200. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/gameApps/GameApps.graphql +0 -0
  201. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/grids/CreateGridChannel.graphql +0 -0
  202. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/grids/GridChannels.graphql +0 -0
  203. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/grids/MintGridToken.graphql +0 -0
  204. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/host/Host.graphql +0 -0
  205. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/marketplace/Marketplace.graphql +0 -0
  206. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/CreateOrgRole.graphql +0 -0
  207. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/CreateOrgToken.graphql +0 -0
  208. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/CreateOrganization.graphql +0 -0
  209. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/DeleteOrgRole.graphql +0 -0
  210. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/InviteOrgMember.graphql +0 -0
  211. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/MemberRoles.graphql +0 -0
  212. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/MyOrganizations.graphql +0 -0
  213. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/OrgMembers.graphql +0 -0
  214. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/OrgPermissions.graphql +0 -0
  215. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/OrgRoles.graphql +0 -0
  216. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/OrgTokens.graphql +0 -0
  217. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/Organization.graphql +0 -0
  218. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/OrganizationBySlug.graphql +0 -0
  219. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/RemoveOrgMember.graphql +0 -0
  220. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/RevokeOrgToken.graphql +0 -0
  221. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/UpdateOrgMemberRoles.graphql +0 -0
  222. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/UpdateOrgRole.graphql +0 -0
  223. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/organizations/UpdateOrgToken.graphql +0 -0
  224. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/payments/CapturePaypalCheckout.graphql +0 -0
  225. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/payments/CreateCheckout.graphql +0 -0
  226. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/payments/MyCheckouts.graphql +0 -0
  227. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/platform/PlatformConfig.graphql +0 -0
  228. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/playerWallet/PlayerWallet.graphql +0 -0
  229. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/quotas/DeleteQuota.graphql +0 -0
  230. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/quotas/EffectiveQuota.graphql +0 -0
  231. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/quotas/QuotasForApp.graphql +0 -0
  232. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/quotas/QuotasForOrg.graphql +0 -0
  233. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/quotas/SetQuota.graphql +0 -0
  234. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/serverStatus/ActiveGraphQLServers.graphql +0 -0
  235. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/serverStatus/GraphqlServers.graphql +0 -0
  236. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/serverStatus/ServerWithLeastClients.graphql +0 -0
  237. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/serverStatus/VersionInfo.graphql +0 -0
  238. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/sharedEnvironment/SharedEnvironment.graphql +0 -0
  239. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/state/DeleteUserAppState.graphql +0 -0
  240. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/state/UpdateUserAppState.graphql +0 -0
  241. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/state/UserAppState.graphql +0 -0
  242. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/state/UserAppStates.graphql +0 -0
  243. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/AddTeamMember.graphql +0 -0
  244. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/CreateTeam.graphql +0 -0
  245. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/CreateTeamRole.graphql +0 -0
  246. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/DeleteTeam.graphql +0 -0
  247. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/DeleteTeamRole.graphql +0 -0
  248. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/JoinTeam.graphql +0 -0
  249. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/LeaveTeam.graphql +0 -0
  250. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/MyTeams.graphql +0 -0
  251. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/RemoveTeamMember.graphql +0 -0
  252. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/RequestToJoinTeam.graphql +0 -0
  253. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/SetTeamMemberRoles.graphql +0 -0
  254. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/SetTeamPolicy.graphql +0 -0
  255. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/Team.graphql +0 -0
  256. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/TeamMembers.graphql +0 -0
  257. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/TeamPolicy.graphql +0 -0
  258. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/TeamRoles.graphql +0 -0
  259. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/Teams.graphql +0 -0
  260. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/UpdateTeam.graphql +0 -0
  261. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teams/UpdateTeamRole.graphql +0 -0
  262. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/teleport/TeleportRequest.graphql +0 -0
  263. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/usage/AppGraphqlOperations.graphql +0 -0
  264. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/usage/AppUsageSummary.graphql +0 -0
  265. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/usage/PlayerPulse.graphql +0 -0
  266. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/DeleteMyAccount.graphql +0 -0
  267. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/FreePlayWindow.graphql +0 -0
  268. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/Me.graphql +0 -0
  269. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/UpdateGamertag.graphql +0 -0
  270. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/UpdateUserState.graphql +0 -0
  271. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/users/User.graphql +0 -0
  272. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/voxels/ListVoxelUpdatesByDistance.graphql +0 -0
  273. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/voxels/ListVoxels.graphql +0 -0
  274. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/voxels/RollbackVoxelUpdates.graphql +0 -0
  275. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/voxels/UpdateVoxel.graphql +0 -0
  276. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/operations/voxels/VoxelUpdateHistory.graphql +0 -0
  277. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/_pins.py +0 -0
  278. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/assert_default_origin.py +0 -0
  279. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/build_openssl.sh +0 -0
  280. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/check_content_policy.py +0 -0
  281. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/check_pin_tiers.py +0 -0
  282. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/cibw_before_all_linux.sh +0 -0
  283. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/resolve-release-tier.sh +0 -0
  284. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/resolve-release-tier.test.sh +0 -0
  285. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/resolve_pypi_version.py +0 -0
  286. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/stamp_version.py +0 -0
  287. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/ci/verify_artifacts.py +0 -0
  288. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/codegen.py +0 -0
  289. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/schema_drift.py +0 -0
  290. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/schema_sync.py +0 -0
  291. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/unasync.py +0 -0
  292. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/scripts/vendor_crowdycpp.py +0 -0
  293. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_concurrency.py +0 -0
  294. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_default_origin.py +0 -0
  295. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_generated/__init__.py +0 -0
  296. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_grid.py +0 -0
  297. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_native.pyi +0 -0
  298. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_operation.py +0 -0
  299. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/__init__.py +0 -0
  300. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/__init__.py +0 -0
  301. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/_base.py +0 -0
  302. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/actors.py +0 -0
  303. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/admin.py +0 -0
  304. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/auth.py +0 -0
  305. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/avatars.py +0 -0
  306. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/billing.py +0 -0
  307. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio.py +0 -0
  308. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_agent.py +0 -0
  309. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_github.py +0 -0
  310. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/discovery.py +0 -0
  311. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/game_apps.py +0 -0
  312. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/host.py +0 -0
  313. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/marketplace.py +0 -0
  314. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/organizations.py +0 -0
  315. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/payments.py +0 -0
  316. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/platform.py +0 -0
  317. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/player_wallet.py +0 -0
  318. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/quotas.py +0 -0
  319. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/shared_environment.py +0 -0
  320. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/state.py +0 -0
  321. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/teams.py +0 -0
  322. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/teleport.py +0 -0
  323. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/usage.py +0 -0
  324. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/domains/voxels.py +0 -0
  325. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/graphql.py +0 -0
  326. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/kit/__init__.py +0 -0
  327. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/kit/actions.py +0 -0
  328. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/kit/kit.py +0 -0
  329. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/kit/social.py +0 -0
  330. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/kit/wire.py +0 -0
  331. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/rediscover.py +0 -0
  332. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/_sync/world.py +0 -0
  333. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/auth_state.py +0 -0
  334. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/codecs.py +0 -0
  335. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/datacenter_redirect.py +0 -0
  336. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/__init__.py +0 -0
  337. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/_base.py +0 -0
  338. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/actors.py +0 -0
  339. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/admin.py +0 -0
  340. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/auth.py +0 -0
  341. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/avatars.py +0 -0
  342. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/billing.py +0 -0
  343. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/crowdy_studio.py +0 -0
  344. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/crowdy_studio_agent.py +0 -0
  345. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/crowdy_studio_github.py +0 -0
  346. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/discovery.py +0 -0
  347. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/game_apps.py +0 -0
  348. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/host.py +0 -0
  349. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/marketplace.py +0 -0
  350. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/organizations.py +0 -0
  351. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/payments.py +0 -0
  352. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/platform.py +0 -0
  353. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/player_wallet.py +0 -0
  354. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/quotas.py +0 -0
  355. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/shared_environment.py +0 -0
  356. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/state.py +0 -0
  357. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/teams.py +0 -0
  358. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/teleport.py +0 -0
  359. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/usage.py +0 -0
  360. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/domains/voxels.py +0 -0
  361. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/enums.py +0 -0
  362. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/estate.py +0 -0
  363. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/exec_gateway.py +0 -0
  364. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/graphql.py +0 -0
  365. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/inputs.py +0 -0
  366. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/kit/__init__.py +0 -0
  367. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/kit/actions.py +0 -0
  368. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/kit/kit.py +0 -0
  369. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/kit/social.py +0 -0
  370. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/kit/wire.py +0 -0
  371. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/lb_cookie.py +0 -0
  372. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/pkce.py +0 -0
  373. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/__init__.py +0 -0
  374. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/agent_errors.py +0 -0
  375. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/agent_types.py +0 -0
  376. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/json_schema.py +0 -0
  377. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/schemas.py +0 -0
  378. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/player_host/types.py +0 -0
  379. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/py.typed +0 -0
  380. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/rediscover.py +0 -0
  381. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/session.py +0 -0
  382. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/__init__.py +0 -0
  383. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/client_tick_interval.py +0 -0
  384. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/controller.py +0 -0
  385. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/diagnostics.py +0 -0
  386. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/github_new_repo.py +0 -0
  387. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/layout.py +0 -0
  388. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/models.py +0 -0
  389. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/studio/starter_projects.py +0 -0
  390. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/subscriptions.py +0 -0
  391. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/sync.py +0 -0
  392. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/utils.py +0 -0
  393. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/src/crowdypy/world.py +0 -0
  394. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/conftest.py +0 -0
  395. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/__init__.py +0 -0
  396. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_identity.py +0 -0
  397. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_open_grid_exec_gateway.py +0 -0
  398. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_ranged_channel.py +0 -0
  399. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_replication.py +0 -0
  400. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_studio.py +0 -0
  401. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_world.py +0 -0
  402. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/e2e/test_e2e_world_data.py +0 -0
  403. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/fixtures/binary-wire-fixtures.json +0 -0
  404. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/fixtures/exec-client-frames.json +0 -0
  405. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/__init__.py +0 -0
  406. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/__init__.py +0 -0
  407. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/test_crowdycpp_roots.py +0 -0
  408. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/domains/test_social_domains.py +0 -0
  409. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_core.py +0 -0
  410. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_estate_moves.py +0 -0
  411. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_exec_gateway.py +0 -0
  412. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_kit.py +0 -0
  413. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_lazy_exports.py +0 -0
  414. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_player_host.py +0 -0
  415. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_release_versions.py +0 -0
  416. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_studio_controller.py +0 -0
  417. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_studio_diagnostics.py +0 -0
  418. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_studio_layout.py +0 -0
  419. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_subscriptions.py +0 -0
  420. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tests/unit/test_transport.py +0 -0
  421. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tools/fixtures/player_host.mjs +0 -0
  422. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/tools/parity/parity.py +0 -0
  423. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/LICENSE +0 -0
  424. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/cmake/CheckPublicHeaders.cmake +0 -0
  425. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/cmake/studio_layout_fixture.hpp.in +0 -0
  426. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/base64.hpp +0 -0
  427. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/bytes.hpp +0 -0
  428. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/clock.hpp +0 -0
  429. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/crypto.hpp +0 -0
  430. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/logger.hpp +0 -0
  431. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/result.hpp +0 -0
  432. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/spsc.hpp +0 -0
  433. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/uuid.hpp +0 -0
  434. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/crowdy.hpp +0 -0
  435. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/default_origin.hpp +0 -0
  436. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/auth.hpp +0 -0
  437. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio.hpp +0 -0
  438. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_agent.hpp +0 -0
  439. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_github.hpp +0 -0
  440. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/discovery.hpp +0 -0
  441. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/domain_base.hpp +0 -0
  442. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/game_apps.hpp +0 -0
  443. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/marketplace.hpp +0 -0
  444. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/player_wallet.hpp +0 -0
  445. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/realtime_control.hpp +0 -0
  446. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/server_status.hpp +0 -0
  447. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/async_scope.hpp +0 -0
  448. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/auth_state.hpp +0 -0
  449. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/datacenter_redirect.hpp +0 -0
  450. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/dispatcher.hpp +0 -0
  451. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/estate.hpp +0 -0
  452. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/graphql_client.hpp +0 -0
  453. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/http.hpp +0 -0
  454. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/json.hpp +0 -0
  455. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/rediscover.hpp +0 -0
  456. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/subscription_client.hpp +0 -0
  457. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/websocket.hpp +0 -0
  458. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/actions.hpp +0 -0
  459. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/kit.hpp +0 -0
  460. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/social.hpp +0 -0
  461. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/wire.hpp +0 -0
  462. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/video_frames.hpp +0 -0
  463. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/adapter.hpp +0 -0
  464. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/player_host.hpp +0 -0
  465. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/schemas.hpp +0 -0
  466. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/types.hpp +0 -0
  467. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/session_provider.hpp +0 -0
  468. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/udp_socket.hpp +0 -0
  469. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/codec.hpp +0 -0
  470. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/durable.hpp +0 -0
  471. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/keys.hpp +0 -0
  472. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/controller.hpp +0 -0
  473. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/diagnostics.hpp +0 -0
  474. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/editor.hpp +0 -0
  475. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github.hpp +0 -0
  476. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github_layout.hpp +0 -0
  477. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/integration.hpp +0 -0
  478. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/layout.hpp +0 -0
  479. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/models.hpp +0 -0
  480. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/runtime.hpp +0 -0
  481. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/include/crowdy/world.hpp +0 -0
  482. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/base64.cpp +0 -0
  483. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/clock.cpp +0 -0
  484. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/crypto_default_unavailable.cpp +0 -0
  485. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/crypto_openssl.cpp +0 -0
  486. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/crypto_unavailable.cpp +0 -0
  487. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/logger.cpp +0 -0
  488. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/core/uuid.cpp +0 -0
  489. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/async_transport.cpp +0 -0
  490. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/auth_state.cpp +0 -0
  491. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/errors.cpp +0 -0
  492. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/graphql_client.cpp +0 -0
  493. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/http_curl.cpp +0 -0
  494. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/http_none.cpp +0 -0
  495. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/json.cpp +0 -0
  496. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/subscription_client.cpp +0 -0
  497. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_curl.cpp +0 -0
  498. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_none.cpp +0 -0
  499. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/player_host/schemas.cpp +0 -0
  500. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/player_host/types.cpp +0 -0
  501. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/replication/socket_errors.hpp +0 -0
  502. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/replication/udp_socket.cpp +0 -0
  503. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/studio/diagnostics.cpp +0 -0
  504. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/studio/editor.cpp +0 -0
  505. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/src/studio/integration.cpp +0 -0
  506. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/LICENSE +0 -0
  507. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.c +0 -0
  508. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.h +0 -0
  509. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-client-frames.json +0 -0
  510. {crowdypy-0.6.0.dev1 → crowdypy-0.8.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-gateway-cases.json +0 -0
@@ -60,7 +60,9 @@ python tools/parity/parity.py --crowdyjs ../CrowdyJS --write docs/parity-matrix.
60
60
  ```
61
61
 
62
62
  then port what changed, refresh `tests/fixtures/` from the same commit, and classify or
63
- cover every new difference. Build CrowdyJS at the new pin (`npm ci && npm run build`) and run
63
+ cover every new difference. `tests/unit/test_fixture_provenance.py` holds each copied fixture
64
+ to its CrowdyJS source, and `exec-client-frames.json` and `voice-frames.json` to the vendored
65
+ CrowdyCPP copies too. Build CrowdyJS at the new pin (`npm ci && npm run build`) and run
64
66
  `node tools/fixtures/player_host.mjs ../CrowdyJS`: it rewrites the player-host schemas and
65
67
  their fixture, and `tests/unit/test_player_host.py` refuses either one from another commit. Moving the CrowdyCPP pin:
66
68
 
@@ -145,5 +147,24 @@ The replication system saturates the local network stack, so the binding
145
147
  - Sends are batched, and the GIL is released while a batch is encoded and sent.
146
148
  - An asyncio loop is woken through `Config::onEventsReady` and a socket pair, never by a
147
149
  sleep-poll.
150
+ - While a World Stores session is attached it owns the connection's handlers. What its stores
151
+ do not keep (audio, video, text, opcode 140, channel audio) is forwarded into the batch
152
+ rows; voxel updates are forwarded only once Python watches them (`watch_voxels`, set by
153
+ `session.on("voxel_update")`), since the chunk store already merges every one.
148
154
  - Every change to the hot path reruns `benchmarks/bench_replication.py` and CrowdyCPP's
149
155
  `bench_send` on the same machine, and updates `benchmarks/README.md`.
156
+
157
+ ## The native session and its chunk store
158
+
159
+ - The session is built without host election and with native write-back off. Both are
160
+ GraphQL work the Python facade does on its timers.
161
+ - Its chunk source, `StagedChunks` in `native/session_binding.cpp`, only applies what the
162
+ facade loaded. `ChunkStore.hydrate()` and `prune_beyond()` hand a chunk to it through
163
+ `WorldSession.hydrate`, so stored edits follow CrowdyCPP's overlay rules: an edit the
164
+ 16x16x16 one-byte grid cannot hold goes to `ChunkData::overlay`.
165
+ - Do not write voxel types or states into the dense grid from Python. That bypasses the
166
+ overlay, and the echo matching of local edits.
167
+ - The voice helpers (`native/voice_binding.cpp`) bind CrowdyCPP's `voice_frames.hpp`.
168
+ `crowdypy.media` checks every argument as CrowdyJS does first, because CrowdyCPP clamps the
169
+ options CrowdyJS refuses.
170
+ - `CROWDY_WITH_OPUS` stays `OFF` in `pyproject.toml`: the wheels link no audio codec.
@@ -59,6 +59,7 @@ nanobind_add_module(_native
59
59
  native/module.cpp
60
60
  native/replication_binding.cpp
61
61
  native/session_binding.cpp
62
+ native/voice_binding.cpp
62
63
  native/wire_binding.cpp
63
64
  )
64
65
  target_include_directories(_native PRIVATE native)
@@ -3,6 +3,137 @@
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.8.0
7
+
8
+ CrowdyJS 18.7.0 and CrowdyCPP 0.60.0. Additive, with reads that change for values they used to
9
+ get wrong (wide voxels) and one new floor: every token mutation (`portal.mint_app_token`,
10
+ `exchange_code`, `refresh`) selects `runtimeGate`, so 0.8.0 needs the ck-api release after
11
+ v2.39.0 that serves it; an older one refuses the selection. Channel audio and the echo of your
12
+ own voxel edits need replication server v0.37.0.
13
+
14
+ - **Voice helpers** (`crowdypy.media`), an optional convention for what an audio payload
15
+ carries: a 10-byte little-endian header in front of each codec frame (version 1, codec 0 raw,
16
+ 1 Opus 48 kHz mono or 2 G.711 µ-law 8 kHz, `u16` seq, `u32` timestamp in codec samples,
17
+ the frame's duration in ms, and the talk-spurt flags `VoiceFlag.SPURT_START` and
18
+ `SPURT_END`).
19
+ - `encode_voice_header(VoiceHeader(...))` and `encode_voice_packet(header, frame)` write it;
20
+ `decode_voice_packet(packet)` returns `None` for a packet shorter than 10 bytes or of
21
+ another version, and never raises on bytes from the network.
22
+ - `VoicePacketizer(codec, frame_ms, *, seq=0, timestamp=0)` numbers one sender's frames
23
+ across the seq and timestamp wraps (`packetize(frame, last=)`, `skip(frames)` for
24
+ silence).
25
+ - `VoiceJitterBuffer(target_delay_ms=60, max_frames=64, reset_after_ms=200)`:
26
+ `push(key, packet, now_ms)` answers `"buffered"`, `"late"`, `"duplicate"` or
27
+ `"malformed"`, and `pull(key, now_ms)` / `poll(now_ms)` return the due `VoicePlayout`s in
28
+ seq order, a gap (`frame` `None`) for each frame that never came.
29
+ - CrowdyCPP's implementation runs natively. Arguments are checked as CrowdyJS checks them, so
30
+ an option or field out of range raises `ValueError` where CrowdyCPP would clamp it.
31
+ - The helpers replay CrowdyJS's `voice-frames.json` byte for byte.
32
+ - No codec ships, and the wheel links none: which codec an app uses, and the library that
33
+ encodes it, is the app's choice.
34
+ - **Channel audio** (party and guild voice).
35
+ - `client.udp.send_channel_audio(channel_id, uuid, payload)` sends message type 35, the
36
+ channel message's layout and signing with its own type byte, at most 1,024 bytes. It needs
37
+ the channel's `send_voice` and the player's `use_voice_chat`; without them the server
38
+ answers `UNAUTHORIZED` for the returned sequence. The sender gets no echo.
39
+ - Members receive message type 36, standalone or bundled, on the new `channel_audio` handler
40
+ of `udp.subscribe` (`notification.channel_id`, the sender's `uuid`, `payload`).
41
+ - In the World Stores it is `session.on("channel_audio", ...)`; the channel inbox does not
42
+ get it. Key a jitter buffer by channel and sender, so one player in two channels is two
43
+ streams.
44
+ - `channels.create`, `grids.create_channel` and `GridScope.channels.create` take
45
+ `members_can_speak` (default false), which gives the member role `send_voice`.
46
+ `GridScope.channels.send_audio(channel_id, uuid, payload)` sends on the grid's channels.
47
+ - Underneath are `ReplicationConnection.send_channel_audio`, and
48
+ `crowdypy.wire.encode_channel_audio` and `ChannelAudioNotification` (from `parse_datagram`)
49
+ for a custom transport.
50
+ - **App-defined spatial messages** (`GENERIC_SPATIAL_1`, 140) reach
51
+ `session.on("generic_spatial", ...)` while a World Stores session is attached
52
+ (CrowdyCPP's `onGenericSpatial`). Without a session, `udp.subscribe`'s `generic_spatial`
53
+ already received them.
54
+ - **`session.on("voxel_update", ...)`** fires for every inbound voxel edit after
55
+ `session.chunks` merged it, with its sender, voxel and state: CrowdyCPP's `onVoxel`, for a
56
+ game that keeps its own world. It includes the echo of your own edits; compare the uuid and
57
+ sequence with your send's.
58
+ - **`ChunkStore` keeps wide voxel types and other addresses.** Positions and types are the app's
59
+ signed 16-bit values, which the platform does not check.
60
+ - An edit the 16x16x16 one-byte grid cannot hold (a type outside 0-255, a position outside
61
+ 0-15) is kept whole in the chunk's overlay. That covers a realtime update, a hydrated
62
+ `voxelStates` entry and a local `set_voxel`.
63
+ - `ChunkStore.overlay(chunk)` returns the overlay as `ChunkOverlayVoxel(x, y, z,
64
+ voxel_type, state)` values keyed by `voxel_key(x, y, z)` (`"x:y:z"`), and `voxel_type_at`
65
+ and `voxel_state_at` read it first.
66
+ - What changes: hydration no longer stores a type outside 0-255 truncated (300 used to read
67
+ as 44), and keeps an entry outside 0-15 instead of skipping it. `voxels()` holds 0 under
68
+ an in-grid voxel whose type is in the overlay.
69
+ - `set_voxel` keeps a position outside 0-15 in the overlay and sends it, where it used to be
70
+ refused. It raises `ValueError`, before anything changes or is sent, for a position or type
71
+ outside 16 bits or a state over 1,024 bytes (`crowdypy.wire.assert_voxel_edit`,
72
+ `VOXEL_STATE_MAX_BYTES`).
73
+ - `udp.send_voxel_update` and `ReplicationConnection.send_voxel_update` refuse a state over
74
+ 1,024 bytes (`CrowdyReplicationError`, `InvalidArgument`); the server refuses one with
75
+ `INVALID_REQUEST`.
76
+ - **The echo of your own voxel edit.** Replication server v0.37.0 delivers every accepted edit
77
+ back to its sender. `ChunkStore` matches the echo to the `set_voxel` that sent it (sender,
78
+ sequence, voxel) and does not apply it again, so a local edit fires `on_chunk_changed` once.
79
+ The echo is applied only when another client's edit of the voxel arrived in between (the
80
+ server ordered yours last).
81
+ - **Hydration goes through the native store.** `ChunkStore.hydrate()` hands each loaded chunk
82
+ to CrowdyCPP's `ChunkStore`, which puts the entries the grid cannot hold in the overlay. An
83
+ entry without a state now clears the voxel's state, also one a local `set_voxel` gave it (0.5.1
84
+ kept that until the next realtime update). `voxel_state_at` reads the native cache only, and
85
+ `prune_beyond` keeps a dirty chunk's states and overlay as well as its grid.
86
+ - **UDP error 33, `APP_PAUSED`** (`crowdypy.wire.ErrorCode.APP_PAUSED`): the replication
87
+ server refuses a paused app's sends.
88
+ - **Pause and access refusals.**
89
+ - `crowdypy.is_app_paused(gate)` reads `AppTokenResponse.runtime_gate` (`AppRuntimeGate`,
90
+ `status` and `reason`) and the `runtimeGate` of `server_status.game_client_bootstrap`.
91
+ Anything but `ACTIVE` is paused. A paused app still mints, so check before entering the
92
+ world.
93
+ - `crowdypy.app_paused_of(error)` reads `APP_PAUSED` (`reason`).
94
+ - `crowdypy.access_refusal_of(error)` reads `ACCESS_REVOKED`, `ACCESS_SUSPENDED`
95
+ (`suspended_until`) or `ACCESS_NOT_GRANTED`.
96
+ - `crowdypy.actor_exists_of(error)` reads `ACTOR_EXISTS` (`owned_by_caller`).
97
+ - Each reader takes a raised `CrowdyGraphQLError` or one raw error entry. The `*_CODE`
98
+ constants name the codes.
99
+ - **New API wraps.**
100
+ - `users.player_profile(user_id)` and `users.player_profiles(user_ids)` return the public
101
+ `userId`, `gamertag` and `disambiguation`. `player_profiles` takes at most
102
+ `PLAYER_PROFILES_MAX` (100) ids, raises `ValueError` above that, and sends nothing for
103
+ none. `users.get` documents that another user's private fields come back `None`.
104
+ - `app_access.suspend(app_id, user_id, until, idempotency_key=None)` takes a timezone-aware
105
+ `datetime` or an ISO-8601 string. With it come `unsuspend` and
106
+ `resync_tier_grid_permissions` (`manage_access_tiers`), and `suspendedUntil` on every
107
+ access record.
108
+ - `exec.restart_type(app_id, node_type)` returns `ExecRestartResult(node_type, stopped)`
109
+ (`manage_compute`). `ExecAppStatus` gains `budget_pause_reason`, `max_instances`,
110
+ `max_reserved_mb`, `instance_limit`, `instances` and `reserved_mb`.
111
+ - `apps.get` and `apps.update` carry `claimOwnerKeys`, chunk reads `voxelStatesTruncated`,
112
+ and `game_client_bootstrap` `runtimeGate` and `wildernessWritesOpen`.
113
+ - The keyframe and heartbeat defaults stay. Idle players on different servers meet at the first
114
+ full update after joining (replication server v0.37.0).
115
+
116
+ ## 0.7.0
117
+
118
+ CrowdyJS 18.6.0 and CrowdyCPP 0.59.0. Additive.
119
+
120
+ - **The input log.** An app with replay logging on has every client input the realtime
121
+ servers accept recorded. `client.input_log.sessions(app_id, *, first=, after=, filter=)`
122
+ lists the app's recorded sessions, newest first (`edges`, `pageInfo`, `totalCount`; a
123
+ session is one game token's inputs), and `client.input_log.messages(app_id, game_token_id,
124
+ *, first=, after=, filter=)` reads one session's inputs, oldest first. `body` is the client
125
+ message in base64 without its authentication tail (`decode_base64` gives the bytes), and
126
+ `sizeBytes` is what stored input logs are billed on. Keep paging while
127
+ `pageInfo.hasNextPage` is true: a page can be short, or empty, when it reached the server's
128
+ time or scan limit. Both are game plane (the app-scoped client). A player reads their own
129
+ sessions, and a holder of `manage_apps` reads every one; without it, listing another
130
+ user's sessions is `FORBIDDEN` and reading another user's session is `NOT_FOUND`. Both
131
+ answer `INPUT_LOG_UNAVAILABLE` on a deployment without input logging, and `messages` also
132
+ answers it, retryable with the same cursor, when the log cannot be read right now.
133
+ - **`replayLoggingEnabled`** is selected on every app read. Turning it on with
134
+ `client.apps.update` is refused with `INPUT_LOG_FUNDS_NEEDED` unless the org's wallet has a
135
+ spendable balance or the org is exempt from billing.
136
+
6
137
  ## 0.6.0
7
138
 
8
139
  CrowdyJS 18.5.0 and CrowdyCPP 0.58.0. Additive.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crowdypy
3
- Version: 0.6.0.dev1
3
+ Version: 0.8.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,14 +51,23 @@ 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.6.0: distance-limited channel messages and the terms gate (CrowdyJS 18.5.0, CrowdyCPP 0.58.0).**
55
- - `client.udp.send_ranged_channel_message(..., chunk=, max_distance=)` publishes to a channel
56
- but reaches only the members whose own actor is within `max_distance` chunks of `chunk`,
57
- by straight-line distance. Members receive the ordinary `channel_message`.
58
- - `client.auth.record_player_consents()` and `player_legal_acceptance()`, `register`'s
59
- `accept_legal` and `attest_age_of_majority`, and `is_legal_acceptance_required_error`: a
60
- gameplay token now waits for the player's agreement to the legal documents and age
61
- attestation.
54
+ **v0.8.0: voice, channel audio, wide voxels, and pause and access refusals (CrowdyJS 18.7.0, CrowdyCPP 0.60.0).**
55
+ - Voice: `crowdypy.media`'s voice helpers (an optional 10-byte header per codec frame,
56
+ `VoicePacketizer`, `VoiceJitterBuffer`), and `client.udp.send_channel_audio()` with the
57
+ `channel_audio` handler, which reaches every member of a channel wherever they are (party
58
+ and guild voice).
59
+ - World Stores: `ChunkStore` keeps voxel edits the 16x16x16 one-byte grid cannot hold in an
60
+ overlay, and applies the echo of your own edit once. `session.on("voxel_update")` and
61
+ `session.on("generic_spatial")` reach a game that keeps its own world.
62
+ - Refusals: `crowdypy.is_app_paused()` reads the runtime gate that tokens and the bootstrap
63
+ carry, and `app_paused_of`, `access_refusal_of` and `actor_exists_of` read the new refusals.
64
+ - New calls: `users.player_profile(s)`, `app_access.suspend` and `unsuspend`, and
65
+ `exec.restart_type`.
66
+ - 0.8.0 needs the ck-api release after v2.39.0, since the token mutations select
67
+ `runtimeGate`. Channel audio and the voxel echo need replication server v0.37.0.
68
+ - 0.7.0 brought the input log (`client.input_log.sessions()` and `messages()`, and
69
+ `replayLoggingEnabled`). 0.6.0 brought distance-limited channel messages
70
+ (`udp.send_ranged_channel_message()`) and the terms gate (`auth.record_player_consents()`).
62
71
  - 0.5.1 made `ChunkStore.hydrate()` keep every recorded voxel edit (`voxelStates`) and
63
72
  `ensure_around()` keep a chunk it already loaded.
64
73
  - 0.5.0 brought the ck-exec gateway check (`client.exec.connect()` sends the connect token
@@ -174,6 +183,13 @@ is not serving) and `CrowdyUserCodeFaultError` (a player module faulted;
174
183
  `player_fault_of(error)` reads the fault) mirror CrowdyJS. A `WRONG_DATACENTER` refusal
175
184
  moves the client to the app's datacenter and retries once, by itself.
176
185
 
186
+ A paused app (its organization ran out of funds, hit a spend cap, or let a subscription
187
+ lapse) still mints a token, so check `crowdypy.is_app_paused(minted.runtime_gate)` before
188
+ entering the world, and tell the player it is paused. Replication then refuses sends with UDP
189
+ error 33 (`APP_PAUSED`). `crowdypy.app_paused_of(error)`, `access_refusal_of(error)`
190
+ (`ACCESS_REVOKED`, `ACCESS_SUSPENDED` with `suspended_until`, `ACCESS_NOT_GRANTED`) and
191
+ `actor_exists_of(error)` read those refusals. None of them clears by retrying.
192
+
177
193
  ## Replication
178
194
 
179
195
  ```python
@@ -201,6 +217,47 @@ async for batch in conn.batches():
201
217
  `crowdypy.replication.ReplicationConnection` is the same for code without an event loop:
202
218
  `wait()` and then `poll()` from your own loop.
203
219
 
220
+ Voxel positions and types are the app's signed 16-bit values, and a voxel state is at most
221
+ 1,024 bytes (`InvalidArgument` otherwise, nothing sent). Replication server v0.37.0 echoes
222
+ every accepted voxel edit back to its sender as a `voxel_update`.
223
+
224
+ ## Voice
225
+
226
+ `send_audio_packet` reaches players near a chunk and carries whatever bytes it is given; a game
227
+ with a voice format of its own keeps it. The voice helpers in `crowdypy.media` are an optional
228
+ format that every Crowded Kingdoms SDK shares, byte for byte. Each packet is a 10-byte header
229
+ (version 1, the codec, a `u16` seq, a `u32` timestamp in codec samples, the frame's duration
230
+ and two talk-spurt flags) followed by one codec frame. `VoicePacketizer` numbers one sender's
231
+ frames. `VoiceJitterBuffer` puts each sender's packets back in order and plays them out 60 ms
232
+ after the first packet of a talk spurt arrived. It reports a frame that never came as a gap,
233
+ drops one that arrives after its playout time, and holds at most 64 frames a sender.
234
+
235
+ `send_channel_audio` reaches every member of a channel wherever they are (party or guild
236
+ voice), at most 1,024 bytes a packet. The sender needs the channel's `send_voice`
237
+ (`members_can_speak=True` on creation gives it to the member role) and the player's
238
+ `use_voice_chat`. There is no echo, and members receive `channel_audio`:
239
+
240
+ ```python
241
+ from crowdypy.media import VoiceCodec, VoiceJitterBuffer, VoicePacketizer
242
+
243
+ party = VoicePacketizer(VoiceCodec.OPUS, 20)
244
+ # Every 20 ms while the player talks (`opus_frame` from your own encoder):
245
+ await game.udp.send_channel_audio(channel_id, my_uuid, party.packetize(opus_frame, last=released))
246
+ # ...and party.skip() for every 20 ms of silence that is not sent.
247
+
248
+ voices = VoiceJitterBuffer()
249
+ game.udp.subscribe({"channel_audio": lambda n: voices.push(f"{n.channel_id}:{n.uuid}", n.payload)})
250
+ for slot in voices.poll(): # at least once a frame, from your audio clock
251
+ if slot.gap:
252
+ conceal(slot.key, slot.frame_ms) # the frame never came
253
+ else:
254
+ play(slot.key, slot.codec, slot.frame)
255
+ ```
256
+
257
+ No codec ships with CrowdyPy, and the wheel links none: which codec an app uses (Opus, or
258
+ G.711 µ-law where it has no Opus), and the library that encodes and decodes it, is the app's
259
+ choice. Where a voice sits in the world (panning, distance attenuation) is the game's too.
260
+
204
261
  ## World Stores
205
262
 
206
263
  ```python
@@ -217,6 +274,12 @@ snapshot = session.actors.snapshot() # once a frame: every actor at once
217
274
  states = pose.decode_many(snapshot.state_offsets, snapshot.state_data) # numpy, no loop
218
275
  ```
219
276
 
277
+ `session.chunks` is a helper for 16x16x16 chunks with one byte per voxel. An edit that grid
278
+ cannot hold (a type outside 0-255, a position outside 0-15) is kept in the chunk's
279
+ `overlay()`, and `voxel_type_at` reads it first. The echo of your own `set_voxel` is not
280
+ applied a second time. A game with other addressing reads every edit from
281
+ `session.on("voxel_update", ...)`, which includes those echoes.
282
+
220
283
  ## Crowdy Studio
221
284
 
222
285
  ```python
@@ -11,14 +11,23 @@ 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.6.0: distance-limited channel messages and the terms gate (CrowdyJS 18.5.0, CrowdyCPP 0.58.0).**
15
- - `client.udp.send_ranged_channel_message(..., chunk=, max_distance=)` publishes to a channel
16
- but reaches only the members whose own actor is within `max_distance` chunks of `chunk`,
17
- by straight-line distance. Members receive the ordinary `channel_message`.
18
- - `client.auth.record_player_consents()` and `player_legal_acceptance()`, `register`'s
19
- `accept_legal` and `attest_age_of_majority`, and `is_legal_acceptance_required_error`: a
20
- gameplay token now waits for the player's agreement to the legal documents and age
21
- attestation.
14
+ **v0.8.0: voice, channel audio, wide voxels, and pause and access refusals (CrowdyJS 18.7.0, CrowdyCPP 0.60.0).**
15
+ - Voice: `crowdypy.media`'s voice helpers (an optional 10-byte header per codec frame,
16
+ `VoicePacketizer`, `VoiceJitterBuffer`), and `client.udp.send_channel_audio()` with the
17
+ `channel_audio` handler, which reaches every member of a channel wherever they are (party
18
+ and guild voice).
19
+ - World Stores: `ChunkStore` keeps voxel edits the 16x16x16 one-byte grid cannot hold in an
20
+ overlay, and applies the echo of your own edit once. `session.on("voxel_update")` and
21
+ `session.on("generic_spatial")` reach a game that keeps its own world.
22
+ - Refusals: `crowdypy.is_app_paused()` reads the runtime gate that tokens and the bootstrap
23
+ carry, and `app_paused_of`, `access_refusal_of` and `actor_exists_of` read the new refusals.
24
+ - New calls: `users.player_profile(s)`, `app_access.suspend` and `unsuspend`, and
25
+ `exec.restart_type`.
26
+ - 0.8.0 needs the ck-api release after v2.39.0, since the token mutations select
27
+ `runtimeGate`. Channel audio and the voxel echo need replication server v0.37.0.
28
+ - 0.7.0 brought the input log (`client.input_log.sessions()` and `messages()`, and
29
+ `replayLoggingEnabled`). 0.6.0 brought distance-limited channel messages
30
+ (`udp.send_ranged_channel_message()`) and the terms gate (`auth.record_player_consents()`).
22
31
  - 0.5.1 made `ChunkStore.hydrate()` keep every recorded voxel edit (`voxelStates`) and
23
32
  `ensure_around()` keep a chunk it already loaded.
24
33
  - 0.5.0 brought the ck-exec gateway check (`client.exec.connect()` sends the connect token
@@ -134,6 +143,13 @@ is not serving) and `CrowdyUserCodeFaultError` (a player module faulted;
134
143
  `player_fault_of(error)` reads the fault) mirror CrowdyJS. A `WRONG_DATACENTER` refusal
135
144
  moves the client to the app's datacenter and retries once, by itself.
136
145
 
146
+ A paused app (its organization ran out of funds, hit a spend cap, or let a subscription
147
+ lapse) still mints a token, so check `crowdypy.is_app_paused(minted.runtime_gate)` before
148
+ entering the world, and tell the player it is paused. Replication then refuses sends with UDP
149
+ error 33 (`APP_PAUSED`). `crowdypy.app_paused_of(error)`, `access_refusal_of(error)`
150
+ (`ACCESS_REVOKED`, `ACCESS_SUSPENDED` with `suspended_until`, `ACCESS_NOT_GRANTED`) and
151
+ `actor_exists_of(error)` read those refusals. None of them clears by retrying.
152
+
137
153
  ## Replication
138
154
 
139
155
  ```python
@@ -161,6 +177,47 @@ async for batch in conn.batches():
161
177
  `crowdypy.replication.ReplicationConnection` is the same for code without an event loop:
162
178
  `wait()` and then `poll()` from your own loop.
163
179
 
180
+ Voxel positions and types are the app's signed 16-bit values, and a voxel state is at most
181
+ 1,024 bytes (`InvalidArgument` otherwise, nothing sent). Replication server v0.37.0 echoes
182
+ every accepted voxel edit back to its sender as a `voxel_update`.
183
+
184
+ ## Voice
185
+
186
+ `send_audio_packet` reaches players near a chunk and carries whatever bytes it is given; a game
187
+ with a voice format of its own keeps it. The voice helpers in `crowdypy.media` are an optional
188
+ format that every Crowded Kingdoms SDK shares, byte for byte. Each packet is a 10-byte header
189
+ (version 1, the codec, a `u16` seq, a `u32` timestamp in codec samples, the frame's duration
190
+ and two talk-spurt flags) followed by one codec frame. `VoicePacketizer` numbers one sender's
191
+ frames. `VoiceJitterBuffer` puts each sender's packets back in order and plays them out 60 ms
192
+ after the first packet of a talk spurt arrived. It reports a frame that never came as a gap,
193
+ drops one that arrives after its playout time, and holds at most 64 frames a sender.
194
+
195
+ `send_channel_audio` reaches every member of a channel wherever they are (party or guild
196
+ voice), at most 1,024 bytes a packet. The sender needs the channel's `send_voice`
197
+ (`members_can_speak=True` on creation gives it to the member role) and the player's
198
+ `use_voice_chat`. There is no echo, and members receive `channel_audio`:
199
+
200
+ ```python
201
+ from crowdypy.media import VoiceCodec, VoiceJitterBuffer, VoicePacketizer
202
+
203
+ party = VoicePacketizer(VoiceCodec.OPUS, 20)
204
+ # Every 20 ms while the player talks (`opus_frame` from your own encoder):
205
+ await game.udp.send_channel_audio(channel_id, my_uuid, party.packetize(opus_frame, last=released))
206
+ # ...and party.skip() for every 20 ms of silence that is not sent.
207
+
208
+ voices = VoiceJitterBuffer()
209
+ game.udp.subscribe({"channel_audio": lambda n: voices.push(f"{n.channel_id}:{n.uuid}", n.payload)})
210
+ for slot in voices.poll(): # at least once a frame, from your audio clock
211
+ if slot.gap:
212
+ conceal(slot.key, slot.frame_ms) # the frame never came
213
+ else:
214
+ play(slot.key, slot.codec, slot.frame)
215
+ ```
216
+
217
+ No codec ships with CrowdyPy, and the wheel links none: which codec an app uses (Opus, or
218
+ G.711 µ-law where it has no Opus), and the library that encodes and decodes it, is the app's
219
+ choice. Where a voice sits in the world (panning, distance attenuation) is the game's too.
220
+
164
221
  ## World Stores
165
222
 
166
223
  ```python
@@ -177,6 +234,12 @@ snapshot = session.actors.snapshot() # once a frame: every actor at once
177
234
  states = pose.decode_many(snapshot.state_offsets, snapshot.state_data) # numpy, no loop
178
235
  ```
179
236
 
237
+ `session.chunks` is a helper for 16x16x16 chunks with one byte per voxel. An edit that grid
238
+ cannot hold (a type outside 0-255, a position outside 0-15) is kept in the chunk's
239
+ `overlay()`, and `voxel_type_at` reads it first. The echo of your own `set_voxel` is not
240
+ applied a second time. A game with other addressing reads every edit from
241
+ `session.on("voxel_update", ...)`, which includes those echoes.
242
+
180
243
  ## Crowdy Studio
181
244
 
182
245
  ```python
@@ -93,3 +93,23 @@ A 60 Hz asyncio loop sends 200 entities a frame (one batch) while about 60,000
93
93
  notifications a second arrive and are dispatched to a handler. Lateness of each frame
94
94
  against its schedule, ten seconds: p50 0.1 ms, p99 0.1 ms, max 0.2 ms. Receiving never
95
95
  holds the loop: it is woken once per batch, not per datagram.
96
+
97
+ ## Re-check, 0.8.0
98
+
99
+ 0.8.0 added handlers to the binding (channel audio, and the session's forwarding of
100
+ app-defined spatial messages, channel audio and watched voxel updates) and re-vendored
101
+ CrowdyCPP 0.60.0. Both builds below ran back to back on the CKS builder (the machine above),
102
+ under CPython 3.12.3 and the system's shared OpenSSL 3.0.13 rather than the wheels' static
103
+ 3.5.9, so compare them with each other, not with the 0.2.0 tables.
104
+
105
+ | | 0.7.0 (CrowdyCPP 0.59.0) | 0.8.0 (CrowdyCPP 0.60.0) |
106
+ |---|---|---|
107
+ | 1a. `send_actor_updates`, one batch of 200 | 647.1 ns/entity | 647.2 ns/entity |
108
+ | 1a. `native.send_spatial` x200 | 838.1 ns/entity | 840.1 ns/entity |
109
+ | 2. notifications delivered to Python, three interleaved runs | 1.774, 1.763, 1.765 million/s | 1.774, 1.762, 1.772 million/s |
110
+ | 4. echo round trip, p50 | 74.8 µs | 74.8 µs |
111
+ | 5. game-loop lateness, p99 | 0.3 ms | 0.2 ms |
112
+
113
+ CrowdyCPP 0.60.0's own `bench_send` section 5 (`sendActorUpdate` x200, Release, same machine
114
+ and OpenSSL) measured 623.9 ns/entity, so one batch costs 1.04x CrowdyCPP's send path per
115
+ entity (1.06x at 0.2.0).
@@ -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.6.0`
8
+ - CrowdyPy `0.8.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
@@ -43,3 +43,12 @@ requirement names one exactly, the same way a caret never matches an npm prerele
43
43
  waits for both consents (`LEGAL_ACCEPTANCE_REQUIRED`).
44
44
  - `udp.send_ranged_channel_message` needs a replication server that serves message type 32
45
45
  (CHANNEL_MESSAGE_RANGED_REQUEST); one that does not delivers nothing.
46
+ - 0.8.0 selects `runtimeGate` on every token mutation (`portal.mint_app_token`,
47
+ `exchange_code`, `refresh`) and on `game_client_bootstrap`, so it needs the ck-api release
48
+ after v2.39.0 that serves it; an older API refuses those calls with a GraphQL validation
49
+ error. The same release serves `playerProfile(s)`, the access suspension and
50
+ `execRestartType`.
51
+ - Channel audio (message types 35 and 36) and the echo of your own voxel edits need replication
52
+ server v0.37.0; an older one drops message type 35 and echoes nothing.
53
+ - The wheels link no audio codec (CrowdyCPP's optional libopus wrapper is built OFF): the
54
+ voice helpers carry an app's codec frames without reading them.
@@ -18,6 +18,7 @@ Unconfigured, every suite skips, so `pytest` in CI records skips, not live passe
18
18
  | `CROWDY_E2E_STUDIO_GRID_ID` | no | a grid in the app that the owner controls (Studio suite) |
19
19
  | `CROWDY_E2E_SLOW=1` | no | long-running suites |
20
20
  | `CROWDY_E2E_THROWAWAY_OWNER=1` | no | the open-grid suite registers a throwaway owner, org and app (archived afterwards) |
21
+ | `CROWDY_E2E_PROVISIONING_TOKEN` | dev and test | dev and test are staff-only, so a new derived player is refused (`TIER_ACCESS_REQUIRED`) unless `register` carries a provisioning token covering its address. Use the `harness` token (Secrets Manager `infra-cp/<tier>/loadtest/provisioning-token-harness`, `token` key) with `CROWDY_E2E_EMAIL=crowdy-e2e@test.invalid`. Sent on `register` only; other tiers ignore it |
21
22
 
22
23
  ```bash
23
24
  pytest tests/e2e -q
@@ -54,6 +55,7 @@ player once and signs it in for the later suites.
54
55
  | 2026-10-01 | dev tier, app `96701660793088` | `crowdypy 0.4.1.dev1` from PyPI (`pip install crowdypy` in a clean Python 3.12; the first version published by trusted publishing) | 8 passed; Studio skipped |
55
56
  | 2026-10-01 | dev tier, app `96701660793088`; the open-grid suite in its own throwaway org and app (`CROWDY_E2E_THROWAWAY_OWNER=1`) | `crowdypy 0.5.0.dev1` from PyPI (`pip install crowdypy` in a clean Python 3.12) | 10 passed; Studio skipped |
56
57
  | 2026-10-08 | local stack: ck-api at the distance-limited channel branch (off `dev`), two replication servers serving message type 32, the 3-node Citus lab | 0.6.0 (branch) | identity, ranged channel, replication, world and world data suites: 10 passed |
58
+ | 2026-10-09 | dev tier, app `96701660793088`, after replication server v0.35.0 and ck-api v2.38.0 reached dev | `crowdypy 0.6.0.dev1` from PyPI (installed into a clean Python 3.12 with uv) | identity (incl. the terms gate), ranged channel, replication, world and world data suites: 10 passed |
57
59
 
58
60
  ## Not covered here
59
61
 
@@ -69,3 +71,10 @@ These CrowdyCPP suites have no CrowdyPy counterpart yet; the reason is in each r
69
71
  | `e2e_soak_two_clients`, `e2e_permission_refresh` | long-running; slated for `CROWDY_E2E_SLOW=1` suites |
70
72
  | `e2e_host_election`, `e2e_durable_stores`, `e2e_chunk_store_live` | the World Stores' host, save and chunk persistence run over GraphQL timers covered by unit suites against fakes; live coverage needs a dedicated app (chunk write-back closes the wilderness) |
71
73
  | `e2e_cross_app`, `e2e_cross_tenant`, `e2e_malicious_input` | platform isolation properties the CrowdyCPP suites already exercise against the same API |
74
+
75
+ 0.8.0's additions (channel audio, the echo of your own voxel edit, `APP_PAUSED`, access
76
+ suspension, player profiles, `exec.restart_type`) have no live suite yet, in CrowdyPy or in
77
+ CrowdyCPP. The unit suites cover them against a fake replication server and a mocked API. From
78
+ 0.8.0 every suite mints with `runtimeGate` selected, so run them only against a tier whose
79
+ ck-api is the release after v2.39.0 or later; an older one refuses the mint as a GraphQL
80
+ validation error. Channel audio and the voxel echo need replication server v0.37.0 as well.