crowdypy 0.30.0.dev1__tar.gz → 0.31.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.
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/MIGRATION.md +18 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/PKG-INFO +3 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/README.md +2 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/docs/compatibility.md +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/docs/e2e-coverage.md +1 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/docs/parity-matrix.md +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/replication.hpp +3 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/replication_binding.cpp +4 -2
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/pyproject.toml +5 -5
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_version.py +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_replication.py +46 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/uv.lock +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/CMakeLists.txt +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/PROVENANCE.md +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/world_data.hpp +34 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/enums.hpp +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/operations.hpp +99 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/json.hpp +14 -4
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/connection.hpp +26 -8
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/types.hpp +8 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/package.json +1 -1
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/json.cpp +33 -5
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/replication/connection.cpp +32 -12
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/session/chunk_store.cpp +1 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/.gitattributes +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/.gitignore +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/.gitleaks.toml +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/AGENTS.md +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/CMakeLists.txt +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/LICENSE +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/SECURITY.md +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/benchmarks/README.md +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/benchmarks/bench_replication.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/licenses/OpenSSL-LICENSE.txt +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/common.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/module.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/session_binding.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/voice_binding.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/native/wire_binding.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/Actor.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/Actors.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/BatchLookupActors.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/CreateActor.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/DeleteActor.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/UpdateActor.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/actors/UpdateActorState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/AppAccessTiers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/AppFeatures.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/AppGrantMemberCandidates.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/AppUserAccessByApp.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/ArchiveAccessTier.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/ClaimFreeAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/CreateAccessTier.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/DefineAppFeature.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/GrantAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/GrantMyAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/GrantTierFeature.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/MyAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/RevokeAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/RevokeTierFeature.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/RuntimePermissions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/SuspendAppAccess.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/TierFeatures.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/appAccess/UpdateAccessTier.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/App.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/AppBySlug.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/AppDiscovery.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/AppRecording.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/AppsForOrg.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/ArchiveApp.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/CodeAdmissions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/CreateApp.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/MarketplaceApps.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/MyApps.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/PlaceableDatacenters.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/SetAppRequiredDocuments.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/apps/UpdateApp.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/auth/Logout.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/auth/LogoutAllDevices.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/avatars/Avatars.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/billing/AppBudget.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/billing/AppBudgets.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/billing/SetAppBudget.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/billing/WalletBalance.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/billing/WalletTransactions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/AddChannelMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/BanChannelMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/Channel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/ChannelMembers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/ChannelPolicy.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/ChannelRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/Channels.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/CreateChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/CreateChannelRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/DeleteChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/DeleteChannelRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/JoinChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/LeaveChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/MyChannels.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/RemoveChannelMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/RequestToJoinChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/SetChannelMemberRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/SetChannelPolicy.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/UnbanChannelMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/UpdateChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/channels/UpdateChannelRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/GetChunk.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/GetChunkLods.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/GetChunksByDistance.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/GetVoxelList.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/UpdateChunk.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/UpdateChunkLods.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/chunks/UpdateChunkState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/crowdyStudio/CrowdyStudio.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/exec/Exec.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/gameApps/GameApps.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/grids/CreateGridChannel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/grids/GridChannels.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/grids/MintGridToken.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/host/Host.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/inputLog/InputLogMessages.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/inputLog/InputLogSessions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/AppManagedPlayerMods.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/DeleteManagedPlayer.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/EndManagedPlayerSessions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/ManagedPlayer.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/ManagedPlayerFields.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/ManagedPlayers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/OrgManagedPlayerSettings.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/OrgSigningKeyFields.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/OrgSigningKeys.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/ProvisionManagedPlayers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/RegisterOrgSigningKey.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/RevokeOrgSigningKey.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/SetAppManagedPlayerMods.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/managedPlayers/UpdateManagedPlayer.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/marketplace/Marketplace.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/moderation/EscalateSafetyReport.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/moderation/ResolveSafetyReport.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/moderation/SafetyReportFields.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/moderation/SafetyReports.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/CreateOrgRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/CreateOrgToken.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/CreateOrganization.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/DeleteOrgRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/InviteOrgMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/MemberRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/MyOrganizations.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/OrgMembers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/OrgPermissions.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/OrgRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/OrgTokens.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/Organization.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/OrganizationBySlug.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/RemoveOrgMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/RevokeOrgToken.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/UpdateOrgMemberRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/UpdateOrgRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/organizations/UpdateOrgToken.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/payments/CapturePaypalCheckout.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/payments/CreateCheckout.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/payments/MyCheckouts.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/platform/PlatformConfig.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/platform/TerritoryPolicies.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/playerWallet/PlayerWallet.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/quotas/DeleteQuota.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/quotas/EffectiveQuota.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/quotas/QuotasForApp.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/quotas/QuotasForOrg.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/quotas/SetQuota.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/AcceptContact.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/BlockPlayer.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/CommSettingsFields.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/ContactRequests.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/FileSafetyReport.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/MyBlocks.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/MyCommSettings.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/MyContacts.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/PlayerContactFields.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/RemoveContact.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/RequestContact.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/RequestParentalConsent.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/SetMyCommSettings.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/safety/UnblockPlayer.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/serverStatus/ActiveGraphQLServers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/serverStatus/GameClientBootstrap.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/serverStatus/GraphqlServers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/serverStatus/ServerWithLeastClients.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/serverStatus/VersionInfo.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/sharedEnvironment/SharedEnvironment.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/state/DeleteUserAppState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/state/UpdateUserAppState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/state/UserAppState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/state/UserAppStates.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/AddTeamMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/BanTeamMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/CreateTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/CreateTeamRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/DeleteTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/DeleteTeamRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/JoinTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/LeaveTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/MyTeams.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/RemoveTeamMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/RequestToJoinTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/SetTeamMemberRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/SetTeamPolicy.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/Team.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/TeamMembers.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/TeamPolicy.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/TeamRoles.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/Teams.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/UnbanTeamMember.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/UpdateTeam.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teams/UpdateTeamRole.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/teleport/TeleportRequest.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/usage/AppGraphqlOperations.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/usage/AppUsageSummary.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/usage/PlayerPulse.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/DeleteMyAccount.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/FreePlayWindow.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/Me.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/PlayerProfile.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/UpdateGamertag.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/UpdateUserState.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/users/User.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/voxels/ListVoxelUpdatesByDistance.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/voxels/ListVoxels.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/voxels/RollbackVoxelUpdates.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/voxels/UpdateVoxel.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/operations/voxels/VoxelUpdateHistory.graphql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/schema.gql +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/_pins.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/assert_default_origin.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/build_openssl.sh +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/check_content_policy.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/check_pin_tiers.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/cibw_before_all_linux.sh +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/resolve-release-tier.sh +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/resolve-release-tier.test.sh +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/resolve_pypi_version.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/stamp_version.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/ci/verify_artifacts.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/codegen.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/schema_drift.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/schema_sync.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/unasync.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/scripts/vendor_crowdycpp.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_concurrency.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_default_origin.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_generated/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_generated/enums.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_generated/inputs.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_generated/operations.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_grid.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_native.pyi +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_operation.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/client.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/_base.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/actors.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/admin.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/app_access.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/apps.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/auth.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/avatars.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/billing.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/channels.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/chunks.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_agent.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/crowdy_studio_github.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/discovery.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/exec.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/game_apps.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/grids.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/host.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/input_log.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/managed_players.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/marketplace.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/moderation.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/organizations.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/payments.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/platform.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/player_wallet.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/portal.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/quotas.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/safety.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/server_status.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/shared_environment.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/state.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/teams.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/teleport.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/udp.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/usage.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/users.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/domains/voxels.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/graphql.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/grid_scope.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/actions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/kit.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/mirror.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/arenas.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/encounters.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/instances.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/leaderboards.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/market.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/matchmaking.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/minigames.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/npcs.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/player.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/presence.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/racing.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/sessions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/tables.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/tactics.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/territory.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/modules/world.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/protocol.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/realtime.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/runtime.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/social.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/store.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/topology.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/kit/wire.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/rediscover.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/stores.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/_sync/world.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/auth_state.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/client.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/codecs.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/datacenter_redirect.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/_base.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/actors.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/admin.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/app_access.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/apps.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/auth.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/avatars.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/billing.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/channels.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/chunks.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/crowdy_studio.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/crowdy_studio_agent.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/crowdy_studio_github.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/discovery.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/exec.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/game_apps.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/grids.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/host.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/input_log.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/managed_players.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/marketplace.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/moderation.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/organizations.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/payments.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/platform.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/player_wallet.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/portal.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/quotas.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/safety.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/server_status.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/shared_environment.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/state.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/teams.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/teleport.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/udp.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/usage.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/users.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/domains/voxels.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/enums.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/errors.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/estate.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/exec_gateway.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/graphql.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/grid_scope.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/inputs.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/actions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/kit.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/mirror.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/arenas.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/encounters.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/instances.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/leaderboards.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/market.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/matchmaking.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/minigames.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/npcs.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/player.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/presence.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/racing.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/sessions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/tables.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/tactics.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/territory.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/modules/world.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/protocol.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/realtime.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/runtime.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/social.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/store.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/topology.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/kit/wire.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/lb_cookie.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/media.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/pkce.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/agent_errors.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/agent_types.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/json_schema.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/schemas.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/schemas.v1.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/player_host/types.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/py.typed +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/rediscover.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/replication.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/session.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/stores.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/client_tick_interval.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/controller.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/diagnostics.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/draft.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/github_draft_store.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/github_new_repo.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/layout.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/models.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/studio/starter_projects.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/subscriptions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/sync.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/utils.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/wire.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/src/crowdypy/world.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/conftest.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/conftest.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_identity.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_idle_release.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_input_log.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_open_grid_exec_gateway.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_ranged_channel.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_replication.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_studio.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_teen_safety.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_world.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/e2e/test_e2e_world_data.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/README.md +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/binary-wire-fixtures.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/exec-client-frames.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/kit-protocol.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/player-host.v1.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/fixtures/voice-frames.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/__init__.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_crowdycpp_roots.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_input_log_reads.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_managed_players.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_org_domains.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_safety_domains.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_social_domains.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_studio_exec_domains.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/domains/test_world_domains.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_check_pin_tiers.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_core.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_durable_stores.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_estate_moves.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_exec_gateway.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_fixture_provenance.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_github_draft_store.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_grid_scope.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_kit.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_kit_protocol.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_lazy_exports.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_lb_cookie.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_player_host.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_refusals.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_release_versions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_sdk_audience.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_studio_controller.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_studio_diagnostics.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_studio_game_editor.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_studio_layout.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_subscriptions.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_transport.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_udp_api.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_udp_first_send_retry.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_voice_frames.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_wire.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tests/unit/test_world_session.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tools/e2e/provision.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tools/fixtures/player_host.mjs +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tools/parity/classifications.toml +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/tools/parity/parity.py +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/LICENSE +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/cmake/CheckPublicHeaders.cmake +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/cmake/CrowdyCPPConfig.cmake.in +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/cmake/CrowdyFindOpus.cmake +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/cmake/studio_layout_fixture.hpp.in +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/client.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/base64.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/bytes.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/clock.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/crypto.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/logger.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/result.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/spsc.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/core/uuid.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/crowdy.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/default_origin.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/admin.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/auth.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_agent.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/crowdy_studio_github.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/discovery.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/domain_base.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/exec.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/game_apps.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/grids.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/groups.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/marketplace.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/player_wallet.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/portal.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/realtime_control.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/safety.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/server_status.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/types.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/users.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/game_session.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/async_scope.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/auth_state.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/cancel.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/datacenter_redirect.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/dispatcher.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/errors.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/estate.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/graphql_client.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/http.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/rediscover.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/subscription_client.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/websocket.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/actions.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/economy.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/genres.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/kit.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/mirror.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/modules.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/protocol.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/realtime.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/runtime.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/social.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/topology.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/kit/wire.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/opus.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/video_frames.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/media/voice_frames.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/adapter.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/player_host.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/schemas.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/player_host/types.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/session_provider.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/udp_socket.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/chunk_store.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/codec.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/durable.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/keys.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/stores.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/session/world_session.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/controller.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/diagnostics.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/editor.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/github_layout.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/integration.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/layout.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/models.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/studio/runtime.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/codec.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/wire/protocol.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/world.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/client.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/base64.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/clock.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/crypto_default_unavailable.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/crypto_openssl.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/crypto_unavailable.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/logger.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/core/uuid.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/domains/exec.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/game_session.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/async_transport.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/auth_state.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/error_extensions.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/errors.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/graphql_client.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/http_curl.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/http_none.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/subscription_client.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_curl.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/graphql/websocket_none.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/economy.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/genres.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/mirror.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/modules.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/protocol.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/runtime.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/kit/topology.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/media/opus.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/player_host/schemas.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/player_host/types.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/replication/socket_errors.hpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/replication/udp_socket.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/session/world_session.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/studio/diagnostics.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/studio/editor.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/src/studio/integration.cpp +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/LICENSE +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.c +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/third_party/yyjson/yyjson.h +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdy-studio-diagnostics.v1.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/crowdyjs-studio-layout.v1.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-client-frames.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/exec-gateway-cases.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/kit-protocol.json +0 -0
- {crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/tools/parity/fixtures/voice-frames.json +0 -0
|
@@ -3,6 +3,24 @@
|
|
|
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.31.0
|
|
7
|
+
|
|
8
|
+
Vendors CrowdyCPP 0.83.0 (the Unreal team's hardening, A1 to A6). Nothing new is needed on the tier.
|
|
9
|
+
|
|
10
|
+
- **MessagePack maps with an array, map, binary or extension key fail to decode** (a kit actor state
|
|
11
|
+
or a mod's reply): a key nested in keys was escaped again at every level, so about 130 bytes asked
|
|
12
|
+
for gigabytes and froze or crashed the decoding thread. Number, boolean and nil keys still become
|
|
13
|
+
their JSON text.
|
|
14
|
+
- **A NaN or an infinity in a decoded value is written as `null` in place** when the native core
|
|
15
|
+
serialises it, instead of turning the whole value into `null`.
|
|
16
|
+
- **Unchanged keyframes of more than 8 actors no longer count as gameplay input** for
|
|
17
|
+
`idle_release_guard_ms`, so a genuine idle release ends a session whose host keeps many actors'
|
|
18
|
+
keyframes going.
|
|
19
|
+
- **A legacy `COMMAND_RECONNECT` (22) is paced** (`client.udp.connect(legacy_reconnect_window_ms=...)`,
|
|
20
|
+
30 s): one per assignment, each at least a window after the last honoured one, the window
|
|
21
|
+
doubling to 10 minutes; the rest are dropped and counted in
|
|
22
|
+
`stats()["legacy_reconnects_suppressed"]`. `0` honours every verified one, as before.
|
|
23
|
+
|
|
6
24
|
## 0.30.0
|
|
7
25
|
|
|
8
26
|
CrowdyJS 18.30.0 and CrowdyCPP 0.82.0 (the ChunkStore rework). Box reads and `since` need ck-api
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crowdypy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.0.dev1
|
|
4
4
|
Summary: Official Python SDK for Crowded Kingdoms: typed GraphQL clients and a native UDP replication core
|
|
5
5
|
Keywords: crowded-kingdoms,multiplayer,replication,graphql,sdk,udp
|
|
6
6
|
Author: Crowded Kingdoms
|
|
@@ -51,6 +51,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.31.0: hardening from CrowdyCPP 0.83.0.** MessagePack keys that are containers are refused (a nested key blew up memory), a NaN serialises as `null` in place, unchanged keyframes of many actors are not gameplay input, and a legacy reconnect command is paced (`legacy_reconnect_window_ms`). See [MIGRATION.md](MIGRATION.md).
|
|
55
|
+
|
|
54
56
|
**v0.30.0: the ChunkStore rework.** `ensure_around` reads only what is missing, as boxes, paged; `set_voxel` is paced and returns an edit id, and an edit the server refuses or never echoes is undone (`on_edit_refused`); a replaced chunk is read again and a reconnect catches up; realtime edits are no longer written back. CrowdyJS 18.30.0 and CrowdyCPP 0.82.0. See [MIGRATION.md](MIGRATION.md).
|
|
55
57
|
|
|
56
58
|
**v0.29.0: reconnect commands verify, bound control frames, and `chunk_changed`.** A server's `COMMAND_RECONNECT` verifies again; against replication servers v0.45.0 the reconnect and release frames carry a per-assignment nonce under their HMAC, so one captured earlier is refused (`stats()["stale_bound_control"]`); `chunk_changed` reports a chunk a hub's or mod's `world.set_chunk` replaced. CrowdyJS 18.29.0 and CrowdyCPP 0.81.0. See [MIGRATION.md](MIGRATION.md).
|
|
@@ -11,6 +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.31.0: hardening from CrowdyCPP 0.83.0.** MessagePack keys that are containers are refused (a nested key blew up memory), a NaN serialises as `null` in place, unchanged keyframes of many actors are not gameplay input, and a legacy reconnect command is paced (`legacy_reconnect_window_ms`). See [MIGRATION.md](MIGRATION.md).
|
|
15
|
+
|
|
14
16
|
**v0.30.0: the ChunkStore rework.** `ensure_around` reads only what is missing, as boxes, paged; `set_voxel` is paced and returns an edit id, and an edit the server refuses or never echoes is undone (`on_edit_refused`); a replaced chunk is read again and a reconnect catches up; realtime edits are no longer written back. CrowdyJS 18.30.0 and CrowdyCPP 0.82.0. See [MIGRATION.md](MIGRATION.md).
|
|
15
17
|
|
|
16
18
|
**v0.29.0: reconnect commands verify, bound control frames, and `chunk_changed`.** A server's `COMMAND_RECONNECT` verifies again; against replication servers v0.45.0 the reconnect and release frames carry a per-assignment nonce under their HMAC, so one captured earlier is refused (`stats()["stale_bound_control"]`); `chunk_changed` reports a chunk a hub's or mod's `world.set_chunk` replaced. CrowdyJS 18.29.0 and CrowdyCPP 0.81.0. See [MIGRATION.md](MIGRATION.md).
|
|
@@ -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.
|
|
8
|
+
- CrowdyPy `0.31.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
|
|
@@ -73,6 +73,7 @@ suites.
|
|
|
73
73
|
| 2026-10-31 | dev tier (ck-api v2.60.0), app `96701660793088`; managed players in app `107209219611648` | `crowdypy 0.23.0.dev1` from PyPI (installed into a clean Python 3.12 with uv) | the teen safety scenarios that register no one (the Minecraft challenge refused; the managed adult; the managed 12-year-old and the blocked country refused): 3 passed |
|
|
74
74
|
| 2026-11-03 | dev tier (ck-api v2.61.0, players from 13), app `96701660793088`, the `harness` provisioning token with `CROWDY_E2E_EMAIL=crowdy-e2e-py@test.invalid`; the existing player and the managed players of the 13+ test org (app `107209219611648`) | 0.24.0 (branch `feat/13plus-v2.61`: CrowdyJS `dev/v18.25.0`, vendoring CrowdyCPP `dev/v0.76.0`) | the teen safety suite only, two registrations in all and none under 13: the sign-up with an age (its account deleted), the DE sign-up refused, the Minecraft challenge, the existing accounts (`hasSafetyModerator` as the org admin and `None` as the outsider, its own sessions, every row's `regionCode`) and the managed players (UA-09 and UA without a region refused, UA-30 admitted): 5 passed. The two-player scenarios failed at their setup: dev now asks an org admin for the developer documents, and the CK org admin behind `CROWDY_E2E_OWNER_EMAIL` has not accepted them, so its `grant` is refused ("Accept the current developer terms (recordDeveloperConsents) before creating or administering an organization"); they were not rerun with another owner, which would have registered two more players |
|
|
75
75
|
| 2026-11-11 | dev tier (ck-api v2.65.0, the email gate), app `96701660793088`, the `harness` provisioning token with `CROWDY_E2E_EMAIL=crowdy-e2e-py@test.invalid` | 0.26.0 (branch `feat/email-confirmation-required`: CrowdyJS `dev/v18.27.0`, vendoring CrowdyCPP `dev/v0.78.0`) | identity, replication and teen safety suites: 12 passed, 2 skipped (the teen safety suite's existing player and managed players, not configured). Accounts the provisioning token makes are not asked to confirm their email, so every mint went through |
|
|
76
|
+
| 2026-11-12 | dev tier (ck-api v2.68.1, replication servers v0.45.0), app `96701660793088`, the `harness` provisioning token with `CROWDY_E2E_EMAIL=crowdy-e2e-py@test.invalid` | 0.30.0 (`dev` at `60de17f`, vendoring CrowdyCPP `dev/v0.82.0`: the ChunkStore rework) | world and replication suites: 4 passed |
|
|
76
77
|
|
|
77
78
|
## Not covered here
|
|
78
79
|
|
|
@@ -5,7 +5,7 @@ Generated by `tools/parity/parity.py`; do not edit by hand. Classifications live
|
|
|
5
5
|
## Target
|
|
6
6
|
|
|
7
7
|
- CrowdyJS: `18.30.0` at `4840d76029ffb15a6de6232dab9336f2e9ab6514`
|
|
8
|
-
- CrowdyCPP (native core): `0.
|
|
8
|
+
- CrowdyCPP (native core): `0.83.0` at `73eb66cdf1c435bc67e405b9a5bd606740209df2`
|
|
9
9
|
- schema.gql identical to CrowdyJS's: yes
|
|
10
10
|
- Gate mode: strict portable parity (every portable gap is release-blocking)
|
|
11
11
|
|
|
@@ -396,6 +396,7 @@ struct ConnectionOptions {
|
|
|
396
396
|
std::int64_t advertiseIntervalMs = 15 * 1000;
|
|
397
397
|
std::int64_t watchdogSilenceMs = 0;
|
|
398
398
|
std::int64_t idleReleaseGuardMs = 60 * 1000;
|
|
399
|
+
std::int64_t legacyReconnectWindowMs = 30 * 1000;
|
|
399
400
|
std::size_t ringCapacity = 4096;
|
|
400
401
|
int socketRecvBufferBytes = 1 << 20;
|
|
401
402
|
int socketSendBufferBytes = 1 << 20;
|
|
@@ -432,6 +433,7 @@ class PyConnection {
|
|
|
432
433
|
config.advertiseIntervalMs = options.advertiseIntervalMs;
|
|
433
434
|
config.watchdogSilenceMs = options.watchdogSilenceMs;
|
|
434
435
|
config.idleReleaseGuardMs = options.idleReleaseGuardMs;
|
|
436
|
+
config.legacyReconnectWindowMs = options.legacyReconnectWindowMs;
|
|
435
437
|
config.ringCapacity = options.ringCapacity;
|
|
436
438
|
config.socketRecvBufferBytes = options.socketRecvBufferBytes;
|
|
437
439
|
config.socketSendBufferBytes = options.socketSendBufferBytes;
|
|
@@ -739,6 +741,7 @@ class PyConnection {
|
|
|
739
741
|
d["reconnects"] = s.reconnects;
|
|
740
742
|
d["idle_releases_after_input"] = s.idleReleasesAfterInput;
|
|
741
743
|
d["stale_bound_control"] = s.staleBoundControl;
|
|
744
|
+
d["legacy_reconnects_suppressed"] = s.legacyReconnectsSuppressed;
|
|
742
745
|
d["last_server_epoch_ms"] = s.lastServerEpochMs;
|
|
743
746
|
nb::dict sentByType;
|
|
744
747
|
nb::dict receivedByType;
|
|
@@ -232,7 +232,7 @@ void register_replication(nb::module_& m) {
|
|
|
232
232
|
bool advertiseCapabilities, std::int64_t advertiseIntervalMs,
|
|
233
233
|
std::int64_t watchdogSilenceMs, std::size_t ringCapacity, int recvBuffer,
|
|
234
234
|
int sendBuffer, bool bundleSends, int bundleWindowMs, std::int64_t providerTimeoutMs,
|
|
235
|
-
std::int64_t idleReleaseGuardMs) {
|
|
235
|
+
std::int64_t idleReleaseGuardMs, std::int64_t legacyReconnectWindowMs) {
|
|
236
236
|
ConnectionOptions o;
|
|
237
237
|
o.appId = appId;
|
|
238
238
|
o.manualPump = manualPump;
|
|
@@ -249,6 +249,7 @@ void register_replication(nb::module_& m) {
|
|
|
249
249
|
o.bundleSends = bundleSends;
|
|
250
250
|
o.bundleWindowMs = bundleWindowMs;
|
|
251
251
|
o.idleReleaseGuardMs = idleReleaseGuardMs;
|
|
252
|
+
o.legacyReconnectWindowMs = legacyReconnectWindowMs;
|
|
252
253
|
new (self) PyConnection(o, token, gameTokenId, expiresAtMs, providerTimeoutMs);
|
|
253
254
|
},
|
|
254
255
|
nb::arg("app_id"), nb::arg("token"), nb::arg("game_token_id"),
|
|
@@ -260,7 +261,8 @@ void register_replication(nb::module_& m) {
|
|
|
260
261
|
nb::arg("socket_recv_buffer_bytes") = 1 << 20,
|
|
261
262
|
nb::arg("socket_send_buffer_bytes") = 1 << 20, nb::arg("bundle_sends") = true,
|
|
262
263
|
nb::arg("bundle_window_ms") = 1, nb::arg("provider_timeout_ms") = 30000,
|
|
263
|
-
nb::arg("idle_release_guard_ms") = 60 * 1000
|
|
264
|
+
nb::arg("idle_release_guard_ms") = 60 * 1000,
|
|
265
|
+
nb::arg("legacy_reconnect_window_ms") = 30 * 1000)
|
|
264
266
|
.def_prop_ro("bridge", &PyConnection::bridge, nb::rv_policy::reference_internal)
|
|
265
267
|
.def("connect", &PyConnection::connect)
|
|
266
268
|
.def("disconnect", &PyConnection::disconnect)
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "crowdypy"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.31.0.dev1"
|
|
8
8
|
description = "Official Python SDK for Crowded Kingdoms: typed GraphQL clients and a native UDP replication core"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT AND Apache-2.0"
|
|
@@ -123,10 +123,10 @@ version = "18.30.0"
|
|
|
123
123
|
commit = "4840d76029ffb15a6de6232dab9336f2e9ab6514"
|
|
124
124
|
|
|
125
125
|
[tool.crowdypy.crowdycpp]
|
|
126
|
-
version = "0.
|
|
127
|
-
tag = "dev/v0.
|
|
128
|
-
commit = "
|
|
129
|
-
tree-sha256 = "
|
|
126
|
+
version = "0.83.0"
|
|
127
|
+
tag = "dev/v0.83.0"
|
|
128
|
+
commit = "73eb66cdf1c435bc67e405b9a5bd606740209df2"
|
|
129
|
+
tree-sha256 = "fc2d2a460cdc403a9a389e99fa6c402c95c87df05529bbe08167bb5bf20cdffd"
|
|
130
130
|
|
|
131
131
|
# schema.gql and operations/ are CrowdyJS's, copied from the commit pinned above by
|
|
132
132
|
# scripts/schema_sync.py, which records these hashes and re-derives them in CI.
|
|
@@ -351,6 +351,52 @@ def test_an_idle_release_right_after_input_reassigns(server: FakeServer) -> None
|
|
|
351
351
|
assert guardless.assigned == 1
|
|
352
352
|
|
|
353
353
|
|
|
354
|
+
def command_reconnect(key: str = TOKEN) -> bytes:
|
|
355
|
+
prefix = bytes([MessageType.COMMAND_RECONNECT])
|
|
356
|
+
return prefix + hmac.new(key.encode("latin-1"), prefix, hashlib.sha256).digest()
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def test_a_legacy_reconnect_is_paced(server: FakeServer) -> None:
|
|
360
|
+
# CrowdyCPP 0.83.0: a legacy 22 signs fixed bytes, so a captured one verifies for the token's
|
|
361
|
+
# life. One is honoured, and another moments later is dropped and counted.
|
|
362
|
+
provider = Provider(server)
|
|
363
|
+
with ReplicationConnection(provider, token(), app_id=7, **QUIET) as connection:
|
|
364
|
+
for honoured in (True, False):
|
|
365
|
+
# A reassignment finishes before the next send: it goes out on the new socket.
|
|
366
|
+
wait_for_state(connection, ConnState.CONNECTED)
|
|
367
|
+
connection.send_heartbeat((0, 0, 0), ME)
|
|
368
|
+
connection.flush_sends()
|
|
369
|
+
server.recv() # the server learns where this assignment's socket is
|
|
370
|
+
before = provider.assigned
|
|
371
|
+
server.send(command_reconnect())
|
|
372
|
+
deadline = time.monotonic() + 2
|
|
373
|
+
while time.monotonic() < deadline:
|
|
374
|
+
connection.wait(0.05)
|
|
375
|
+
connection.poll()
|
|
376
|
+
if honoured and provider.assigned > before:
|
|
377
|
+
break
|
|
378
|
+
if not honoured and connection.stats()["legacy_reconnects_suppressed"] == 1:
|
|
379
|
+
break
|
|
380
|
+
assert provider.assigned == (before + 1 if honoured else before)
|
|
381
|
+
assert connection.stats()["legacy_reconnects_suppressed"] == 1
|
|
382
|
+
|
|
383
|
+
unpaced = Provider(server)
|
|
384
|
+
with ReplicationConnection(
|
|
385
|
+
unpaced, token(), app_id=7, legacy_reconnect_window_ms=0, **QUIET
|
|
386
|
+
) as connection:
|
|
387
|
+
for n in (2, 3):
|
|
388
|
+
wait_for_state(connection, ConnState.CONNECTED)
|
|
389
|
+
connection.send_heartbeat((0, 0, 0), ME)
|
|
390
|
+
connection.flush_sends()
|
|
391
|
+
server.recv()
|
|
392
|
+
server.send(command_reconnect())
|
|
393
|
+
deadline = time.monotonic() + 2
|
|
394
|
+
while unpaced.assigned < n and time.monotonic() < deadline:
|
|
395
|
+
connection.wait(0.05)
|
|
396
|
+
connection.poll()
|
|
397
|
+
assert unpaced.assigned == n
|
|
398
|
+
|
|
399
|
+
|
|
354
400
|
def test_a_release_that_does_not_verify_is_ignored(server: FakeServer) -> None:
|
|
355
401
|
provider = Provider(server)
|
|
356
402
|
with ReplicationConnection(provider, token(), app_id=7, **QUIET) as connection:
|
|
@@ -5,4 +5,4 @@ pins under `[tool.crowdypy.crowdycpp]`. It is written by
|
|
|
5
5
|
`scripts/vendor_crowdycpp.py` and checked in CI by re-deriving it from that commit.
|
|
6
6
|
Do not edit it: change CrowdyCPP, release it on the same tier, and re-vendor.
|
|
7
7
|
|
|
8
|
-
Vendored from `dev/v0.
|
|
8
|
+
Vendored from `dev/v0.83.0` (`73eb66cdf1c435bc67e405b9a5bd606740209df2`).
|
{crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/domains/world_data.hpp
RENAMED
|
@@ -331,6 +331,40 @@ class VoxelsAPI : public DomainBase {
|
|
|
331
331
|
listByDistanceAsync(area.toInput(appId), std::move(cb));
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
/// listInRegion() selecting only what rebuilds a cell: each chunk's `coordinates`, and each
|
|
335
|
+
/// edit's `location`, `voxelType` and `state` (operation ListVoxelUpdatesByDistanceCells).
|
|
336
|
+
/// The log keeps one row per position, the latest write, so a chunk's answer is bounded by
|
|
337
|
+
/// the positions ever edited in it, not by its history.
|
|
338
|
+
graphql::Json listInRegionCells(std::string_view appId, const ChunkRegion& area) const {
|
|
339
|
+
graphql::JVal vars;
|
|
340
|
+
vars["input"] = area.toInput(appId);
|
|
341
|
+
return execUnwrap(gen::voxels::kListVoxelUpdatesByDistanceCellsDocument, vars);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
void listInRegionCellsAsync(std::string_view appId, const ChunkRegion& area,
|
|
345
|
+
graphql::GraphQLCallback cb) const {
|
|
346
|
+
graphql::JVal vars;
|
|
347
|
+
vars["input"] = area.toInput(appId);
|
|
348
|
+
execUnwrapAsync(gen::voxels::kListVoxelUpdatesByDistanceCellsDocument, vars, {},
|
|
349
|
+
std::move(cb));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/// listInRegionCells() with each edit's `createdAt`, the server time of its latest write,
|
|
353
|
+
/// for a reader that orders edits by time (operation ListVoxelUpdatesByDistanceCellsTimed).
|
|
354
|
+
graphql::Json listInRegionCellsTimed(std::string_view appId, const ChunkRegion& area) const {
|
|
355
|
+
graphql::JVal vars;
|
|
356
|
+
vars["input"] = area.toInput(appId);
|
|
357
|
+
return execUnwrap(gen::voxels::kListVoxelUpdatesByDistanceCellsTimedDocument, vars);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
void listInRegionCellsTimedAsync(std::string_view appId, const ChunkRegion& area,
|
|
361
|
+
graphql::GraphQLCallback cb) const {
|
|
362
|
+
graphql::JVal vars;
|
|
363
|
+
vars["input"] = area.toInput(appId);
|
|
364
|
+
execUnwrapAsync(gen::voxels::kListVoxelUpdatesByDistanceCellsTimedDocument, vars, {},
|
|
365
|
+
std::move(cb));
|
|
366
|
+
}
|
|
367
|
+
|
|
334
368
|
/// Durable single-voxel update (requires update_voxel_data permission).
|
|
335
369
|
graphql::Json update(const graphql::JVal& input) const {
|
|
336
370
|
graphql::JVal vars;
|
{crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/generated/enums.hpp
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Inputs: operations/**/*.graphql and schema.gql (synced from the published
|
|
4
4
|
// SDL at https://docs.crowdedkingdoms.com/schema/game-api.graphql).
|
|
5
5
|
// schema.gql sha256: 13094c2757b41d50c8aee996009a00d0995ef597bd792c778c25585576a45f33
|
|
6
|
-
// operations sha256:
|
|
6
|
+
// operations sha256: eca7de01bfc5d967afbf6c230b6596a9ae42bf9a584ac1021c9f6e9399873f1c
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Inputs: operations/**/*.graphql and schema.gql (synced from the published
|
|
4
4
|
// SDL at https://docs.crowdedkingdoms.com/schema/game-api.graphql).
|
|
5
5
|
// schema.gql sha256: 13094c2757b41d50c8aee996009a00d0995ef597bd792c778c25585576a45f33
|
|
6
|
-
// operations sha256:
|
|
6
|
+
// operations sha256: eca7de01bfc5d967afbf6c230b6596a9ae42bf9a584ac1021c9f6e9399873f1c
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
@@ -11053,6 +11053,102 @@ inline constexpr std::string_view kListVoxelUpdatesByDistanceIsolatedDocument =
|
|
|
11053
11053
|
})gql";
|
|
11054
11054
|
inline constexpr std::string_view kListVoxelUpdatesByDistanceOperationName = "ListVoxelUpdatesByDistance";
|
|
11055
11055
|
|
|
11056
|
+
/// voxels/ListVoxelUpdatesByDistanceCells.graphql
|
|
11057
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsDocument = R"gql(query ListVoxelUpdatesByDistanceCells($input: ListVoxelUpdatesByDistanceInput!) {
|
|
11058
|
+
listVoxelUpdatesByDistance(input: $input) {
|
|
11059
|
+
limit
|
|
11060
|
+
skip
|
|
11061
|
+
chunks {
|
|
11062
|
+
coordinates {
|
|
11063
|
+
x
|
|
11064
|
+
y
|
|
11065
|
+
z
|
|
11066
|
+
}
|
|
11067
|
+
voxels {
|
|
11068
|
+
location {
|
|
11069
|
+
x
|
|
11070
|
+
y
|
|
11071
|
+
z
|
|
11072
|
+
}
|
|
11073
|
+
voxelType
|
|
11074
|
+
state
|
|
11075
|
+
}
|
|
11076
|
+
}
|
|
11077
|
+
}
|
|
11078
|
+
})gql";
|
|
11079
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsIsolatedDocument = R"gql(query ListVoxelUpdatesByDistanceCells($input: ListVoxelUpdatesByDistanceInput!) {
|
|
11080
|
+
listVoxelUpdatesByDistance(input: $input) {
|
|
11081
|
+
limit
|
|
11082
|
+
skip
|
|
11083
|
+
chunks {
|
|
11084
|
+
coordinates {
|
|
11085
|
+
x
|
|
11086
|
+
y
|
|
11087
|
+
z
|
|
11088
|
+
}
|
|
11089
|
+
voxels {
|
|
11090
|
+
location {
|
|
11091
|
+
x
|
|
11092
|
+
y
|
|
11093
|
+
z
|
|
11094
|
+
}
|
|
11095
|
+
voxelType
|
|
11096
|
+
state
|
|
11097
|
+
}
|
|
11098
|
+
}
|
|
11099
|
+
}
|
|
11100
|
+
})gql";
|
|
11101
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsOperationName = "ListVoxelUpdatesByDistanceCells";
|
|
11102
|
+
|
|
11103
|
+
/// voxels/ListVoxelUpdatesByDistanceCellsTimed.graphql
|
|
11104
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsTimedDocument = R"gql(query ListVoxelUpdatesByDistanceCellsTimed($input: ListVoxelUpdatesByDistanceInput!) {
|
|
11105
|
+
listVoxelUpdatesByDistance(input: $input) {
|
|
11106
|
+
limit
|
|
11107
|
+
skip
|
|
11108
|
+
chunks {
|
|
11109
|
+
coordinates {
|
|
11110
|
+
x
|
|
11111
|
+
y
|
|
11112
|
+
z
|
|
11113
|
+
}
|
|
11114
|
+
voxels {
|
|
11115
|
+
location {
|
|
11116
|
+
x
|
|
11117
|
+
y
|
|
11118
|
+
z
|
|
11119
|
+
}
|
|
11120
|
+
voxelType
|
|
11121
|
+
state
|
|
11122
|
+
createdAt
|
|
11123
|
+
}
|
|
11124
|
+
}
|
|
11125
|
+
}
|
|
11126
|
+
})gql";
|
|
11127
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsTimedIsolatedDocument = R"gql(query ListVoxelUpdatesByDistanceCellsTimed($input: ListVoxelUpdatesByDistanceInput!) {
|
|
11128
|
+
listVoxelUpdatesByDistance(input: $input) {
|
|
11129
|
+
limit
|
|
11130
|
+
skip
|
|
11131
|
+
chunks {
|
|
11132
|
+
coordinates {
|
|
11133
|
+
x
|
|
11134
|
+
y
|
|
11135
|
+
z
|
|
11136
|
+
}
|
|
11137
|
+
voxels {
|
|
11138
|
+
location {
|
|
11139
|
+
x
|
|
11140
|
+
y
|
|
11141
|
+
z
|
|
11142
|
+
}
|
|
11143
|
+
voxelType
|
|
11144
|
+
state
|
|
11145
|
+
createdAt
|
|
11146
|
+
}
|
|
11147
|
+
}
|
|
11148
|
+
}
|
|
11149
|
+
})gql";
|
|
11150
|
+
inline constexpr std::string_view kListVoxelUpdatesByDistanceCellsTimedOperationName = "ListVoxelUpdatesByDistanceCellsTimed";
|
|
11151
|
+
|
|
11056
11152
|
/// voxels/ListVoxels.graphql
|
|
11057
11153
|
inline constexpr std::string_view kListVoxelsDocument = R"gql(query ListVoxels($input: ListVoxelsInput!) {
|
|
11058
11154
|
listVoxels(input: $input) {
|
|
@@ -11335,6 +11431,8 @@ inline constexpr std::string_view kVoxelUpdateHistoryConnectionOperationName = "
|
|
|
11335
11431
|
|
|
11336
11432
|
inline constexpr std::string_view documentFor(std::string_view operationName) {
|
|
11337
11433
|
if (operationName == "ListVoxelUpdatesByDistance") return kListVoxelUpdatesByDistanceIsolatedDocument;
|
|
11434
|
+
if (operationName == "ListVoxelUpdatesByDistanceCells") return kListVoxelUpdatesByDistanceCellsIsolatedDocument;
|
|
11435
|
+
if (operationName == "ListVoxelUpdatesByDistanceCellsTimed") return kListVoxelUpdatesByDistanceCellsTimedIsolatedDocument;
|
|
11338
11436
|
if (operationName == "ListVoxels") return kListVoxelsIsolatedDocument;
|
|
11339
11437
|
if (operationName == "RollbackVoxelUpdates") return kRollbackVoxelUpdatesIsolatedDocument;
|
|
11340
11438
|
if (operationName == "UpdateVoxel") return kUpdateVoxelIsolatedDocument;
|
{crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/graphql/json.hpp
RENAMED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
#include <variant>
|
|
11
11
|
#include <vector>
|
|
12
12
|
|
|
13
|
+
#include "crowdy/core/result.hpp"
|
|
14
|
+
|
|
13
15
|
/// JSON support for the GraphQL layer (never used on the UDP path).
|
|
14
16
|
///
|
|
15
17
|
/// Two shapes:
|
|
@@ -66,7 +68,8 @@ class JVal {
|
|
|
66
68
|
/// JVal::array(...).
|
|
67
69
|
JVal& operator[](std::nullptr_t) = delete;
|
|
68
70
|
|
|
69
|
-
/// Serialize to a compact JSON string (RFC 8259 escaping).
|
|
71
|
+
/// Serialize to a compact JSON string (RFC 8259 escaping). NaN and infinity are written
|
|
72
|
+
/// as `null`, as JSON.stringify writes them.
|
|
70
73
|
std::string dump() const;
|
|
71
74
|
|
|
72
75
|
private:
|
|
@@ -122,8 +125,13 @@ class Json {
|
|
|
122
125
|
/// int64. Integer JSON numbers are converted losslessly.
|
|
123
126
|
std::string asBigIntString(std::string_view fallback = {}) const;
|
|
124
127
|
|
|
125
|
-
/// Serialize this value back to a JSON string.
|
|
128
|
+
/// Serialize this value back to a JSON string. NaN and infinity are written as `null` in
|
|
129
|
+
/// place, so the rest of the value survives. A value that still cannot be written (a
|
|
130
|
+
/// string that is not valid UTF-8, which fromMsgpack can produce) comes back as "null":
|
|
131
|
+
/// use tryDump() to tell that apart from a null value.
|
|
126
132
|
std::string dump() const;
|
|
133
|
+
/// dump(), reporting a value it cannot write as Errc::Malformed instead of "null".
|
|
134
|
+
Result<std::string> tryDump() const;
|
|
127
135
|
|
|
128
136
|
/// This value as MessagePack, the payload format of ck-exec calls: integers
|
|
129
137
|
/// keep their exact width and sign, objects become maps with string keys. A
|
|
@@ -132,9 +140,11 @@ class Json {
|
|
|
132
140
|
/// the calling thread's stack.
|
|
133
141
|
std::string toMsgpack() const;
|
|
134
142
|
/// Parse one MessagePack value into a document. Binary becomes a base64
|
|
135
|
-
/// string and extension types null; nesting deeper than 64 is refused.
|
|
143
|
+
/// string and extension types null; nesting deeper than 64 is refused. A map
|
|
144
|
+
/// key must be a string, a number, a boolean or nil (the last three become
|
|
145
|
+
/// their JSON text); an array, map, binary or extension key is refused.
|
|
136
146
|
/// Returns a null Json (ok() == false) on malformed, truncated or trailing
|
|
137
|
-
/// input.
|
|
147
|
+
/// input, or on a refused key.
|
|
138
148
|
static Json fromMsgpack(std::string_view bytes);
|
|
139
149
|
|
|
140
150
|
/// Iterate object members / array elements, in order, one step each: linear in
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <memory>
|
|
6
6
|
#include <mutex>
|
|
7
7
|
#include <thread>
|
|
8
|
+
#include <unordered_map>
|
|
8
9
|
|
|
9
10
|
#include "crowdy/core/clock.hpp"
|
|
10
11
|
#include "crowdy/core/crypto.hpp"
|
|
@@ -301,6 +302,10 @@ class Connection {
|
|
|
301
302
|
/// Bound control frames (44, 45) carrying another assignment's nonce, dropped: a
|
|
302
303
|
/// frame captured earlier and sent again.
|
|
303
304
|
std::uint64_t staleBoundControl = 0;
|
|
305
|
+
/// Verified legacy COMMAND_RECONNECTs (22) dropped because one was honoured too
|
|
306
|
+
/// recently (0.83.0): a 22 signs fixed bytes, so a captured one verifies for the
|
|
307
|
+
/// game token's life, and each honoured one moves the player to another server.
|
|
308
|
+
std::uint64_t legacyReconnectsSuppressed = 0;
|
|
304
309
|
std::int64_t lastServerEpochMs = 0;
|
|
305
310
|
/// Messages sent, by wire opcode (actor/voxel/audio/text/event/channel/
|
|
306
311
|
/// heartbeat requests).
|
|
@@ -422,16 +427,29 @@ class Connection {
|
|
|
422
427
|
|
|
423
428
|
/// Monotonic ms of the last send that counts as gameplay input (0: none yet).
|
|
424
429
|
std::atomic<std::int64_t> lastGameplayMs_{0};
|
|
425
|
-
/// The last actor-update payload hash per actor this
|
|
426
|
-
/// repeats an unchanged state is not input.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
430
|
+
/// The last actor-update payload hash per actor this assignment, so a keyframe that
|
|
431
|
+
/// repeats an unchanged state is not input. An actor's first update is a change. Past
|
|
432
|
+
/// kMaxTrackedActors actors, an untracked actor's keyframe counts as unchanged, so a host
|
|
433
|
+
/// keeping a large world's keyframes going still looks idle when it is.
|
|
434
|
+
struct ActorUuidHasher {
|
|
435
|
+
std::size_t operator()(const core::ActorUuid& u) const noexcept {
|
|
436
|
+
std::uint64_t h = 1469598103934665603ULL;
|
|
437
|
+
for (char c : u) h = (h ^ static_cast<std::uint8_t>(c)) * 1099511628211ULL;
|
|
438
|
+
return static_cast<std::size_t>(h);
|
|
439
|
+
}
|
|
431
440
|
};
|
|
432
|
-
std::
|
|
433
|
-
std::
|
|
441
|
+
static constexpr std::size_t kMaxTrackedActors = 4096;
|
|
442
|
+
std::unordered_map<core::ActorUuid, std::uint64_t, ActorUuidHasher> actorStateHashes_;
|
|
434
443
|
std::mutex actorStateMutex_;
|
|
444
|
+
|
|
445
|
+
/// Config::legacyReconnectWindowMs: a legacy COMMAND_RECONNECT (22) is honoured once per
|
|
446
|
+
/// assignment, and each honoured one must follow the last by the current window. Touched
|
|
447
|
+
/// only on the receive path and in doAssign().
|
|
448
|
+
static constexpr std::int64_t kLegacyReconnectWindowMaxMs = 600'000;
|
|
449
|
+
std::int64_t lastLegacyReconnectMs_ = 0;
|
|
450
|
+
std::int64_t legacyReconnectWindowMs_ = 0;
|
|
451
|
+
bool legacyReconnectHonoured_ = false;
|
|
452
|
+
bool honourLegacyReconnect();
|
|
435
453
|
void noteGameplaySend(wire::MessageType type, const SpatialSend& p);
|
|
436
454
|
bool actorStateChanged(const SpatialSend& p);
|
|
437
455
|
bool idleReleaseFollowsInput() const;
|
{crowdypy-0.30.0.dev1 → crowdypy-0.31.0.dev1}/vendor/CrowdyCPP/include/crowdy/replication/types.hpp
RENAMED
|
@@ -105,6 +105,14 @@ struct Config {
|
|
|
105
105
|
/// release final.
|
|
106
106
|
std::int64_t idleReleaseGuardMs = 60 * 1000;
|
|
107
107
|
|
|
108
|
+
/// A verified legacy COMMAND_RECONNECT (22) reassigns at most once per assignment, and
|
|
109
|
+
/// only this long after the last one it honoured; the window doubles with each honoured
|
|
110
|
+
/// one up to 10 minutes, and goes back to this after 10 minutes without one. A 22 signs
|
|
111
|
+
/// fixed bytes, so one captured earlier verifies again for the game token's life; the
|
|
112
|
+
/// rest are dropped and count in Stats::legacyReconnectsSuppressed. The bound form (44)
|
|
113
|
+
/// is not limited. 0 honours every verified 22, as before 0.83.0.
|
|
114
|
+
std::int64_t legacyReconnectWindowMs = 30 * 1000;
|
|
115
|
+
|
|
108
116
|
/// Capacity (events) of the net->game notification ring.
|
|
109
117
|
std::size_t ringCapacity = 4096;
|
|
110
118
|
|
|
@@ -94,6 +94,10 @@ void JVal::dumpTo(std::string& out) const {
|
|
|
94
94
|
void operator()(bool b) { out += b ? "true" : "false"; }
|
|
95
95
|
void operator()(std::int64_t i) { out += std::to_string(i); }
|
|
96
96
|
void operator()(double d) {
|
|
97
|
+
if (!std::isfinite(d)) {
|
|
98
|
+
out += "null"; // as JSON.stringify writes NaN and infinity
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
97
101
|
char buf[32];
|
|
98
102
|
std::snprintf(buf, sizeof(buf), "%.17g", d);
|
|
99
103
|
out += buf;
|
|
@@ -243,9 +247,14 @@ std::string Json::asBigIntString(std::string_view fallback) const {
|
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
std::string Json::dump() const {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
250
|
+
auto out = tryDump();
|
|
251
|
+
return out.ok() ? std::move(out.value()) : std::string("null");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
Result<std::string> Json::tryDump() const {
|
|
255
|
+
if (!val_) return std::string("null");
|
|
256
|
+
char* s = yyjson_val_write(val(val_), YYJSON_WRITE_INF_AND_NAN_AS_NULL, nullptr);
|
|
257
|
+
if (!s) return Errc::Malformed;
|
|
249
258
|
std::string out(s);
|
|
250
259
|
free(s);
|
|
251
260
|
return out;
|
|
@@ -438,15 +447,34 @@ struct Unpacker {
|
|
|
438
447
|
}
|
|
439
448
|
return a;
|
|
440
449
|
}
|
|
450
|
+
// A map key must be a scalar. A container key written as text is escaped again at every
|
|
451
|
+
// level it is nested in another key, so 130 bytes nested 60 deep asked for gigabytes.
|
|
452
|
+
static bool scalarKey(std::uint8_t t) {
|
|
453
|
+
if ((t & 0xf0) == 0x80 || (t & 0xf0) == 0x90) return false; // fixmap, fixarray
|
|
454
|
+
switch (t) {
|
|
455
|
+
case 0xc4: case 0xc5: case 0xc6: // bin
|
|
456
|
+
case 0xc7: case 0xc8: case 0xc9: // ext
|
|
457
|
+
case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: // fixext
|
|
458
|
+
case 0xdc: case 0xdd: case 0xde: case 0xdf: // array, map
|
|
459
|
+
return false;
|
|
460
|
+
default:
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
441
464
|
yyjson_mut_val* map(std::size_t n, int depth) {
|
|
442
465
|
yyjson_mut_val* o = yyjson_mut_obj(doc);
|
|
443
466
|
for (std::size_t i = 0; i < n && ok; ++i) {
|
|
467
|
+
if (!need(1)) break;
|
|
468
|
+
if (!scalarKey(*p)) {
|
|
469
|
+
ok = false;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
444
472
|
yyjson_mut_val* k = value(depth + 1);
|
|
445
473
|
yyjson_mut_val* v = value(depth + 1);
|
|
446
474
|
if (!ok || !k || !v) break;
|
|
447
475
|
if (!yyjson_mut_is_str(k)) {
|
|
448
|
-
// A
|
|
449
|
-
char* text = yyjson_mut_val_write(k,
|
|
476
|
+
// A number, boolean or nil key keeps its value as text, as JSON has only string keys.
|
|
477
|
+
char* text = yyjson_mut_val_write(k, YYJSON_WRITE_INF_AND_NAN_AS_NULL, nullptr);
|
|
450
478
|
k = yyjson_mut_strcpy(doc, text ? text : "null");
|
|
451
479
|
free(text);
|
|
452
480
|
}
|