Battlefield Portal web-grpc
This npm and python package can be used to directly call the https://portal.battlefield.com/ api. we're making this public since you can read the javascript of the website and figure this out yourself easily anyway, but we want to make sure only 1 github repo has to be kept in sync with the api and the rest that uses it just has to update a package and a few code changes to still have it work.
https://www.npmjs.com/package/bfportal-grpc
https://pypi.org/project/bfportal-grpc/
example
import { CommunityGamesClient, communitygames } from 'bfportal-grpc'
const communityGames = new CommunityGamesClient(
'https://kingston-prod-wgw-envoy.ops.dice.se',
null
)
const metadata = {
'x-dice-tenancy': 'prod_default-prod_default-kingston-common',
'x-gateway-session-id': sessionId,
'x-grpc-web': '1',
'x-user-agent': 'grpc-web-javascript/0.1',
}
const request = new communitygames.GetPlaygroundRequest()
request.setPlaygroundid(testPlayground)
const response = await communityGames.getPlayground(request, metadata)
const modRules = response
.getPlayground()
?.getOriginalplayground()
?.getModrules()
?.getCompatiblerules()
?.getRules()
if (modRules instanceof Uint8Array) {
console.log(new TextDecoder().decode(modRules))
}
const playgroundName = response
.getPlayground()
?.getOriginalplayground()
?.getName()
the proto files are accessable directly via "node_modules/bfportal-grpc/proto/communitygames.proto" to for example decode to json:
import { load } from 'protobufjs'
// use reponse from previous example
const root = await load('node_modules/bfportal-grpc/proto/communitygames.proto')
const AwesomeMessage = root.lookupType(
'web.communitygames.PlaygroundInfoResponse'
)
const decoded = AwesomeMessage.decode(response.serializeBinary())
const json_str = JSON.stringify(decoded, null, 4)
non-async example
import { CommunityGamesClient, communitygames } from 'bfportal-grpc'
const communityGames = new CommunityGamesClient(
'https://kingston-prod-wgw-envoy.ops.dice.se',
null
)
const metadata = {
'x-dice-tenancy': 'prod_default-prod_default-kingston-common',
'x-gateway-session-id': sessionId,
'x-grpc-web': '1',
'x-user-agent': 'grpc-web-javascript/0.1',
}
const request = new communitygames.GetPlaygroundRequest()
request.setPlaygroundid('bbe433c0-13fa-11ed-bc32-24a8c2c0764e')
const call = communityGames.getPlayground(
request,
metadata,
(_err: grpcWeb.Error, response: communitygames.PlaygroundInfoResponse) => {
// console.log("err:", _err)
var modRules = response
.getPlayground()
?.getOriginalplayground()
?.getModrules()
?.getCompatiblerules()
?.getRules()
if (modRules instanceof Uint8Array) {
console.log(new TextDecoder().decode(modRules))
}
load(
'node_modules/bfportal-grpc/proto/communitygames.proto',
function (err, root) {
if (err) throw err
if (root == undefined) return
const AwesomeMessage = root.lookupType(
'web.communitygames.PlaygroundInfoResponse'
)
let decoded = AwesomeMessage.decode(response.serializeBinary())
fs.writeFile(
'test.json',
JSON.stringify(decoded, null, 4),
function (err: any) {
if (err) {
console.log(err)
}
}
)
}
)
}
)
python
for python you can use the 'sonora' package to do grpc-web
import asyncio
import sonora.aio
from bfportal_grpc import communitygames_pb2, communitygames_pb2_grpc, access_token, authentication_pb2, authentication_pb2_grpc
async def main():
cookie = access_token.Cookie(sid="", remid="")
token = await access_token.getBf2042GatewaySession(cookie)
async with sonora.aio.insecure_web_channel(
f"https://kingston-prod-wgw-envoy.ops.dice.se"
) as channel:
stub = authentication_pb2_grpc.AuthenticationStub(channel)
auth_response: authentication_pb2.AuthResponse = await stub.viaAuthCode(authentication_pb2.AuthRequest(platform=1, authCode=token, redirectUri='https://portal.battlefield.com/'), metadata=(
('x-dice-tenancy', 'prod_default-prod_default-kingston-common'),
('x-grpc-web', '1'),
('x-user-agent', 'grpc-web-javascript/0.1')
))
stub = communitygames_pb2_grpc.CommunityGamesStub(channel)
response: communitygames_pb2.PlaygroundInfoResponse = await stub.getPlayground(communitygames_pb2.GetPlaygroundRequest(playgroundId="10992a10-461a-11ec-8de0-d9f491f92236"), metadata=(
('x-dice-tenancy', 'prod_default-prod_default-kingston-common'),
('x-gateway-session-id', auth_response.sessionId),
('x-grpc-web', '1'),
('x-user-agent', 'grpc-web-javascript/0.1')
))
print(response.playground.originalPlayground.name)
if __name__ == "__main__":
asyncio.run(main())
current build method from proto to javascript via python
needs proto-compile, which can be installed with:
pip3 install proto-compile
and build with:
proto-compile --clear-output-dirs --verbosity=1 ./proto ./src/proto grpc-web --grpc_web_out_options="import_style=typescript,mode=grpcweb"
building for python requires grpcio-tools, which can be installed with:
pip3 install grpcio-tools
and build with:
python3 -m grpc_tools.protoc -I. --python_out=./bfportal_grpc --grpc_python_out=./bfportal_grpc ./proto/communitygames.proto ./proto/localization.proto ./proto/authentication.proto ./proto/reporting.proto
python package used: https://github.com/romnn/proto-compile
Pushing your changes
package versions can be made with npm run build and npm version patch git push --tags origin main to release.
for python patch with npm run build:python, npm run python:setimports and poetry build.
example library used: https://github.com/tomchen/example-typescript-package
Metadata
Release files for bfportal-grpc 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| bfportal_grpc-0.1.4.tar.gz | 16.5 kB | Without provenance | Details for bfportal_grpc-0.1.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bfportal_grpc-0.1.4-py3-none-any.whl | Python 3 | none | any | Details for bfportal_grpc-0.1.4-py3-none-any.whl |
Total release size: 35.6 kB
Release files / bfportal_grpc-0.1.4.tar.gz
| Download URL | bfportal_grpc-0.1.4.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
566e7344ae74aadc303ecc50576c25229302b8cd33df4e1ea74173e9504524d5
|
|
BLAKE2b-256 checksum How to use checksums |
fa0f72262aa8efd50ad74ab79d7be800c93146c322956f7de88247266d29153e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.5.1 CPython/3.11.3 Darwin/22.4.0
|
Release files / bfportal_grpc-0.1.4-py3-none-any.whl
| Download URL | bfportal_grpc-0.1.4-py3-none-any.whl |
|---|---|
| Size | 19.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f23ff33ccd4f0d787e53af5b798d9ae95e90ab62d828ab4af433850dc455593c
|
|
BLAKE2b-256 checksum How to use checksums |
23fb1dc306809b96ca675e3d24c6752a0aa57e95299c70f0ad863c04cff76a51
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.5.1 CPython/3.11.3 Darwin/22.4.0
|
Security for bfportal-grpc 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.