crowdypy 0.9.0.dev1__tar.gz → 0.9.1.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.
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/MIGRATION.md +11 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/PKG-INFO +3 -3
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/README.md +2 -2
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/docs/compatibility.md +5 -1
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/pyproject.toml +1 -1
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/check_content_policy.py +5 -1
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/check_pin_tiers.py +75 -6
- crowdypy-0.9.1.dev1/src/crowdypy/_sync/domains/input_log.py +113 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_version.py +1 -1
- crowdypy-0.9.1.dev1/src/crowdypy/domains/input_log.py +112 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/test_world_domains.py +19 -0
- crowdypy-0.9.1.dev1/tests/unit/test_check_pin_tiers.py +59 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/uv.lock +2 -2
- crowdypy-0.9.0.dev1/src/crowdypy/_sync/domains/input_log.py +0 -80
- crowdypy-0.9.0.dev1/src/crowdypy/domains/input_log.py +0 -79
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/.gitattributes +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/.gitignore +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/.gitleaks.toml +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/AGENTS.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/CMakeLists.txt +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/LICENSE +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/SECURITY.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/benchmarks/README.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/benchmarks/bench_replication.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/docs/e2e-coverage.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/docs/parity-matrix.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/licenses/OpenSSL-LICENSE.txt +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/common.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/module.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/replication.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/replication_binding.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/session_binding.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/voice_binding.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/native/wire_binding.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/Actor.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/Actors.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/BatchLookupActors.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/CreateActor.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/DeleteActor.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/UpdateActor.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/actors/UpdateActorState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/AppAccessTiers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/AppFeatures.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/AppGrantMemberCandidates.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/AppUserAccessByApp.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/ArchiveAccessTier.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/ClaimFreeAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/CreateAccessTier.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/DefineAppFeature.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/GrantAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/GrantMyAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/GrantTierFeature.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/MyAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/RevokeAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/RevokeTierFeature.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/RuntimePermissions.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/SuspendAppAccess.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/TierFeatures.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/appAccess/UpdateAccessTier.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/App.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/AppBySlug.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/AppDiscovery.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/AppsForOrg.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/ArchiveApp.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/CodeAdmissions.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/CreateApp.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/MarketplaceApps.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/MyApps.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/PlaceableDatacenters.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/apps/UpdateApp.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/auth/Logout.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/auth/LogoutAllDevices.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/avatars/Avatars.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/billing/AppBudget.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/billing/AppBudgets.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/billing/SetAppBudget.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/billing/WalletBalance.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/billing/WalletTransactions.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/AddChannelMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/Channel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/ChannelMembers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/ChannelPolicy.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/ChannelRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/Channels.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/CreateChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/CreateChannelRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/DeleteChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/DeleteChannelRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/JoinChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/LeaveChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/MyChannels.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/RemoveChannelMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/RequestToJoinChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/SetChannelMemberRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/SetChannelPolicy.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/UpdateChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/channels/UpdateChannelRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/GetChunk.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/GetChunkLods.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/GetChunksByDistance.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/GetVoxelList.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/UpdateChunk.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/UpdateChunkLods.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/chunks/UpdateChunkState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/crowdyStudio/CrowdyStudio.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/exec/Exec.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/gameApps/GameApps.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/grids/CreateGridChannel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/grids/GridChannels.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/grids/MintGridToken.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/host/Host.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/inputLog/InputLogMessages.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/inputLog/InputLogSessions.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/marketplace/Marketplace.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/CreateOrgRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/CreateOrgToken.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/CreateOrganization.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/DeleteOrgRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/InviteOrgMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/MemberRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/MyOrganizations.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/OrgMembers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/OrgPermissions.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/OrgRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/OrgTokens.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/Organization.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/OrganizationBySlug.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/RemoveOrgMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/RevokeOrgToken.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/UpdateOrgMemberRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/UpdateOrgRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/organizations/UpdateOrgToken.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/payments/CapturePaypalCheckout.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/payments/CreateCheckout.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/payments/MyCheckouts.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/platform/PlatformConfig.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/playerWallet/PlayerWallet.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/quotas/DeleteQuota.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/quotas/EffectiveQuota.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/quotas/QuotasForApp.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/quotas/QuotasForOrg.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/quotas/SetQuota.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/serverStatus/ActiveGraphQLServers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/serverStatus/GameClientBootstrap.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/serverStatus/GraphqlServers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/serverStatus/ServerWithLeastClients.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/serverStatus/VersionInfo.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/sharedEnvironment/SharedEnvironment.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/state/DeleteUserAppState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/state/UpdateUserAppState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/state/UserAppState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/state/UserAppStates.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/AddTeamMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/CreateTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/CreateTeamRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/DeleteTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/DeleteTeamRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/JoinTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/LeaveTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/MyTeams.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/RemoveTeamMember.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/RequestToJoinTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/SetTeamMemberRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/SetTeamPolicy.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/Team.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/TeamMembers.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/TeamPolicy.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/TeamRoles.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/Teams.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/UpdateTeam.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teams/UpdateTeamRole.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/teleport/TeleportRequest.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/usage/AppGraphqlOperations.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/usage/AppUsageSummary.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/usage/PlayerPulse.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/DeleteMyAccount.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/FreePlayWindow.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/Me.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/PlayerProfile.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/UpdateGamertag.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/UpdateUserState.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/users/User.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/voxels/ListVoxelUpdatesByDistance.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/voxels/ListVoxels.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/voxels/RollbackVoxelUpdates.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/voxels/UpdateVoxel.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/operations/voxels/VoxelUpdateHistory.graphql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/schema.gql +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/_pins.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/assert_default_origin.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/build_openssl.sh +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/cibw_before_all_linux.sh +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/resolve-release-tier.sh +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/resolve-release-tier.test.sh +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/resolve_pypi_version.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/stamp_version.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/ci/verify_artifacts.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/codegen.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/schema_drift.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/schema_sync.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/unasync.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/scripts/vendor_crowdycpp.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_concurrency.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_default_origin.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_generated/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_generated/enums.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_generated/inputs.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_generated/operations.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_grid.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_native.pyi +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_operation.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/client.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/_base.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/actors.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/admin.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/app_access.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/apps.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/auth.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/avatars.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/billing.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/channels.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/chunks.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/crowdy_studio.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/crowdy_studio_agent.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/crowdy_studio_github.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/discovery.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/exec.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/game_apps.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/grids.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/host.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/marketplace.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/organizations.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/payments.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/platform.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/player_wallet.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/portal.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/quotas.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/server_status.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/shared_environment.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/state.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/teams.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/teleport.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/udp.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/usage.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/users.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/domains/voxels.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/graphql.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/grid_scope.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/kit/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/kit/actions.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/kit/kit.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/kit/social.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/kit/wire.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/rediscover.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/stores.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/_sync/world.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/auth_state.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/client.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/codecs.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/datacenter_redirect.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/_base.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/actors.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/admin.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/app_access.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/apps.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/auth.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/avatars.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/billing.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/channels.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/chunks.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/crowdy_studio.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/crowdy_studio_agent.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/crowdy_studio_github.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/discovery.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/exec.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/game_apps.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/grids.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/host.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/marketplace.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/organizations.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/payments.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/platform.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/player_wallet.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/portal.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/quotas.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/server_status.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/shared_environment.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/state.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/teams.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/teleport.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/udp.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/usage.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/users.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/domains/voxels.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/enums.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/errors.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/estate.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/exec_gateway.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/graphql.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/grid_scope.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/inputs.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/kit/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/kit/actions.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/kit/kit.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/kit/social.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/kit/wire.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/lb_cookie.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/media.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/pkce.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/agent_errors.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/agent_types.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/json_schema.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/schemas.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/schemas.v1.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/player_host/types.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/py.typed +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/rediscover.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/replication.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/session.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/stores.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/client_tick_interval.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/controller.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/diagnostics.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/github_new_repo.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/layout.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/models.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/studio/starter_projects.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/subscriptions.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/sync.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/utils.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/wire.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/src/crowdypy/world.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/conftest.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/conftest.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_identity.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_open_grid_exec_gateway.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_ranged_channel.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_replication.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_studio.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_world.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/e2e/test_e2e_world_data.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/fixtures/README.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/fixtures/binary-wire-fixtures.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/fixtures/exec-client-frames.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/fixtures/player-host.v1.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/fixtures/voice-frames.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/__init__.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/test_crowdycpp_roots.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/test_org_domains.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/test_social_domains.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/domains/test_studio_exec_domains.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_core.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_durable_stores.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_estate_moves.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_exec_gateway.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_fixture_provenance.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_grid_scope.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_kit.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_lazy_exports.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_player_host.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_refusals.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_release_versions.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_replication.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_sdk_audience.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_studio_controller.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_studio_diagnostics.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_studio_layout.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_subscriptions.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_transport.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_udp_api.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_voice_frames.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_wire.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tests/unit/test_world_session.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tools/e2e/provision.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tools/fixtures/player_host.mjs +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tools/parity/classifications.toml +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/tools/parity/parity.py +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/CMakeLists.txt +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/LICENSE +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/PROVENANCE.md +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/cmake/CheckPublicHeaders.cmake +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/cmake/CrowdyCPPConfig.cmake.in +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/cmake/CrowdyFindOpus.cmake +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/cmake/studio_layout_fixture.hpp.in +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/client.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/base64.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/bytes.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/clock.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/crypto.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/logger.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/result.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/spsc.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/core/uuid.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/crowdy.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/default_origin.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/admin.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/auth.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_agent.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_github.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/discovery.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/domain_base.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/exec.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/game_apps.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/grids.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/groups.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/marketplace.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/player_wallet.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/portal.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/realtime_control.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/server_status.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/types.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/users.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/domains/world_data.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/generated/enums.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/generated/operations.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/async_scope.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/auth_state.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/datacenter_redirect.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/dispatcher.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/errors.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/estate.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/graphql_client.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/http.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/json.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/rediscover.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/subscription_client.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/websocket.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/kit/actions.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/kit/kit.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/kit/social.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/kit/wire.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/media/opus.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/media/video_frames.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/media/voice_frames.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/adapter.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/player_host.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/schemas.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/types.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/replication/connection.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/replication/session_provider.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/replication/types.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/replication/udp_socket.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/chunk_store.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/codec.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/durable.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/keys.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/stores.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/session/world_session.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/controller.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/diagnostics.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/editor.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github_layout.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/integration.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/layout.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/models.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/studio/runtime.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/wire/codec.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/wire/protocol.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/include/crowdy/world.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/package.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/client.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/base64.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/clock.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/crypto_default_unavailable.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/crypto_openssl.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/crypto_unavailable.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/logger.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/core/uuid.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/domains/exec.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/async_transport.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/auth_state.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/error_extensions.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/errors.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/graphql_client.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/http_curl.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/http_none.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/json.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/subscription_client.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/websocket_curl.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/graphql/websocket_none.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/media/opus.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/player_host/schemas.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/player_host/types.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/replication/connection.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/replication/socket_errors.hpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/replication/udp_socket.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/session/world_session.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/studio/diagnostics.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/studio/editor.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/src/studio/integration.cpp +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/third_party/yyjson/LICENSE +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.c +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.h +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdy-studio-diagnostics.v1.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdyjs-studio-layout.v1.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-client-frames.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-gateway-cases.json +0 -0
- {crowdypy-0.9.0.dev1 → crowdypy-0.9.1.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/voice-frames.json +0 -0
|
@@ -3,6 +3,17 @@
|
|
|
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.9.1
|
|
7
|
+
|
|
8
|
+
A patch release with the same API as 0.9.0, the same CrowdyJS (18.8.0) and CrowdyCPP (0.61.0) pins.
|
|
9
|
+
|
|
10
|
+
- **`client.input_log` sends a session filter's `userId` as a string**, the decimal string every
|
|
11
|
+
id is on the wire. An `int` used to go out as a JSON number.
|
|
12
|
+
- **Its docstrings say when a read is retryable.** From the Game API release after v2.40.2,
|
|
13
|
+
`InputLogAPI.messages` answers `INPUT_LOG_TEMPORARILY_UNAVAILABLE` when the log cannot be read
|
|
14
|
+
right now and `INPUT_LOG_RATE_LIMITED` while another read of yours is running; both carry
|
|
15
|
+
`extensions.retryable`, so retry with the same cursor after a short back-off.
|
|
16
|
+
|
|
6
17
|
## 0.9.0
|
|
7
18
|
|
|
8
19
|
CrowdyJS 18.8.0 and CrowdyCPP 0.61.0. Additive, with one floor: the build documents select
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crowdypy
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1.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,8 +51,8 @@ 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.9.
|
|
55
|
-
bullet below.
|
|
54
|
+
**v0.9.1: the input log's session filter sends `userId` as a string, and its reads document when
|
|
55
|
+
to retry.** See the 0.9.1 bullet below; 0.9.0 added the SDK a build compiled against.
|
|
56
56
|
|
|
57
57
|
**v0.8.0: voice, channel audio, wide voxels, and pause and access refusals (CrowdyJS 18.7.0, CrowdyCPP 0.60.0).**
|
|
58
58
|
- Voice: `crowdypy.media`'s voice helpers (an optional 10-byte header per codec frame,
|
|
@@ -11,8 +11,8 @@ 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.9.
|
|
15
|
-
bullet below.
|
|
14
|
+
**v0.9.1: the input log's session filter sends `userId` as a string, and its reads document when
|
|
15
|
+
to retry.** See the 0.9.1 bullet below; 0.9.0 added the SDK a build compiled against.
|
|
16
16
|
|
|
17
17
|
**v0.8.0: voice, channel audio, wide voxels, and pause and access refusals (CrowdyJS 18.7.0, CrowdyCPP 0.60.0).**
|
|
18
18
|
- Voice: `crowdypy.media`'s voice helpers (an optional 10-byte header per codec frame,
|
|
@@ -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.9.
|
|
8
|
+
- CrowdyPy `0.9.1`
|
|
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
|
|
@@ -41,6 +41,10 @@ requirement names one exactly, the same way a caret never matches an npm prerele
|
|
|
41
41
|
- `auth.record_player_consents` and `auth.player_legal_acceptance` need ck-api v2.35.0; an
|
|
42
42
|
older API answers them with a GraphQL validation error. From v2.35.0 a gameplay token
|
|
43
43
|
waits for both consents (`LEGAL_ACCEPTANCE_REQUIRED`).
|
|
44
|
+
- The input log (`client.input_log`, 0.7.0) needs ck-api v2.39.0 or later: every app read selects
|
|
45
|
+
`replayLoggingEnabled`, which an older API refuses with a GraphQL validation error. The retryable
|
|
46
|
+
`INPUT_LOG_TEMPORARILY_UNAVAILABLE` / `INPUT_LOG_RATE_LIMITED` and the `logging_off` / `shutdown`
|
|
47
|
+
end reasons come with the ck-api release after v2.40.2.
|
|
44
48
|
- `udp.send_ranged_channel_message` needs a replication server that serves message type 32
|
|
45
49
|
(CHANNEL_MESSAGE_RANGED_REQUEST); one that does not delivers nothing.
|
|
46
50
|
- 0.8.0 selects `runtimeGate` on every token mutation (`portal.mint_app_token`,
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "crowdypy"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.1.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"
|
|
@@ -41,7 +41,6 @@ DENYLIST = (
|
|
|
41
41
|
"dev-run-buddy",
|
|
42
42
|
)
|
|
43
43
|
SKIP_DIRS = {
|
|
44
|
-
".git": "object store; holds every historical revision by construction",
|
|
45
44
|
".venv": "the developer's virtualenv; third-party code",
|
|
46
45
|
"build": "CMake build trees, regenerated per build",
|
|
47
46
|
"node_modules": "third-party dependencies",
|
|
@@ -76,6 +75,11 @@ def tree() -> Iterator[tuple[str, bytes]]:
|
|
|
76
75
|
current = stack.pop()
|
|
77
76
|
for entry in sorted(current.iterdir()):
|
|
78
77
|
rel = entry.relative_to(ROOT).as_posix()
|
|
78
|
+
if entry.name == ".git":
|
|
79
|
+
# A clone's object store, which holds every historical revision by
|
|
80
|
+
# construction, or a worktree's pointer file, which names the checkout's own
|
|
81
|
+
# path. Neither is ever packaged.
|
|
82
|
+
continue
|
|
79
83
|
if entry.is_dir():
|
|
80
84
|
if entry.name not in SKIP_DIRS:
|
|
81
85
|
stack.append(entry)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Both pins name
|
|
2
|
+
"""Both pins name published releases, promoted to THIS branch's tier of their repositories.
|
|
3
3
|
|
|
4
4
|
python scripts/ci/check_pin_tiers.py --crowdyjs <checkout> --crowdycpp <checkout> --tier dev
|
|
5
5
|
python scripts/ci/check_pin_tiers.py --crowdyjs <checkout> --crowdycpp <checkout> --from-ref
|
|
@@ -10,6 +10,11 @@ CrowdyPy's ``dev`` may pin only CrowdyJS and CrowdyCPP commits reachable from th
|
|
|
10
10
|
branch head: a promotion merges forward, so one commit satisfies every tier once it has
|
|
11
11
|
travelled the ladder, and pinning a head would make an unrelated landing turn this red.
|
|
12
12
|
The checkouts need full history (``fetch-depth: 0``).
|
|
13
|
+
|
|
14
|
+
And released: each pinned commit must be the target of a ``<tier>/v<version>`` tag of its
|
|
15
|
+
repository for the pinned version (any tier's, for the same ladder reason). Reachability
|
|
16
|
+
alone let 0.7.0 pin CrowdyJS ``ca9fbb5`` as 18.6.0 while ``dev/v18.6.0`` is ``7662d0b0``.
|
|
17
|
+
That half needs no tier, so it runs on every ref.
|
|
13
18
|
"""
|
|
14
19
|
|
|
15
20
|
from __future__ import annotations
|
|
@@ -43,6 +48,55 @@ def _from_ref() -> str | None:
|
|
|
43
48
|
return _tier_of(branch) if branch and branch != "HEAD" else None
|
|
44
49
|
|
|
45
50
|
|
|
51
|
+
def parse_tag_refs(text: str) -> dict[str, str]:
|
|
52
|
+
"""``git ls-remote --tags`` output: tag name -> the commit it points at (an annotated tag's
|
|
53
|
+
peeled ``^{}`` line wins over the tag object's own sha)."""
|
|
54
|
+
out: dict[str, str] = {}
|
|
55
|
+
for line in text.splitlines():
|
|
56
|
+
parts = line.strip().split()
|
|
57
|
+
if len(parts) != 2 or len(parts[0]) != 40 or not parts[1].startswith("refs/tags/"):
|
|
58
|
+
continue
|
|
59
|
+
sha, ref = parts
|
|
60
|
+
name = ref.removeprefix("refs/tags/")
|
|
61
|
+
if name.endswith("^{}"):
|
|
62
|
+
out[name.removesuffix("^{}")] = sha
|
|
63
|
+
else:
|
|
64
|
+
out.setdefault(name, sha)
|
|
65
|
+
return out
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def tag_verdict(commit: str, version: str, tags: dict[str, str]) -> tuple[bool, str]:
|
|
69
|
+
"""Whether ``commit`` is a published ``version``: the target of a ``<tier>/v<version>`` tag."""
|
|
70
|
+
named = [f"{tier}/v{version}" for tier in TIERS]
|
|
71
|
+
matching = [name for name in named if tags.get(name) == commit]
|
|
72
|
+
if matching:
|
|
73
|
+
return True, f"{commit[:12]} is {', '.join(matching)}"
|
|
74
|
+
elsewhere = [f"{name} is {tags[name][:12]}" for name in named if name in tags]
|
|
75
|
+
if elsewhere:
|
|
76
|
+
return False, f"{commit[:12]} is not a published {version}: {', '.join(elsewhere)}"
|
|
77
|
+
return False, f"{commit[:12]} is not a published {version}: no {' / '.join(named)} tag exists"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def tagged(repo: Path, commit: str, version: str) -> tuple[bool, str]:
|
|
81
|
+
listed = subprocess.run(
|
|
82
|
+
[
|
|
83
|
+
"git",
|
|
84
|
+
"-C",
|
|
85
|
+
str(repo),
|
|
86
|
+
"ls-remote",
|
|
87
|
+
"--tags",
|
|
88
|
+
"origin",
|
|
89
|
+
*[f"refs/tags/{tier}/v{version}*" for tier in TIERS],
|
|
90
|
+
],
|
|
91
|
+
capture_output=True,
|
|
92
|
+
text=True,
|
|
93
|
+
check=False,
|
|
94
|
+
)
|
|
95
|
+
if listed.returncode != 0:
|
|
96
|
+
return False, f"cannot list the tags of {repo}: {listed.stderr.strip()[:200]}"
|
|
97
|
+
return tag_verdict(commit, version, parse_tag_refs(listed.stdout))
|
|
98
|
+
|
|
99
|
+
|
|
46
100
|
def reachable(repo: Path, commit: str, tier: str) -> tuple[bool, str]:
|
|
47
101
|
fetched = subprocess.run(
|
|
48
102
|
[
|
|
@@ -93,23 +147,38 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
93
147
|
group.add_argument("--from-ref", action="store_true")
|
|
94
148
|
args = parser.parse_args(argv)
|
|
95
149
|
tier = args.tier or _from_ref()
|
|
96
|
-
if tier is None:
|
|
97
|
-
print(
|
|
98
|
-
"check_pin_tiers: this ref carries no tier, so the comparison was SKIPPED (a PR into dev/test/prod is judged by that base)"
|
|
99
|
-
)
|
|
100
|
-
return 0
|
|
101
150
|
pins = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["tool"]["crowdypy"]
|
|
102
151
|
failed = False
|
|
152
|
+
unreleased = False
|
|
103
153
|
for name, repo, pin in (
|
|
104
154
|
("CrowdyJS", args.crowdyjs, pins["crowdyjs"]),
|
|
105
155
|
("CrowdyCPP", args.crowdycpp, pins["crowdycpp"]),
|
|
106
156
|
):
|
|
157
|
+
ok, detail = tagged(repo, pin["commit"], pin["version"])
|
|
158
|
+
unreleased |= not ok
|
|
159
|
+
print(
|
|
160
|
+
f"check_pin_tiers: {name} {pin['version']}: {detail}",
|
|
161
|
+
file=sys.stdout if ok else sys.stderr,
|
|
162
|
+
)
|
|
163
|
+
if tier is None:
|
|
164
|
+
continue
|
|
107
165
|
ok, detail = reachable(repo, pin["commit"], tier)
|
|
108
166
|
failed |= not ok
|
|
109
167
|
print(
|
|
110
168
|
f"check_pin_tiers: {name} {pin['version']}: {detail}",
|
|
111
169
|
file=sys.stdout if ok else sys.stderr,
|
|
112
170
|
)
|
|
171
|
+
if unreleased:
|
|
172
|
+
print(
|
|
173
|
+
"check_pin_tiers: pin the commit a release tag points at (CrowdyJS's, then CrowdyCPP's).",
|
|
174
|
+
file=sys.stderr,
|
|
175
|
+
)
|
|
176
|
+
return 1
|
|
177
|
+
if tier is None:
|
|
178
|
+
print(
|
|
179
|
+
"check_pin_tiers: this ref carries no tier, so the reachability comparison was SKIPPED (a PR into dev/test/prod is judged by that base)"
|
|
180
|
+
)
|
|
181
|
+
return 0
|
|
113
182
|
if failed:
|
|
114
183
|
print(
|
|
115
184
|
f"check_pin_tiers: a CrowdyPy {tier} branch may pin only commits promoted to {tier}. "
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# GENERATED by scripts/unasync.py from src/crowdypy/domains/input_log.py. Do not edit.
|
|
2
|
+
"""The input log (``client.input_log``): recorded client inputs of an app with replay logging on.
|
|
3
|
+
|
|
4
|
+
An app with replay logging on (``App.replayLoggingEnabled``, set with ``client.apps.update``)
|
|
5
|
+
has every client input the realtime servers accept recorded. These calls read them back on
|
|
6
|
+
the app-scoped client for the app; an identity session token is refused. A player reads only
|
|
7
|
+
the sessions and inputs they sent; a holder of ``manage_apps`` on the app reads every session.
|
|
8
|
+
Inputs are kept for the input log's published retention (up to about an hour longer), so an old
|
|
9
|
+
session can still be listed after its inputs are gone. Both answer ``INPUT_LOG_UNAVAILABLE`` on a
|
|
10
|
+
deployment without input logging. From the Game API release after v2.40.2,
|
|
11
|
+
:meth:`InputLogAPI.messages` answers ``INPUT_LOG_TEMPORARILY_UNAVAILABLE`` when the log cannot be
|
|
12
|
+
read right now and ``INPUT_LOG_RATE_LIMITED`` while another read of yours is running (one per user,
|
|
13
|
+
two per app): both carry ``extensions.retryable``, so retry with the same cursor after a short
|
|
14
|
+
back-off. Earlier Game APIs answer ``INPUT_LOG_UNAVAILABLE``, or an empty page, instead.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from collections.abc import Mapping
|
|
20
|
+
from typing import Any
|
|
21
|
+
|
|
22
|
+
import msgspec
|
|
23
|
+
|
|
24
|
+
from crowdypy._generated import inputs
|
|
25
|
+
from crowdypy._generated import operations as ops
|
|
26
|
+
from crowdypy._sync.domains._base import Domain, omit_none
|
|
27
|
+
from crowdypy.utils import bigint
|
|
28
|
+
|
|
29
|
+
__all__ = ["InputLogAPI"]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _session_filter(
|
|
33
|
+
filter: inputs.InputLogSessionFilter | Mapping[str, Any] | None,
|
|
34
|
+
) -> inputs.InputLogSessionFilter | Mapping[str, Any] | None:
|
|
35
|
+
"""``userId`` as the decimal string every id is on the wire: an int went out as a JSON
|
|
36
|
+
number, safe at today's ids and unlike every other id the SDK sends."""
|
|
37
|
+
if isinstance(filter, inputs.InputLogSessionFilter):
|
|
38
|
+
# Typed str, so an int here is a caller past the type hints: exactly the case to mend.
|
|
39
|
+
user_id: Any = filter.user_id
|
|
40
|
+
if isinstance(user_id, int) and not isinstance(user_id, bool):
|
|
41
|
+
return msgspec.structs.replace(filter, user_id=bigint(user_id))
|
|
42
|
+
return filter
|
|
43
|
+
if isinstance(filter, Mapping) and isinstance(filter.get("userId"), int):
|
|
44
|
+
return {**filter, "userId": bigint(filter["userId"])}
|
|
45
|
+
return filter
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class InputLogAPI(Domain):
|
|
49
|
+
def sessions(
|
|
50
|
+
self,
|
|
51
|
+
app_id: str | int,
|
|
52
|
+
*,
|
|
53
|
+
first: int | None = None,
|
|
54
|
+
after: str | None = None,
|
|
55
|
+
filter: inputs.InputLogSessionFilter | Mapping[str, Any] | None = None,
|
|
56
|
+
) -> dict[str, Any]:
|
|
57
|
+
"""An app's recorded sessions, newest first: ``edges { cursor node }``, ``pageInfo``,
|
|
58
|
+
``totalCount``. A session is one game token's inputs.
|
|
59
|
+
|
|
60
|
+
``filter`` takes ``userId`` (another user's needs ``manage_apps``, else ``FORBIDDEN``;
|
|
61
|
+
an int is sent as its decimal string), ``from`` / ``to`` and ``messageType``. Page with
|
|
62
|
+
``first`` (default 50, max 200) and the previous page's ``pageInfo.endCursor`` as
|
|
63
|
+
``after``. A node's ``endReason`` is ``expired``, ``revoked``, ``reconnect`` or
|
|
64
|
+
``released`` as the client saw it, ``logging_off`` or ``shutdown`` from the Game API
|
|
65
|
+
release after v2.40.2, ``unrecorded``, or null while the session may still run.
|
|
66
|
+
"""
|
|
67
|
+
result: dict[str, Any] = self._request(
|
|
68
|
+
ops.INPUT_LOG_SESSIONS,
|
|
69
|
+
omit_none(
|
|
70
|
+
{
|
|
71
|
+
"appId": bigint(app_id),
|
|
72
|
+
"first": first,
|
|
73
|
+
"after": after,
|
|
74
|
+
"filter": _session_filter(filter),
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
)
|
|
78
|
+
return result
|
|
79
|
+
|
|
80
|
+
def messages(
|
|
81
|
+
self,
|
|
82
|
+
app_id: str | int,
|
|
83
|
+
game_token_id: str | int,
|
|
84
|
+
*,
|
|
85
|
+
first: int | None = None,
|
|
86
|
+
after: str | None = None,
|
|
87
|
+
filter: inputs.InputLogMessageFilter | Mapping[str, Any] | None = None,
|
|
88
|
+
) -> dict[str, Any]:
|
|
89
|
+
"""One session's recorded inputs (``game_token_id`` from :meth:`sessions`), oldest first.
|
|
90
|
+
|
|
91
|
+
``body`` is the client message in base64 (``decode_base64`` gives the bytes), from its
|
|
92
|
+
type byte up to its authentication tail, which is not recorded; ``sizeBytes`` is what
|
|
93
|
+
stored input logs are billed on. Spatial inputs carry their chunk and actor, channel
|
|
94
|
+
inputs their channel. **Keep paging while ``pageInfo.hasNextPage`` is true**, not while
|
|
95
|
+
``endCursor`` is set: a page can be short, or empty, when it reached the server's time or
|
|
96
|
+
scan limit; keep the previous cursor if one comes back null. ``filter`` takes ``from`` /
|
|
97
|
+
``to`` and ``messageTypes`` (at most 64). Another user's session answers ``NOT_FOUND``
|
|
98
|
+
without ``manage_apps``; a malformed cursor, or (from the Game API release after v2.40.2)
|
|
99
|
+
one from another session, ``BAD_USER_INPUT``.
|
|
100
|
+
"""
|
|
101
|
+
result: dict[str, Any] = self._request(
|
|
102
|
+
ops.INPUT_LOG_MESSAGES,
|
|
103
|
+
omit_none(
|
|
104
|
+
{
|
|
105
|
+
"appId": bigint(app_id),
|
|
106
|
+
"gameTokenId": bigint(game_token_id),
|
|
107
|
+
"first": first,
|
|
108
|
+
"after": after,
|
|
109
|
+
"filter": filter,
|
|
110
|
+
}
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
return result
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""The input log (``client.input_log``): recorded client inputs of an app with replay logging on.
|
|
2
|
+
|
|
3
|
+
An app with replay logging on (``App.replayLoggingEnabled``, set with ``client.apps.update``)
|
|
4
|
+
has every client input the realtime servers accept recorded. These calls read them back on
|
|
5
|
+
the app-scoped client for the app; an identity session token is refused. A player reads only
|
|
6
|
+
the sessions and inputs they sent; a holder of ``manage_apps`` on the app reads every session.
|
|
7
|
+
Inputs are kept for the input log's published retention (up to about an hour longer), so an old
|
|
8
|
+
session can still be listed after its inputs are gone. Both answer ``INPUT_LOG_UNAVAILABLE`` on a
|
|
9
|
+
deployment without input logging. From the Game API release after v2.40.2,
|
|
10
|
+
:meth:`InputLogAPI.messages` answers ``INPUT_LOG_TEMPORARILY_UNAVAILABLE`` when the log cannot be
|
|
11
|
+
read right now and ``INPUT_LOG_RATE_LIMITED`` while another read of yours is running (one per user,
|
|
12
|
+
two per app): both carry ``extensions.retryable``, so retry with the same cursor after a short
|
|
13
|
+
back-off. Earlier Game APIs answer ``INPUT_LOG_UNAVAILABLE``, or an empty page, instead.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from collections.abc import Mapping
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
import msgspec
|
|
22
|
+
|
|
23
|
+
from crowdypy._generated import inputs
|
|
24
|
+
from crowdypy._generated import operations as ops
|
|
25
|
+
from crowdypy.domains._base import Domain, omit_none
|
|
26
|
+
from crowdypy.utils import bigint
|
|
27
|
+
|
|
28
|
+
__all__ = ["InputLogAPI"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _session_filter(
|
|
32
|
+
filter: inputs.InputLogSessionFilter | Mapping[str, Any] | None,
|
|
33
|
+
) -> inputs.InputLogSessionFilter | Mapping[str, Any] | None:
|
|
34
|
+
"""``userId`` as the decimal string every id is on the wire: an int went out as a JSON
|
|
35
|
+
number, safe at today's ids and unlike every other id the SDK sends."""
|
|
36
|
+
if isinstance(filter, inputs.InputLogSessionFilter):
|
|
37
|
+
# Typed str, so an int here is a caller past the type hints: exactly the case to mend.
|
|
38
|
+
user_id: Any = filter.user_id
|
|
39
|
+
if isinstance(user_id, int) and not isinstance(user_id, bool):
|
|
40
|
+
return msgspec.structs.replace(filter, user_id=bigint(user_id))
|
|
41
|
+
return filter
|
|
42
|
+
if isinstance(filter, Mapping) and isinstance(filter.get("userId"), int):
|
|
43
|
+
return {**filter, "userId": bigint(filter["userId"])}
|
|
44
|
+
return filter
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class InputLogAPI(Domain):
|
|
48
|
+
async def sessions(
|
|
49
|
+
self,
|
|
50
|
+
app_id: str | int,
|
|
51
|
+
*,
|
|
52
|
+
first: int | None = None,
|
|
53
|
+
after: str | None = None,
|
|
54
|
+
filter: inputs.InputLogSessionFilter | Mapping[str, Any] | None = None,
|
|
55
|
+
) -> dict[str, Any]:
|
|
56
|
+
"""An app's recorded sessions, newest first: ``edges { cursor node }``, ``pageInfo``,
|
|
57
|
+
``totalCount``. A session is one game token's inputs.
|
|
58
|
+
|
|
59
|
+
``filter`` takes ``userId`` (another user's needs ``manage_apps``, else ``FORBIDDEN``;
|
|
60
|
+
an int is sent as its decimal string), ``from`` / ``to`` and ``messageType``. Page with
|
|
61
|
+
``first`` (default 50, max 200) and the previous page's ``pageInfo.endCursor`` as
|
|
62
|
+
``after``. A node's ``endReason`` is ``expired``, ``revoked``, ``reconnect`` or
|
|
63
|
+
``released`` as the client saw it, ``logging_off`` or ``shutdown`` from the Game API
|
|
64
|
+
release after v2.40.2, ``unrecorded``, or null while the session may still run.
|
|
65
|
+
"""
|
|
66
|
+
result: dict[str, Any] = await self._request(
|
|
67
|
+
ops.INPUT_LOG_SESSIONS,
|
|
68
|
+
omit_none(
|
|
69
|
+
{
|
|
70
|
+
"appId": bigint(app_id),
|
|
71
|
+
"first": first,
|
|
72
|
+
"after": after,
|
|
73
|
+
"filter": _session_filter(filter),
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
return result
|
|
78
|
+
|
|
79
|
+
async def messages(
|
|
80
|
+
self,
|
|
81
|
+
app_id: str | int,
|
|
82
|
+
game_token_id: str | int,
|
|
83
|
+
*,
|
|
84
|
+
first: int | None = None,
|
|
85
|
+
after: str | None = None,
|
|
86
|
+
filter: inputs.InputLogMessageFilter | Mapping[str, Any] | None = None,
|
|
87
|
+
) -> dict[str, Any]:
|
|
88
|
+
"""One session's recorded inputs (``game_token_id`` from :meth:`sessions`), oldest first.
|
|
89
|
+
|
|
90
|
+
``body`` is the client message in base64 (``decode_base64`` gives the bytes), from its
|
|
91
|
+
type byte up to its authentication tail, which is not recorded; ``sizeBytes`` is what
|
|
92
|
+
stored input logs are billed on. Spatial inputs carry their chunk and actor, channel
|
|
93
|
+
inputs their channel. **Keep paging while ``pageInfo.hasNextPage`` is true**, not while
|
|
94
|
+
``endCursor`` is set: a page can be short, or empty, when it reached the server's time or
|
|
95
|
+
scan limit; keep the previous cursor if one comes back null. ``filter`` takes ``from`` /
|
|
96
|
+
``to`` and ``messageTypes`` (at most 64). Another user's session answers ``NOT_FOUND``
|
|
97
|
+
without ``manage_apps``; a malformed cursor, or (from the Game API release after v2.40.2)
|
|
98
|
+
one from another session, ``BAD_USER_INPUT``.
|
|
99
|
+
"""
|
|
100
|
+
result: dict[str, Any] = await self._request(
|
|
101
|
+
ops.INPUT_LOG_MESSAGES,
|
|
102
|
+
omit_none(
|
|
103
|
+
{
|
|
104
|
+
"appId": bigint(app_id),
|
|
105
|
+
"gameTokenId": bigint(game_token_id),
|
|
106
|
+
"first": first,
|
|
107
|
+
"after": after,
|
|
108
|
+
"filter": filter,
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
return result
|
|
@@ -135,6 +135,25 @@ CASES = [
|
|
|
135
135
|
kwargs={"first": 20, "after": "c1", "filter": {"userId": "7", "messageType": 129}},
|
|
136
136
|
label="filtered",
|
|
137
137
|
),
|
|
138
|
+
# a userId given as an int goes out as the decimal string every id is on the wire
|
|
139
|
+
case(
|
|
140
|
+
InputLogAPI,
|
|
141
|
+
"sessions",
|
|
142
|
+
(42,),
|
|
143
|
+
"InputLogSessions",
|
|
144
|
+
{"appId": "42", "filter": {"userId": "9007199254740993"}},
|
|
145
|
+
kwargs={"filter": {"userId": 9007199254740993}},
|
|
146
|
+
label="int user id, mapping",
|
|
147
|
+
),
|
|
148
|
+
case(
|
|
149
|
+
InputLogAPI,
|
|
150
|
+
"sessions",
|
|
151
|
+
(42,),
|
|
152
|
+
"InputLogSessions",
|
|
153
|
+
{"appId": "42", "filter": {"userId": "7"}},
|
|
154
|
+
kwargs={"filter": inputs.InputLogSessionFilter(user_id=7)}, # type: ignore[arg-type]
|
|
155
|
+
label="int user id, struct",
|
|
156
|
+
),
|
|
138
157
|
case(
|
|
139
158
|
InputLogAPI,
|
|
140
159
|
"messages",
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""scripts/ci/check_pin_tiers.py: a pin must be a published release, not just a promoted commit."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib.util
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
ROOT = Path(__file__).resolve().parents[2]
|
|
11
|
+
SCRIPT = ROOT / "scripts" / "ci" / "check_pin_tiers.py"
|
|
12
|
+
if not SCRIPT.exists():
|
|
13
|
+
# The wheel builds run tests/unit from a copy that carries no scripts/.
|
|
14
|
+
pytest.skip("scripts/ci is not in this test tree", allow_module_level=True)
|
|
15
|
+
_spec = importlib.util.spec_from_file_location("check_pin_tiers", SCRIPT)
|
|
16
|
+
assert _spec
|
|
17
|
+
assert _spec.loader
|
|
18
|
+
check = importlib.util.module_from_spec(_spec)
|
|
19
|
+
_spec.loader.exec_module(check)
|
|
20
|
+
|
|
21
|
+
RELEASED = "7662d0b0" + "a" * 32
|
|
22
|
+
UNRELEASED = "ca9fbb50" + "b" * 32
|
|
23
|
+
TAG_OBJECT = "f00dfeed" + "c" * 32
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_parses_lightweight_and_annotated_tags_the_peeled_commit_winning() -> None:
|
|
27
|
+
tags = check.parse_tag_refs(
|
|
28
|
+
"\n".join(
|
|
29
|
+
[
|
|
30
|
+
f"{RELEASED}\trefs/tags/dev/v18.6.0",
|
|
31
|
+
f"{TAG_OBJECT}\trefs/tags/test/v18.6.0",
|
|
32
|
+
f"{RELEASED}\trefs/tags/test/v18.6.0^{{}}",
|
|
33
|
+
]
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
assert tags == {"dev/v18.6.0": RELEASED, "test/v18.6.0": RELEASED}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_a_pin_on_a_tagged_release_passes_whichever_tier_tagged_it() -> None:
|
|
40
|
+
ok, detail = check.tag_verdict(RELEASED, "18.6.0", {"dev/v18.6.0": RELEASED})
|
|
41
|
+
assert ok
|
|
42
|
+
assert "dev/v18.6.0" in detail
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_refuses_0_7_0s_pin_reachable_but_not_the_released_commit() -> None:
|
|
46
|
+
ok, detail = check.tag_verdict(UNRELEASED, "18.6.0", {"dev/v18.6.0": RELEASED})
|
|
47
|
+
assert not ok
|
|
48
|
+
assert "not a published 18.6.0: dev/v18.6.0 is 7662d0b0aaaa" in detail
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_refuses_a_version_no_tier_has_tagged() -> None:
|
|
52
|
+
ok, detail = check.tag_verdict(RELEASED, "18.9.0", {})
|
|
53
|
+
assert not ok
|
|
54
|
+
assert "no dev/v18.9.0 / test/v18.9.0 / prod/v18.9.0 tag exists" in detail
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_another_versions_tag_at_the_same_commit_does_not_count() -> None:
|
|
58
|
+
ok, _ = check.tag_verdict(RELEASED, "18.6.0", {"dev/v18.6.1": RELEASED})
|
|
59
|
+
assert not ok
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 5
|
|
3
3
|
requires-python = ">=3.12"
|
|
4
4
|
resolution-markers = [
|
|
5
5
|
"python_full_version >= '3.15'",
|
|
@@ -103,7 +103,7 @@ wheels = [
|
|
|
103
103
|
|
|
104
104
|
[[package]]
|
|
105
105
|
name = "crowdypy"
|
|
106
|
-
version = "0.9.
|
|
106
|
+
version = "0.9.1"
|
|
107
107
|
source = { editable = "." }
|
|
108
108
|
dependencies = [
|
|
109
109
|
{ name = "httpx" },
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# GENERATED by scripts/unasync.py from src/crowdypy/domains/input_log.py. Do not edit.
|
|
2
|
-
"""The input log (``client.input_log``): recorded client inputs of an app with replay logging on.
|
|
3
|
-
|
|
4
|
-
An app with replay logging on (``App.replayLoggingEnabled``, set with ``client.apps.update``)
|
|
5
|
-
has every client input the realtime servers accept recorded. These calls read them back on
|
|
6
|
-
the app-scoped client for the app; an identity session token is refused. A player reads only
|
|
7
|
-
the sessions and inputs they sent; a holder of ``manage_apps`` on the app reads every session.
|
|
8
|
-
Inputs are kept for the input log's published retention, so an old session can still be listed
|
|
9
|
-
after its inputs are gone. Both answer ``INPUT_LOG_UNAVAILABLE`` on a deployment without input
|
|
10
|
-
logging, and :meth:`InputLogAPI.messages` also answers it, retryable with the same cursor, when the
|
|
11
|
-
log cannot be read right now.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
from __future__ import annotations
|
|
15
|
-
|
|
16
|
-
from collections.abc import Mapping
|
|
17
|
-
from typing import Any
|
|
18
|
-
|
|
19
|
-
from crowdypy._generated import inputs
|
|
20
|
-
from crowdypy._generated import operations as ops
|
|
21
|
-
from crowdypy._sync.domains._base import Domain, omit_none
|
|
22
|
-
from crowdypy.utils import bigint
|
|
23
|
-
|
|
24
|
-
__all__ = ["InputLogAPI"]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class InputLogAPI(Domain):
|
|
28
|
-
def sessions(
|
|
29
|
-
self,
|
|
30
|
-
app_id: str | int,
|
|
31
|
-
*,
|
|
32
|
-
first: int | None = None,
|
|
33
|
-
after: str | None = None,
|
|
34
|
-
filter: inputs.InputLogSessionFilter | Mapping[str, Any] | None = None,
|
|
35
|
-
) -> dict[str, Any]:
|
|
36
|
-
"""An app's recorded sessions, newest first: ``edges { cursor node }``, ``pageInfo``,
|
|
37
|
-
``totalCount``. A session is one game token's inputs.
|
|
38
|
-
|
|
39
|
-
``filter`` takes ``userId`` (another user's needs ``manage_apps``, else ``FORBIDDEN``),
|
|
40
|
-
``from`` / ``to`` and ``messageType``. Page with ``first`` (default 50, max 200) and the
|
|
41
|
-
previous page's ``pageInfo.endCursor`` as ``after``.
|
|
42
|
-
"""
|
|
43
|
-
result: dict[str, Any] = self._request(
|
|
44
|
-
ops.INPUT_LOG_SESSIONS,
|
|
45
|
-
omit_none({"appId": bigint(app_id), "first": first, "after": after, "filter": filter}),
|
|
46
|
-
)
|
|
47
|
-
return result
|
|
48
|
-
|
|
49
|
-
def messages(
|
|
50
|
-
self,
|
|
51
|
-
app_id: str | int,
|
|
52
|
-
game_token_id: str | int,
|
|
53
|
-
*,
|
|
54
|
-
first: int | None = None,
|
|
55
|
-
after: str | None = None,
|
|
56
|
-
filter: inputs.InputLogMessageFilter | Mapping[str, Any] | None = None,
|
|
57
|
-
) -> dict[str, Any]:
|
|
58
|
-
"""One session's recorded inputs (``game_token_id`` from :meth:`sessions`), oldest first.
|
|
59
|
-
|
|
60
|
-
``body`` is the client message in base64 (``decode_base64`` gives the bytes), from its
|
|
61
|
-
type byte up to its authentication tail, which is not recorded; ``sizeBytes`` is what
|
|
62
|
-
stored input logs are billed on. Spatial inputs carry their chunk and actor, channel
|
|
63
|
-
inputs their channel. **Keep paging while ``pageInfo.hasNextPage`` is true**: a page can
|
|
64
|
-
be short, or empty, when it reached the server's time or scan limit. ``filter`` takes
|
|
65
|
-
``from`` / ``to`` and ``messageTypes`` (at most 64). Another user's session answers
|
|
66
|
-
``NOT_FOUND`` without ``manage_apps``.
|
|
67
|
-
"""
|
|
68
|
-
result: dict[str, Any] = self._request(
|
|
69
|
-
ops.INPUT_LOG_MESSAGES,
|
|
70
|
-
omit_none(
|
|
71
|
-
{
|
|
72
|
-
"appId": bigint(app_id),
|
|
73
|
-
"gameTokenId": bigint(game_token_id),
|
|
74
|
-
"first": first,
|
|
75
|
-
"after": after,
|
|
76
|
-
"filter": filter,
|
|
77
|
-
}
|
|
78
|
-
),
|
|
79
|
-
)
|
|
80
|
-
return result
|