Skip to main content

A python library for serializing and deserializing bancho packets.

Project description

Chio

GitHub Actions Workflow Status PyPI - Downloads GitHub License

Chio (Bancho I/O) is a python library for serializing and deserializing bancho packets, with support for all versions of osu! that use bancho (2008-2025).

It was made with the intention of documenting everything about the bancho protocol, and to provide a base for server frameworks, since the packet handling part is most often the annoying part.
Having any client be able to connect to it is a very sweet addition on top, if you are interested in those as well.

If you wish to use this library, I would appreciate some credit for my work. Thanks!

Usage

This library requires an installation of python 3.8 or higher.
You can install the library with pip:

pip install chio

Or you can also install it from source directly, if preferred:

pip install git+https://github.com/Lekuruu/chio.py

Here is a very basic example of how to use this library, and how to get a client to log in:

import chio

# Chio expects you to have the `chio.Stream` class
# implemented, i.e. it needs a `read()` and `write()`
# function to work properly
stream = chio.Stream()

# The client version is how chio determines what
# protocol to use. This one can be parsed through the
# initial login request, that the client makes.
client_version = 20140127

# Chio has combined the user presence, stats and status
# into one class, to support more clients. You are also
# able to provide your own player class, as long as you
# have the same fields added on to it.
info = chio.UserInfo(
    id=2,
    name="peppy",
    presence=chio.UserPresence(),
    stats=chio.UserStats(),
    status=chio.UserStatus()
)

# Select a client protocol to use for encoding/decoding
io = chio.select_client(client_version)

# Send the users information (userId, presence & stats)
io.write_packet(stream, chio.PacketType.BanchoLoginReply, info.id)
io.write_packet(stream, chio.PacketType.BanchoUserPresence, info)
io.write_packet(stream, chio.PacketType.BanchoUserStats, info)

# Force client to join #osu
io.write_packet(stream, chio.PacketType.BanchoChannelJoinSuccess, "#osu")

# Send a message in #osu from BanchoBot
io.write_packet(
    stream,
    chio.PacketType.BanchoMessage,
    chio.Message(content="Hello, World!", sender="BanchoBot", target="#osu")
)

packet, data = io.read_packet(stream)
print(f"Received packet '{packet.name}' with {data}.")

You can also read & write from bytes directly, for example when using HTTP clients instead of TCP clients:

encoded = io.write_packet_to_bytes(chio.PacketType.BanchoLoginReply, info.id)
packet, data = io.read_packet_from_bytes(b"...")

If you are using asyncio, you may want to use the read_packet_async & write_packet_async functions respectively for asynchronous usage. This feature is currently untested, but should work in theory. If you encounter any bugs with it, don't be afraid to report them.

encoded = await io.write_packet_async(stream, chio.PacketType.BanchoLoginReply, info.id)
packet, data = await io.read_packet_async(stream)

Patching

You are able to overwrite specifc packet readers/writers, with the chio.patch decorator. As an example, to patch the BanchoUserStats packet inside of b20120723:

@chio.patch(PacketType.BanchoUserStats, 20120723)
def write_user_stats(cls, info: UserInfo):
    stream = MemoryStream()
    write_s32(stream, info.id)
    stream.write(cls.write_status_update(info.status))
    write_u64(stream, info.stats.rscore)
    write_f32(stream, info.stats.accuracy)
    write_u32(stream, info.stats.playcount)
    write_u64(stream, info.stats.tscore)
    write_u32(stream, info.stats.rank)
    write_u16(stream, info.stats.pp)
    yield PacketType.BanchoUserStats, stream.data

Additionally, it's possible to set a certain slot size & protocol version for each version:

# Set protocol version to 10 for b20120818
chio.set_protocol_version(10, 20120818)

# Override slot size to 32 for b20160404
chio.set_slot_size(32, 20160404)

Datatypes

Depending on the packet you send or receive, you will need to account for different datatypes.
Here is a list of them for each packet:

Packet Type
OsuUserStatus chio.UserStatus
OsuMessage chio.Message
OsuExit bool (IsUpdating)
OsuStatusUpdateRequest N/A
OsuPong N/A
BanchoLoginReply int (UserId) or chio.LoginError
BanchoMessage chio.Message
BanchoPing N/A
BanchoIrcChangeUsername str (old name), str (new name)
BanchoIrcQuit str (Username)
BanchoUserStats chio.UserInfo
BanchoUserQuit chio.UserQuit
BanchoSpectatorJoined int (UserId)
BanchoSpectatorLeft int (UserId)
BanchoSpectateFrames chio.ReplayFrameBundle
OsuStartSpectating int (UserId)
OsuStopSpectating int (UserId)
OsuSpectateFrames chio.ReplayFrameBundle
BanchoVersionUpdate N/A
OsuErrorReport str (Exception)
OsuCantSpectate N/A
BanchoSpectatorCantSpectate int (UserId)
BanchoGetAttention N/A
BanchoAnnounce str (Message)
OsuPrivateMessage chio.Message
BanchoMatchUpdate chio.Match
BanchoMatchNew chio.Match
BanchoMatchDisband int (MatchId)
OsuLobbyPart N/A
OsuLobbyJoin N/A
OsuMatchCreate chio.Match
OsuMatchJoin int (MatchId)
OsuMatchPart N/A
BanchoLobbyJoin int (UserId)
BanchoLobbyPart int (UserId)
BanchoMatchJoinSuccess chio.Match
BanchoMatchJoinFail N/A
OsuMatchChangeSlot int (SlotId)
OsuMatchReady N/A
OsuMatchLock int (SlotId)
OsuMatchChangeSettings chio.Match
BanchoFellowSpectatorJoined int (UserId)
BanchoFellowSpectatorLeft int (UserId)
OsuMatchStart N/A
BanchoMatchStart chio.Match
OsuMatchScoreUpdate chio.ScoreFrame
BanchoMatchScoreUpdate chio.ScoreFrame
OsuMatchComplete N/A
BanchoMatchTransferHost N/A
OsuMatchChangeMods chio.Mods
OsuMatchLoadComplete N/A
BanchoMatchAllPlayersLoaded N/A
OsuMatchNoBeatmap N/A
OsuMatchNotReady N/A
OsuMatchFailed N/A
BanchoMatchPlayerFailed int (SlotId)
BanchoMatchComplete N/A
OsuMatchHasBeatmap N/A
OsuMatchSkipRequest N/A
BanchoMatchSkip N/A
OsuChannelJoin str (Channel Name)
BanchoChannelJoinSuccess str (Channel Name)
BanchoChannelAvailable chio.Channel
BanchoChannelRevoked str (Channel Name)
BanchoChannelAvailableAutojoin chio.Channel
OsuBeatmapInfoRequest chio.BeatmapInfoRequest
BanchoBeatmapInfoReply chio.BeatmapInfoReply
OsuMatchTransferHost int (SlotId)
BanchoLoginPermissions chio.Permissions or int
BanchoFriendsList list[int]
OsuFriendsAdd int (UserId)
OsuFriendsRemove int (UserId)
BanchoProtocolNegotiation N/A or int
BanchoTitleUpdate chio.TitleUpdate
OsuMatchChangeTeam N/A
OsuChannelLeave str (Channel Name)
OsuReceiveUpdates chio.PresenceFilter
BanchoMonitor N/A
BanchoMatchPlayerSkipped int (SlotId)
OsuSetIrcAwayMessage chio.Message
BanchoUserPresence chio.UserInfo
OsuUserStatsRequest list[int]
BanchoRestart int (Retry After Milliseconds)
OsuInvite int (UserId)
BanchoInvite chio.Message
OsuMatchChangePassword chio.Match
BanchoMatchChangePassword str (New Password)
BanchoSilenceInfo int (Locked Until Seconds)
OsuTournamentMatchInfo int (MatchId)
BanchoUserSilenced int (UserId)
BanchoUserPresenceSingle int (UserId)
BanchoUserPresenceBundle list[int] (UserIDs)
OsuPresenceRequest list[int] (UserIDs)
OsuPresenceRequestAll N/A
OsuChangeFriendOnlyDms bool (Enabled/Disabled)
BanchoUserDmsBlocked chio.Message
BanchoTargetIsSilenced chio.Message
BanchoVersionUpdateForced N/A
BanchoSwitchServer int (After Idle Time)
BanchoAccountRestricted N/A
BanchoRTX str (Message)
BanchoMatchAbort N/A
BanchoSwitchTournamentServer str (Server)
OsuTournamentJoinMatchChannel int (MatchId)
OsuTournamentLeaveMatchChannel int (MatchId)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chio-1.1.20.tar.gz (40.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chio-1.1.20-py3-none-any.whl (70.0 kB view details)

Uploaded Python 3

File details

Details for the file chio-1.1.20.tar.gz.

File metadata

  • Download URL: chio-1.1.20.tar.gz
  • Upload date:
  • Size: 40.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for chio-1.1.20.tar.gz
Algorithm Hash digest
SHA256 33f682d278d78e9eb8d87f7ad87f9d378c5d96307a718036069a50b452604e61
MD5 5f0f7706a115c52461ece68d1a77f814
BLAKE2b-256 8ff632eea7aaa6fd835403235c1540ddda386662186bf015ef5d2f854f0d61c5

See more details on using hashes here.

File details

Details for the file chio-1.1.20-py3-none-any.whl.

File metadata

  • Download URL: chio-1.1.20-py3-none-any.whl
  • Upload date:
  • Size: 70.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for chio-1.1.20-py3-none-any.whl
Algorithm Hash digest
SHA256 c7aa42cc9a137001bd34372279cc0305e30dc390961a1a8c86705d7a36091d77
MD5 36fbbfe0fa433bce3d1886d20df0201f
BLAKE2b-256 68ce46ff179cb7e4ebe35e6420e32f15eb01a954c8b28e6a81abb3af7253af9d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page