chio

package module
v0.0.0-...-ffb72b7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2025 License: MIT Imports: 11 Imported by: 0

README

Chio

Chio (Bancho Input/Output) is a bancho packet serialization library written in go, that aims to support as many clients as possible.

[!WARNING] This project is a work in progress and is not ready for production usage yet. For a full implementation, please view chio.py!

Example Usage

import (
    "io"
    "fmt"

    "github.com/lekuruu/chio"
)

// Assuming you have some kind of tcp server
func HandleConnection(stream io.ReadWriteCloser, version int) {
    defer stream.Close()

    io := chio.GetClientInterface(version)
    io.WriteLoginReply(stream, 2)
    io.WriteUserStats(stream, chio.UserInfo{ ... })
    io.WriteAnnouncement(stream, "Hello, World!")

    for {
        packet, err := client.IO.ReadPacket(stream)
        if err != nil {
            fmt.Println("Error reading packet:", err.Error())
            break
        }

        fmt.Printf("Received packet: %d, %v\n", packet.Id, packet.Data)
    }
}

Documentation

Index

Constants

View Source
const (
	OsuSendUserStatus              uint16 = 0
	OsuSendIrcMessage              uint16 = 1
	OsuExit                        uint16 = 2
	OsuRequestStatusUpdate         uint16 = 3
	OsuPong                        uint16 = 4
	BanchoLoginReply               uint16 = 5
	BanchoCommandError             uint16 = 6
	BanchoSendMessage              uint16 = 7
	BanchoPing                     uint16 = 8
	BanchoHandleIrcChangeUsername  uint16 = 9
	BanchoHandleIrcQuit            uint16 = 10
	BanchoHandleOsuUpdate          uint16 = 11
	BanchoHandleOsuQuit            uint16 = 12
	BanchoSpectatorJoined          uint16 = 13
	BanchoSpectatorLeft            uint16 = 14
	BanchoSpectateFrames           uint16 = 15
	OsuStartSpectating             uint16 = 16
	OsuStopSpectating              uint16 = 17
	OsuSpectateFrames              uint16 = 18
	BanchoVersionUpdate            uint16 = 19
	OsuErrorReport                 uint16 = 20
	OsuCantSpectate                uint16 = 21
	BanchoSpectatorCantSpectate    uint16 = 22
	BanchoGetAttention             uint16 = 23
	BanchoAnnounce                 uint16 = 24
	OsuSendIrcMessagePrivate       uint16 = 25
	BanchoMatchUpdate              uint16 = 26
	BanchoMatchNew                 uint16 = 27
	BanchoMatchDisband             uint16 = 28
	OsuLobbyPart                   uint16 = 29
	OsuLobbyJoin                   uint16 = 30
	OsuMatchCreate                 uint16 = 31
	OsuMatchJoin                   uint16 = 32
	OsuMatchPart                   uint16 = 33
	BanchoLobbyJoin                uint16 = 34
	BanchoLobbyPart                uint16 = 35
	BanchoMatchJoinSuccess         uint16 = 36
	BanchoMatchJoinFail            uint16 = 37
	OsuMatchChangeSlot             uint16 = 38
	OsuMatchReady                  uint16 = 39
	OsuMatchLock                   uint16 = 40
	OsuMatchChangeSettings         uint16 = 41
	BanchoFellowSpectatorJoined    uint16 = 42
	BanchoFellowSpectatorLeft      uint16 = 43
	OsuMatchStart                  uint16 = 44
	BanchoMatchStart               uint16 = 46
	OsuMatchScoreUpdate            uint16 = 47
	BanchoMatchScoreUpdate         uint16 = 48
	OsuMatchComplete               uint16 = 49
	BanchoMatchTransferHost        uint16 = 50
	OsuMatchChangeMods             uint16 = 51
	OsuMatchLoadComplete           uint16 = 52
	BanchoMatchAllPlayersLoaded    uint16 = 53
	OsuMatchNoBeatmap              uint16 = 54
	OsuMatchNotReady               uint16 = 55
	OsuMatchFailed                 uint16 = 56
	BanchoMatchPlayerFailed        uint16 = 57
	BanchoMatchComplete            uint16 = 58
	OsuMatchHasBeatmap             uint16 = 59
	OsuMatchSkipRequest            uint16 = 60
	BanchoMatchSkip                uint16 = 61
	BanchoUnauthorized             uint16 = 62
	OsuChannelJoin                 uint16 = 63
	BanchoChannelJoinSuccess       uint16 = 64
	BanchoChannelAvailable         uint16 = 65
	BanchoChannelRevoked           uint16 = 66
	BanchoChannelAvailableAutojoin uint16 = 67
	OsuBeatmapInfoRequest          uint16 = 68
	BanchoBeatmapInfoReply         uint16 = 69
	OsuMatchTransferHost           uint16 = 70
	BanchoLoginPermissions         uint16 = 71
	BanchoFriendsList              uint16 = 72
	OsuFriendsAdd                  uint16 = 73
	OsuFriendsRemove               uint16 = 74
	BanchoProtocolNegotiation      uint16 = 75
	BanchoTitleUpdate              uint16 = 76
	OsuMatchChangeTeam             uint16 = 77
	OsuChannelLeave                uint16 = 78
	OsuReceiveUpdates              uint16 = 79
	BanchoMonitor                  uint16 = 80
	BanchoMatchPlayerSkipped       uint16 = 81
	OsuSetIrcAwayMessage           uint16 = 82
	BanchoUserPresence             uint16 = 83
	OsuUserStatsRequest            uint16 = 85
	BanchoRestart                  uint16 = 86
	OsuInvite                      uint16 = 87
	BanchoInvite                   uint16 = 88
	BanchoChannelInfoComplete      uint16 = 89
	OsuMatchChangePassword         uint16 = 90
	BanchoMatchChangePassword      uint16 = 91
	BanchoSilenceInfo              uint16 = 92
	OsuTournamentMatchInfo         uint16 = 93
	BanchoUserSilenced             uint16 = 94
	BanchoUserPresenceSingle       uint16 = 95
	BanchoUserPresenceBundle       uint16 = 96
	OsuPresenceRequest             uint16 = 97
	OsuPresenceRequestAll          uint16 = 98
	OsuChangeFriendOnlyDMs         uint16 = 99
	BanchoUserDMsBlocked           uint16 = 100
	BanchoTargetIsSilenced         uint16 = 101
	BanchoVersionUpdateForced      uint16 = 102
	BanchoSwitchServer             uint16 = 103
	BanchoAccountRestricted        uint16 = 104
	BanchoRTX                      uint16 = 105
	BanchoMatchAbort               uint16 = 106
	BanchoSwitchTournamentServer   uint16 = 107
	OsuTournamentJoinMatchChannel  uint16 = 108
	OsuTournamentLeaveMatchChannel uint16 = 109

	BanchoHandleIrcJoin   uint16 = 0xFFFF
	OsuMatchChangeBeatmap uint16 = 0xFFFE
)
View Source
const (
	StatusIdle         uint8 = 0
	StatusAfk          uint8 = 1
	StatusPlaying      uint8 = 2
	StatusEditing      uint8 = 3
	StatusModding      uint8 = 4
	StatusMultiplayer  uint8 = 5
	StatusWatching     uint8 = 6
	StatusUnknown      uint8 = 7
	StatusTesting      uint8 = 8
	StatusSubmitting   uint8 = 9
	StatusPaused       uint8 = 10
	StatusLobby        uint8 = 11
	StatusMultiplaying uint8 = 12
	StatusOsuDirect    uint8 = 13

	// Unused in later versions, but required for compatibility
	StatusStatsUpdate uint8 = 10
)
View Source
const (
	ModeOsu   uint8 = 0
	ModeTaiko uint8 = 1
	ModeCatch uint8 = 2
	ModeMania uint8 = 3
)
View Source
const (
	InvalidLogin          int32 = -1
	InvalidVersion        int32 = -2
	UserBanned            int32 = -3
	UserInactive          int32 = -4
	ServerError           int32 = -5
	UnauthorizedTestBuild int32 = -6
)
View Source
const (
	PermissionsNone       = 0
	PermissionsRegular    = 1 << 0
	PermissionsBAT        = 1 << 1
	PermissionsSupporter  = 1 << 2
	PermissionsFriend     = 1 << 3
	PermissionsPeppy      = 1 << 4
	PermissionsTournament = 1 << 5
)
View Source
const (
	QuitStateGone         uint8 = 0
	QuitStateOsuRemaining uint8 = 1
	QuitStateIrcRemaining uint8 = 2
)
View Source
const (
	AvatarExtensionNone = 0
	AvatarExtensionPng  = 1
	AvatarExtensionJpg  = 2
)
View Source
const (
	PresenceFilterNone    uint8 = 0
	PresenceFilterAll     uint8 = 1
	PresenceFilterFriends uint8 = 2
)
View Source
const (
	CompletenessStatusOnly uint8 = 0
	CompletenessStatistics uint8 = 1
	CompletenessFull       uint8 = 2
)
View Source
const (
	ReplayActionStandard      uint8 = 0
	ReplayActionNewSong       uint8 = 1
	ReplayActionSkip          uint8 = 2
	ReplayActionCompletion    uint8 = 3
	ReplayActionFail          uint8 = 4
	ReplayActionPause         uint8 = 5
	ReplayActionUnpause       uint8 = 6
	ReplayActionSongSelect    uint8 = 7
	ReplayActionWatchingOther uint8 = 8
)
View Source
const (
	ButtonStateNoButton uint8 = 0
	ButtonStateLeft1    uint8 = 1 << 0
	ButtonStateRight1   uint8 = 1 << 1
	ButtonStateLeft2    uint8 = 1 << 2
	ButtonStateRight2   uint8 = 1 << 3
	ButtonStateSmoke    uint8 = 1 << 4
)
View Source
const (
	OsuRankXH int8 = 0
	OsuRankSH int8 = 1
	OsuRankX  int8 = 2
	OsuRankS  int8 = 3
	OsuRankA  int8 = 4
	OsuRankB  int8 = 5
	OsuRankC  int8 = 6
	OsuRankD  int8 = 7
	OsuRankF  int8 = 8
	OsuRankN  int8 = 9
)
View Source
const (
	NoMod       uint32 = 0
	NoFail      uint32 = 1 << 0
	Easy        uint32 = 1 << 1
	NoVideo     uint32 = 1 << 2
	Hidden      uint32 = 1 << 3
	HardRock    uint32 = 1 << 4
	SuddenDeath uint32 = 1 << 5
	DoubleTime  uint32 = 1 << 6
	Relax       uint32 = 1 << 7
	HalfTime    uint32 = 1 << 8
	Nightcore   uint32 = 1 << 9
	Flashlight  uint32 = 1 << 10
	Autoplay    uint32 = 1 << 11
	SpunOut     uint32 = 1 << 12
	Autopilot   uint32 = 1 << 13
	Perfect     uint32 = 1 << 14
	Key4        uint32 = 1 << 15
	Key5        uint32 = 1 << 16
	Key6        uint32 = 1 << 17
	Key7        uint32 = 1 << 18
	Key8        uint32 = 1 << 19
	FadeIn      uint32 = 1 << 20
	Random      uint32 = 1 << 21
	Cinema      uint32 = 1 << 22
	Target      uint32 = 1 << 23
	Key9        uint32 = 1 << 24
	KeyCoop     uint32 = 1 << 25
	Key1        uint32 = 1 << 26
	Key3        uint32 = 1 << 27
	Key2        uint32 = 1 << 28
	ScoreV2     uint32 = 1 << 29
	Mirror      uint32 = 1 << 30
)
View Source
const (
	MatchTypeStandard  uint8 = 0
	MatchTypePowerplay uint8 = 1
)
View Source
const (
	ScoringTypeScore    uint8 = 0
	ScoringTypeAccuracy uint8 = 1
	ScoringTypeCombo    uint8 = 2
	ScoringTypeScoreV2  uint8 = 3
)
View Source
const (
	TeamTypeHeadToHead uint8 = 0
	TeamTypeTagCoop    uint8 = 1
	TeamTypeTeamVs     uint8 = 2
	TeamTypeTagTeam    uint8 = 3
)
View Source
const (
	SlotStatusOpen      uint8 = 1 << 0
	SlotStatusLocked    uint8 = 1 << 1
	SlotStatusNotReady  uint8 = 1 << 2
	SlotStatusReady     uint8 = 1 << 3
	SlotStatusNoMap     uint8 = 1 << 4
	SlotStatusPlaying   uint8 = 1 << 5
	SlotStatusComplete  uint8 = 1 << 6
	SlotStatusQuit      uint8 = 1 << 7
	SlotStatusHasPlayer uint8 = SlotStatusNotReady | SlotStatusReady | SlotStatusNoMap | SlotStatusPlaying | SlotStatusComplete
)
View Source
const (
	SlotTeamNeutral uint8 = 0
	SlotTeamBlue    uint8 = 1
	SlotTeamRed     uint8 = 2
)
View Source
const (
	RankedStatusPending   int8 = 0
	RankedStatusRanked    int8 = 1
	RankedStatusApproved  int8 = 2
	RankedStatusQualified int8 = 3
)

Variables

View Source
var CountryCodes []string = []string{}/* 253 elements not displayed */
View Source
var CountryNames []string = []string{}/* 253 elements not displayed */

Functions

func GetCountryIndexFromCode

func GetCountryIndexFromCode(code string) int8

func GetCountryIndexFromName

func GetCountryIndexFromName(name string) int8

func HandlePanic

func HandlePanic(err *error)

Types

type BanchoIO

type BanchoIO interface {
	// WritePacket writes a packet to the provided stream
	WritePacket(stream io.Writer, packetId uint16, data []byte) error

	// ReadPacket reads a packet from the provided stream
	ReadPacket(stream io.Reader) (packet *BanchoPacket, err error)

	// SupportedPackets returns a list of packetIds that are supported by the client
	SupportedPackets() []uint16

	// ImplementsPacket checks if the packetId is implemented in the client
	ImplementsPacket(packetId uint16) bool

	// ProtocolVersion returns the bancho protocol version used by the client
	ProtocolVersion() int

	// OverrideProtocolVersion lets you specify a custom bancho protocol version
	OverrideProtocolVersion(version int)

	// MatchSlotSize returns the number of slots that are used in the match
	MatchSlotSize() int

	// OverrideMatchSlotSize lets you specify a custom amount of slots to read & write to the client
	OverrideMatchSlotSize(amount int)

	// Packet writers
	BanchoWriters
}

BanchoIO is an interface that wraps the basic methods for reading and writing packets to a Bancho client

func GetClientInterface

func GetClientInterface(clientVersion int) BanchoIO

GetClientInterface returns a BanchoIO interface for the given client version

type BanchoPacket

type BanchoPacket struct {
	Id   uint16
	Data interface{}
}

BanchoPackcet is a struct that represents a packet that is sent or received

type BanchoWriters

type BanchoWriters interface {
	WriteLoginReply(stream io.Writer, reply int32) error
	WriteMessage(stream io.Writer, message Message) error
	WritePing(stream io.Writer) error
	WriteIrcChangeUsername(stream io.Writer, oldName, newName string) error
	WriteUserStats(stream io.Writer, info UserInfo) error
	WriteUserQuit(stream io.Writer, quit UserQuit) error
	WriteSpectatorJoined(stream io.Writer, userId int32) error
	WriteSpectatorLeft(stream io.Writer, userId int32) error
	WriteSpectateFrames(stream io.Writer, bundle ReplayFrameBundle) error
	WriteVersionUpdate(stream io.Writer) error
	WriteSpectatorCantSpectate(stream io.Writer, userId int32) error
	WriteGetAttention(stream io.Writer) error
	WriteAnnouncement(stream io.Writer, message string) error
	WriteMatchUpdate(stream io.Writer, match Match) error
	WriteMatchNew(stream io.Writer, match Match) error
	WriteMatchDisband(stream io.Writer, matchId int32) error
	WriteLobbyJoin(stream io.Writer, userId int32) error
	WriteLobbyPart(stream io.Writer, userId int32) error
	WriteMatchJoinSuccess(stream io.Writer, match Match) error
	WriteMatchJoinFail(stream io.Writer) error
	WriteFellowSpectatorJoined(stream io.Writer, userId int32) error
	WriteFellowSpectatorLeft(stream io.Writer, userId int32) error
	WriteMatchStart(stream io.Writer, match Match) error
	WriteMatchScoreUpdate(stream io.Writer, frame ScoreFrame) error
	WriteMatchTransferHost(stream io.Writer) error
	WriteMatchAllPlayersLoaded(stream io.Writer) error
	WriteMatchPlayerFailed(stream io.Writer, slotId uint32) error
	WriteMatchComplete(stream io.Writer) error
	WriteMatchSkip(stream io.Writer) error
	WriteUnauthorized(stream io.Writer) error
	WriteChannelJoinSuccess(stream io.Writer, channel string) error
	WriteChannelRevoked(stream io.Writer, channel string) error
	WriteChannelAvailable(stream io.Writer, channel Channel) error
	WriteChannelAvailableAutojoin(stream io.Writer, channel Channel) error
	WriteBeatmapInfoReply(stream io.Writer, reply BeatmapInfoReply) error
	WriteLoginPermissions(stream io.Writer, permissions uint32) error
	WriteFriendsList(stream io.Writer, userIds []int32) error
	WriteProtocolNegotiation(stream io.Writer, version int32) error
	WriteTitleUpdate(stream io.Writer, update TitleUpdate) error
	WriteMonitor(stream io.Writer) error
	WriteMatchPlayerSkipped(stream io.Writer, slotId int32) error
	WriteUserPresence(stream io.Writer, info UserInfo) error
	WriteRestart(stream io.Writer, retryMs int32) error
	WriteInvite(stream io.Writer, message Message) error
	WriteChannelInfoComplete(stream io.Writer) error
	WriteMatchChangePassword(stream io.Writer, password string) error
	WriteSilenceInfo(stream io.Writer, timeRemaining int32) error
	WriteUserSilenced(stream io.Writer, userId uint32) error
	WriteUserPresenceSingle(stream io.Writer, info UserInfo) error
	WriteUserPresenceBundle(stream io.Writer, infos []UserInfo) error
	WriteUserDMsBlocked(stream io.Writer, targetName string) error
	WriteTargetIsSilenced(stream io.Writer, targetName string) error
	WriteVersionUpdateForced(stream io.Writer) error
	WriteSwitchServer(stream io.Writer, target int32) error
	WriteAccountRestricted(stream io.Writer) error
	WriteRTX(stream io.Writer, message string) error
	WriteMatchAbort(stream io.Writer) error
	WriteSwitchTournamentServer(stream io.Writer, ip string) error
}

BanchoWriters is an interface that wraps the methods for writing to a Bancho client

type BeatmapInfo

type BeatmapInfo struct {
	Index        int16
	BeatmapId    int32
	BeatmapSetId int32
	ThreadId     int32
	RankedStatus int8
	OsuRank      int8
	TaikoRank    int8
	FruitsRank   int8
	ManiaRank    int8
	Checksum     string
}

func (*BeatmapInfo) IsRanked

func (info *BeatmapInfo) IsRanked() bool

IsRanked is used to check whether or not the map is ranked/approved

type BeatmapInfoReply

type BeatmapInfoReply struct {
	Beatmaps []BeatmapInfo
}

type BeatmapInfoRequest

type BeatmapInfoRequest struct {
	Filenames []string
	Ids       []int32
}

type Channel

type Channel struct {
	Name      string
	Topic     string
	Owner     string
	UserCount int16
}

type ErrorCollection

type ErrorCollection struct {
	// contains filtered or unexported fields
}

func NewErrorCollection

func NewErrorCollection() *ErrorCollection

func (*ErrorCollection) Add

func (ec *ErrorCollection) Add(err error)

func (*ErrorCollection) Errors

func (ec *ErrorCollection) Errors() []error

func (*ErrorCollection) HasErrors

func (ec *ErrorCollection) HasErrors() bool

func (*ErrorCollection) Length

func (ec *ErrorCollection) Length() int

func (*ErrorCollection) Next

func (ec *ErrorCollection) Next() error

func (*ErrorCollection) Pop

func (ec *ErrorCollection) Pop(index int) error

func (*ErrorCollection) String

func (ec *ErrorCollection) String() string

type Match

type Match struct {
	Id              int32
	InProgress      bool
	Type            uint8
	Mods            uint32
	Name            string
	Password        string
	BeatmapText     string
	BeatmapId       int32
	BeatmapChecksum string
	Slots           []*MatchSlot
	HostId          int32
	Mode            uint8
	ScoringType     uint8
	TeamType        uint8
	Freemod         bool
	Seed            int32
}

type MatchJoin

type MatchJoin struct {
	MatchId  int32
	Password string
}

type MatchSlot

type MatchSlot struct {
	UserId int32
	Status uint8
	Team   uint8
	Mods   uint32
}

func (*MatchSlot) HasPlayer

func (s *MatchSlot) HasPlayer() bool

type Message

type Message struct {
	Sender   string
	Content  string
	Target   string
	SenderId int32
}

type ReplayFrame

type ReplayFrame struct {
	ButtonState uint8
	MouseX      float32
	MouseY      float32
	Time        int32
}

type ReplayFrameBundle

type ReplayFrameBundle struct {
	Action uint8
	Extra  int32
	Frames []*ReplayFrame
	Frame  *ScoreFrame
}

type ScoreFrame

type ScoreFrame struct {
	Time         int32
	Id           uint8
	Total300     uint16
	Total100     uint16
	Total50      uint16
	TotalGeki    uint16
	TotalKatu    uint16
	TotalMiss    uint16
	TotalScore   uint32
	MaxCombo     uint16
	CurrentCombo uint16
	Perfect      bool
	Hp           uint8
	TagByte      uint8
}

func (*ScoreFrame) Checksum

func (sf *ScoreFrame) Checksum() string

ScoreFrame checksum calculation used in version b323

type TitleUpdate

type TitleUpdate struct {
	ImageUrl    string
	RedirectUrl string
}

type UserInfo

type UserInfo struct {
	Id       int32
	Name     string
	Presence *UserPresence
	Status   *UserStatus
	Stats    *UserStats
}

func (*UserInfo) AvatarFilename

func (u *UserInfo) AvatarFilename() string

type UserPresence

type UserPresence struct {
	IsIrc        bool
	Timezone     int8
	CountryIndex int8
	Permissions  uint8
	Longitude    float32
	Latitude     float32
	City         string
}

func (*UserPresence) CountryCode

func (presence *UserPresence) CountryCode() string

func (*UserPresence) CountryName

func (presence *UserPresence) CountryName() string

func (*UserPresence) Location

func (presence *UserPresence) Location() string

type UserQuit

type UserQuit struct {
	Info      *UserInfo
	QuitState uint8
}

type UserStats

type UserStats struct {
	Rank      int32
	Rscore    uint64
	Tscore    uint64
	Accuracy  float64
	Playcount int32
	PP        uint16
}

type UserStatus

type UserStatus struct {
	Action          uint8
	Text            string
	Mods            uint32
	Mode            uint8
	BeatmapChecksum string
	BeatmapId       int32
	UpdateStats     bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL