Skip to main content

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

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)

Source distribution for bfportal-grpc 0.1.4
File Size Uploaded
bfportal_grpc-0.1.4.tar.gz 16.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bfportal-grpc 0.1.4
File Interpreter ABI Platform
bfportal_grpc-0.1.4-py3-none-any.whl Python 3 none any Details

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

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 release files

0.1.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page