BattleBit Community Server API
A re-implementation of the official community server API for BattleBit
Preamble
The goal of this project is to create an alternate, Python-implementation to the official community server API, which is written in C#. This project can be considered production-ready.
Prerequisites
- Python 3.10 or later
- A running, whitelisted BattleBit Server (Version 2.1.2)
Usage
As a user of this API, there are two important things to know, Handlers and Commands. More on those in the following paragraphs. Basic examples on how to use this project can be found in /battlebit_community_server_api/example.
Handlers
Handlers are the users way of hooking themselves onto certain events that are happening. Such as "A player joins the server" and "A player sent a chat message".
For each event, the user can register their own handler with the ApiServer.register_handler method. This method takes an OpCodes value and any Callable.
IMPORTANT: Each handler has the signature async def handler(d: bytes) -> bytes. It receives the raw TCP message as an input and returns a TCP message.
Use TcpParsingService to parse the incoming data into the datamodel objects. Use OutgoingGameServerMessage to return data. Refer to the examples for further information.
Default Handlers
If there is no Handler registered for an OP-Code, the default Handler for that event is executed. The user can also use default Handlers in their own Handler, see example/SendingCommands.py.
Implementation status of default handlers
| Event | Status | Behavior | Associated Parser (from TcpParingService) |
|---|---|---|---|
| HAIL | HAIL is accepted | parse_hail_message |
|
| PLAYER_CONNECTED | Event does not expect a response | parse_player_connected |
|
| PLAYER_DISCONNECTED | Event does not expect a response | parse_player_disconnected |
|
| ON_PLAYER_TYPED_MESSAGE | Allows message via RESPOND_PLAYER_MESSAGE |
parse_on_player_typed_message |
|
| ON_PLAYER_KILLED_ANOTHER_PLAYER | Event does not expect a response | parse_on_player_killed_another_player |
|
| ON_PLAYER_JOINING | Official Stats are returned via SEND_PLAYER_STATS |
parse_on_player_joining |
|
| SAVE_PLAYER_STATS | Event does not expect a response | parse_save_player_stats |
|
| ON_PLAYER_ASKING_TO_CHANGE_ROLE | Allows requested role change via SetRoleTo |
parse_on_player_asking_to_change_role |
|
| ON_PLAYER_CHANGED_ROLE | Event does not expect a response | parse_on_player_changed_role |
|
| ON_PLAYER_JOINED_A_SQUAD | Event does not expect a response | parse_on_player_joined_a_squad |
|
| ON_PLAYER_LEFT_SQUAD | Event does not expect a response | parse_on_player_left_squad |
|
| ON_PLAYER_CHANGED_TEAM | Event does not expect a response | parse_on_player_changed_team |
|
| ON_PLAYER_REQUESTING_TO_SPAWN | Request is granted via SPAWN_PLAYER |
parse_on_player_requesting_to_spawn |
|
| ON_PLAYER_REPORT | Event does not expect a response | parse_on_player_report |
|
| ON_PLAYER_SPAWN | Event does not expect a response | parse_on_player_spawn |
|
| ON_PLAYER_DIE | Event does not expect a response | parse_on_player_die |
|
| NOTIFY_NEW_MAP_ROTATION | Event does not expect a response | parse_notify_new_map_rotation |
|
| NOTIFY_NEW_GAME_MODE_ROTATION | Event does not expect a response | parse_notify_new_gamemode_rotation |
|
| NOTIFY_NEW_ROUND_STATE | Event does not expect a response | parse_new_round_state |
|
| ON_PLAYER_ASKING_TO_CHANGE_TEAM | Allows requested team change via SetTeamTo |
parse_on_player_asking_to_change_team |
|
| GAME_TICK | Event does not expect a response | parse_game_tick |
|
| ON_PLAYER_GIVEN_UP | Event does not expect a response | parse_on_player_given_up |
|
| ON_PLAYER_REVIVED_ANOTHER | Event does not expect a response | parse_on_player_revived_another |
|
| ON_SQUAD_POINTS_CHANGED | Event does not expect a response | parse_on_squad_points_changed |
|
| NOTIFY_NEW_ROUND_ID | Event does not expect a response | parse_notify_new_round_id |
|
| LOG | Logs will be written to logger on DEBUG level | parse_log |
|
| ON_SQUAD_LEADER_CHANGED | Event does not expect a response | parse_on_squad_leader_changed |
|
| UPDATE_NEW_GAME_DATA | Event does not expect a response | parse_update_new_game_data |
|
| UPDATE_CONNECTED_PLAYERS | Event does not expect a response | parse_update_connected_players |
Commands
While Handlers are triggered on an event and respond to the server, Commands can be executed at any point.
To execute an Command, pick a Command from the Command module (for example Command.SayToChat), use its initializer to prepare it, and then queue it for execution.
You can also build your own commands by using the Command base class.
To execute a command, use ApiServer.add_command_to_queue.
Predefined commands
| Command | Effect |
|---|---|
| ForceStartGame | Starts the Round |
| ForceStartGame | Ends the Round |
| SayToAllChat | Sends chat message into All-Chat |
| SayToChat | Sends chat message that is only visible to a specific player |
| SetRoleTo | Sets the role of player |
| SetTeamTo | Sets the team of player |
| SetNewPassword | Sets a new password for the server |
| SetPingLimit | Sets a new ping limit for the server |
| AnnounceShort | Displays an announcement to all players for a short duration |
| AnnounceLong | Displays an announcement to all players for a long duration |
| UILogOnServer | Displays a log message on the server for a set duration |
| SetLoadingScreenText | Sets the text that is displayed to players in the loading screen |
| SetRulesScreenText | Sets the text that is displayed to the players in the rules screen |
| StopServer | Stops the server |
| CloseServer | Announces that the server will close |
| KickAllPlayers | Kicks every player |
| KickPlayer | Kicks specific player, optionally with a text that is displayed to the player |
| KillPlayer | Kills specific player |
| SwapTeam | Swaps specific player to the other team |
| KickFromSquad | Kicks specific player from squad |
| JoinSquad | Joins specific player into a squad |
| DisbandPlayerSquad | Disbands a squad |
| PromoteSquadLeader | Promotes specific player to be the squadleader of the squad he is currently in |
| WarnPlayer | Displays warn message to player |
| MessageToPlayer | Displays message to player (not in chat, use SayToChat if you want that) |
| SetPlayerHp | Sets a specific player's HP |
| DamagePlayer | Damage specific player |
| HealPlayer | Heal specific player |
| SetSquadPoints | Sets squadpoints for a specific squad |
| SetMapRotation | Sets the map rotation |
| SetGamemodeRotation | Sets the gamemode rotation |
| SetMapSize | Sets the map size for the next round |
Predefined OutgoingGameServerMessages
New in version 0.1.1
There are OutgoingGameServerMessages that have already been preconfigured with the correct OP-Code and accept typed arguments.
Below is a list of the ones that are currently available.
| Name | Effect |
|---|---|
| SetPlayerModification | Given a SteamID and a PlayerModification object, this OutgoingGameServerMessage will apply the modifications to the player with that SteamID (if that player is still on the server) |
| PlaceVoxelBlock | Given a Vector3 and a VoxelBlockData object, this OutgoingGameServerMessage will place the specified block at the specified location. |
| DestroyVoxelBlock | Destroys a block at the specified location |
The predefined OutgoingGameServerMessages can be imported from battlebit_community_server_api.helper.PredefinedOutgoingGameServerMessages.
Adding commands from outside
At some point you might want to queue Commands or OutgoingGameServerMessages from outside the API loop.
You can find an example doing just that at example/SetNewRoomSettings.py.
Contributing
The current state of development does not yet allow for productive, cooperative contribution.
Licence
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2023 David Rodenkirchen <davidr.develop@gmail.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
Metadata
Release files for battlebit-community-server-api 0.1.1
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 | |
|---|---|---|---|---|
| battlebit-community-server-api-0.1.1.tar.gz | 38.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| battlebit_community_server_api-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.5 kB
Release files / battlebit-community-server-api-0.1.1.tar.gz
| Download URL | battlebit-community-server-api-0.1.1.tar.gz |
|---|---|
| Size | 38.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ffcea13eccfb99a3937ffb2ce85926c135ba9c14d7f32adaa752acf4014c3e24
|
|
BLAKE2b-256 checksum How to use checksums |
d0659ff563be2259a98eb8055177af932e722be123cb017e6d3f45e7df72ec0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.3
|
Release files / battlebit_community_server_api-0.1.1-py3-none-any.whl
| Download URL | battlebit_community_server_api-0.1.1-py3-none-any.whl |
|---|---|
| Size | 53.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7cd95fec823c1d4b0fc88dc34b0a716710abb1990291e05920f9bed269309044
|
|
BLAKE2b-256 checksum How to use checksums |
715c2c638589a662789aa8b3f5ba85b5120cdda716f93b475aff3d1520d6ed3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.3
|
Security for battlebit-community-server-api 0.1.1
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.