Allow regiserting multiple callbacks (closed #4)

This commit is contained in:
ChillerDragon 2024-06-25 09:22:25 +08:00
parent 141865538f
commit 3ecb2a32aa
8 changed files with 198 additions and 274 deletions

View file

@ -60,8 +60,12 @@ func main() {
})
// if you do not implement OnError it will throw on error
client.OnError(func(err error) {
client.OnError(func(err error) bool {
fmt.Print(err)
// return false to consume the error
// return true to pass it on to the next error handler (likely throws in the end)
return false
})
go func() {

View file

@ -11,91 +11,117 @@ import (
// It might send a response packet
type DefaultAction func()
// Internal method to call user hooks and register default behavior for a given message
// Example:
//
// userMsgCallback(
//
// client.Callbacks.GameSvMotd,
// &messages7.SvMotd{},
// func() { fmt.Println("default action") },
//
// )
func userMsgCallback[T any](userCallbacks []func(T, DefaultAction), msg T, defaultAction DefaultAction) {
if len(userCallbacks) == 0 {
defaultAction()
return
}
for _, callback := range userCallbacks {
callback(msg, defaultAction)
}
}
// TODO: this should be a map but the type checker broke me
//
// // key is the network7.MessageId
// UserMsgCallbacks map[int]UserMsgCallback
type UserMsgCallbacks struct {
PacketIn func(*protocol7.Packet) bool
PacketOut func(*protocol7.Packet) bool
MsgUnknown func(*messages7.Unknown, DefaultAction)
InternalError func(error)
Snapshot func(*snapshot7.Snapshot, DefaultAction)
// return false to drop the packet
PacketIn []func(*protocol7.Packet) bool
// return false to drop the packet
PacketOut []func(*protocol7.Packet) bool
// return false to drop the error (ignore it)
//
// return true to pass the error on and finally throw
InternalError []func(error) bool
MsgUnknown []func(*messages7.Unknown, DefaultAction)
Snapshot []func(*snapshot7.Snapshot, DefaultAction)
CtrlKeepAlive func(*messages7.CtrlKeepAlive, DefaultAction)
CtrlConnect func(*messages7.CtrlConnect, DefaultAction)
CtrlAccept func(*messages7.CtrlAccept, DefaultAction)
CtrlToken func(*messages7.CtrlToken, DefaultAction)
CtrlClose func(*messages7.CtrlClose, DefaultAction)
CtrlKeepAlive []func(*messages7.CtrlKeepAlive, DefaultAction)
CtrlConnect []func(*messages7.CtrlConnect, DefaultAction)
CtrlAccept []func(*messages7.CtrlAccept, DefaultAction)
CtrlToken []func(*messages7.CtrlToken, DefaultAction)
CtrlClose []func(*messages7.CtrlClose, DefaultAction)
SysInfo func(*messages7.Info, DefaultAction)
SysMapChange func(*messages7.MapChange, DefaultAction)
SysMapData func(*messages7.MapData, DefaultAction)
SysServerInfo func(*messages7.ServerInfo, DefaultAction)
SysConReady func(*messages7.ConReady, DefaultAction)
SysSnap func(*messages7.Snap, DefaultAction)
SysSnapEmpty func(*messages7.SnapEmpty, DefaultAction)
SysSnapSingle func(*messages7.SnapSingle, DefaultAction)
SysSnapSmall func(*messages7.SnapSmall, DefaultAction)
SysInputTiming func(*messages7.InputTiming, DefaultAction)
SysRconAuthOn func(*messages7.RconAuthOn, DefaultAction)
SysRconAuthOff func(*messages7.RconAuthOff, DefaultAction)
SysRconLine func(*messages7.RconLine, DefaultAction)
SysRconCmdAdd func(*messages7.RconCmdAdd, DefaultAction)
SysRconCmdRem func(*messages7.RconCmdRem, DefaultAction)
SysAuthChallenge func(*messages7.AuthChallenge, DefaultAction)
SysAuthResult func(*messages7.AuthResult, DefaultAction)
SysReady func(*messages7.Ready, DefaultAction)
SysEnterGame func(*messages7.EnterGame, DefaultAction)
SysInput func(*messages7.Input, DefaultAction)
SysRconCmd func(*messages7.RconCmd, DefaultAction)
SysRconAuth func(*messages7.RconAuth, DefaultAction)
SysRequestMapData func(*messages7.RequestMapData, DefaultAction)
SysAuthStart func(*messages7.AuthStart, DefaultAction)
SysAuthResponse func(*messages7.AuthResponse, DefaultAction)
SysPing func(*messages7.Ping, DefaultAction)
SysPingReply func(*messages7.PingReply, DefaultAction)
SysError func(*messages7.Error, DefaultAction)
SysMaplistEntryAdd func(*messages7.MaplistEntryAdd, DefaultAction)
SysMaplistEntryRem func(*messages7.MaplistEntryRem, DefaultAction)
SysInfo []func(*messages7.Info, DefaultAction)
SysMapChange []func(*messages7.MapChange, DefaultAction)
SysMapData []func(*messages7.MapData, DefaultAction)
SysServerInfo []func(*messages7.ServerInfo, DefaultAction)
SysConReady []func(*messages7.ConReady, DefaultAction)
SysSnap []func(*messages7.Snap, DefaultAction)
SysSnapEmpty []func(*messages7.SnapEmpty, DefaultAction)
SysSnapSingle []func(*messages7.SnapSingle, DefaultAction)
SysSnapSmall []func(*messages7.SnapSmall, DefaultAction)
SysInputTiming []func(*messages7.InputTiming, DefaultAction)
SysRconAuthOn []func(*messages7.RconAuthOn, DefaultAction)
SysRconAuthOff []func(*messages7.RconAuthOff, DefaultAction)
SysRconLine []func(*messages7.RconLine, DefaultAction)
SysRconCmdAdd []func(*messages7.RconCmdAdd, DefaultAction)
SysRconCmdRem []func(*messages7.RconCmdRem, DefaultAction)
SysAuthChallenge []func(*messages7.AuthChallenge, DefaultAction)
SysAuthResult []func(*messages7.AuthResult, DefaultAction)
SysReady []func(*messages7.Ready, DefaultAction)
SysEnterGame []func(*messages7.EnterGame, DefaultAction)
SysInput []func(*messages7.Input, DefaultAction)
SysRconCmd []func(*messages7.RconCmd, DefaultAction)
SysRconAuth []func(*messages7.RconAuth, DefaultAction)
SysRequestMapData []func(*messages7.RequestMapData, DefaultAction)
SysAuthStart []func(*messages7.AuthStart, DefaultAction)
SysAuthResponse []func(*messages7.AuthResponse, DefaultAction)
SysPing []func(*messages7.Ping, DefaultAction)
SysPingReply []func(*messages7.PingReply, DefaultAction)
SysError []func(*messages7.Error, DefaultAction)
SysMaplistEntryAdd []func(*messages7.MaplistEntryAdd, DefaultAction)
SysMaplistEntryRem []func(*messages7.MaplistEntryRem, DefaultAction)
GameSvMotd func(*messages7.SvMotd, DefaultAction)
GameSvBroadcast func(*messages7.SvBroadcast, DefaultAction)
GameSvChat func(*messages7.SvChat, DefaultAction)
GameSvTeam func(*messages7.SvTeam, DefaultAction)
// GameSvKillMsg func(*messages7.SvKillMsg, DefaultAction)
// GameSvTuneParams func(*messages7.SvTuneParams, DefaultAction)
// GameSvExtraProjectile func(*messages7.SvExtraProjectile, DefaultAction)
GameReadyToEnter func(*messages7.SvReadyToEnter, DefaultAction)
// GameWeaponPickup func(*messages7.SvWeaponPickup, DefaultAction)
// GameEmoticon func(*messages7.SvEmoticon, DefaultAction)
// GameSvVoteClearoptions func(*messages7.SvVoteClearoptions, DefaultAction)
// GameSvVoteOptionlistadd func(*messages7.SvVoteOptionlistadd, DefaultAction)
// GameSvVotePptionadd func(*messages7.SvVotePptionadd, DefaultAction)
// GameSvVoteOptionremove func(*messages7.SvVoteOptionremove, DefaultAction)
// GameSvVoteSet func(*messages7.SvVoteSet, DefaultAction)
// GameSvVoteStatus func(*messages7.SvVoteStatus, DefaultAction)
// GameSvServerSettings func(*messages7.SvServerSettings, DefaultAction)
GameSvClientInfo func(*messages7.SvClientInfo, DefaultAction)
// GameSvGameInfo func(*messages7.SvGameInfo, DefaultAction)
// GameSvClientDrop func(*messages7.SvClientDrop, DefaultAction)
// GameSvGameMsg func(*messages7.SvGameMsg, DefaultAction)
// GameDeClientEnter func(*messages7.DeClientEnter, DefaultAction)
// GameDeClientLeave func(*messages7.DeClientLeave, DefaultAction)
// GameClSay func(*messages7.ClSay, DefaultAction)
// GameClSetTeam func(*messages7.ClSetTeam, DefaultAction)
// GameClSetSpectatorMode func(*messages7.ClSetSpectatorMode, DefaultAction)
GameClStartInfo func(*messages7.ClStartInfo, DefaultAction)
// GameClKill func(*messages7.ClKill, DefaultAction)
// GameClReadyChange func(*messages7.ClReadyChange, DefaultAction)
// GameClEmoticon func(*messages7.ClEmoticon, DefaultAction)
// GameClVote func(*messages7.ClVote, DefaultAction)
// GameClCallVote func(*messages7.ClCallVote, DefaultAction)
// GameSvSkinChange func(*messages7.SvSkinChange, DefaultAction)
// GameClSkinChange func(*messages7.ClSkinChange, DefaultAction)
// GameSvRaceFinish func(*messages7.SvRaceFinish, DefaultAction)
// GameSvCheckpoint func(*messages7.SvCheckpoint, DefaultAction)
// GameSvCommandInfo func(*messages7.SvCommandInfo, DefaultAction)
// GameSvCommandInfoRemove func(*messages7.SvCommandInfoRemove, DefaultAction)
// GameClCommand func(*messages7.ClCommand, DefaultAction)
GameSvMotd []func(*messages7.SvMotd, DefaultAction)
GameSvBroadcast []func(*messages7.SvBroadcast, DefaultAction)
GameSvChat []func(*messages7.SvChat, DefaultAction)
GameSvTeam []func(*messages7.SvTeam, DefaultAction)
// GameSvKillMsg []func(*messages7.SvKillMsg, DefaultAction)
// GameSvTuneParams []func(*messages7.SvTuneParams, DefaultAction)
// GameSvExtraProjectile []func(*messages7.SvExtraProjectile, DefaultAction)
GameSvReadyToEnter []func(*messages7.SvReadyToEnter, DefaultAction)
// GameWeaponPickup []func(*messages7.SvWeaponPickup, DefaultAction)
// GameEmoticon []func(*messages7.SvEmoticon, DefaultAction)
// GameSvVoteClearoptions []func(*messages7.SvVoteClearoptions, DefaultAction)
// GameSvVoteOptionlistadd []func(*messages7.SvVoteOptionlistadd, DefaultAction)
// GameSvVotePptionadd []func(*messages7.SvVotePptionadd, DefaultAction)
// GameSvVoteOptionremove []func(*messages7.SvVoteOptionremove, DefaultAction)
// GameSvVoteSet []func(*messages7.SvVoteSet, DefaultAction)
// GameSvVoteStatus []func(*messages7.SvVoteStatus, DefaultAction)
// GameSvServerSettings []func(*messages7.SvServerSettings, DefaultAction)
GameSvClientInfo []func(*messages7.SvClientInfo, DefaultAction)
// GameSvGameInfo []func(*messages7.SvGameInfo, DefaultAction)
// GameSvClientDrop []func(*messages7.SvClientDrop, DefaultAction)
// GameSvGameMsg []func(*messages7.SvGameMsg, DefaultAction)
// GameDeClientEnter []func(*messages7.DeClientEnter, DefaultAction)
// GameDeClientLeave []func(*messages7.DeClientLeave, DefaultAction)
// GameClSay []func(*messages7.ClSay, DefaultAction)
// GameClSetTeam []func(*messages7.ClSetTeam, DefaultAction)
// GameClSetSpectatorMode []func(*messages7.ClSetSpectatorMode, DefaultAction)
GameClStartInfo []func(*messages7.ClStartInfo, DefaultAction)
// GameClKill []func(*messages7.ClKill, DefaultAction)
// GameClReadyChange []func(*messages7.ClReadyChange, DefaultAction)
// GameClEmoticon []func(*messages7.ClEmoticon, DefaultAction)
// GameClVote []func(*messages7.ClVote, DefaultAction)
// GameClCallVote []func(*messages7.ClCallVote, DefaultAction)
// GameSvSkinChange []func(*messages7.SvSkinChange, DefaultAction)
// GameClSkinChange []func(*messages7.ClSkinChange, DefaultAction)
// GameSvRaceFinish []func(*messages7.SvRaceFinish, DefaultAction)
// GameSvCheckpoint []func(*messages7.SvCheckpoint, DefaultAction)
// GameSvCommandInfo []func(*messages7.SvCommandInfo, DefaultAction)
// GameSvCommandInfoRemove []func(*messages7.SvCommandInfoRemove, DefaultAction)
// GameClCommand []func(*messages7.ClCommand, DefaultAction)
}

View file

@ -39,9 +39,11 @@ type Client struct {
}
func (client *Client) throwError(err error) {
if client.Callbacks.InternalError != nil {
client.Callbacks.InternalError(err)
return
for _, callback := range client.Callbacks.InternalError {
if callback(err) == false {
return
}
}
log.Fatal(err)
}

View file

@ -11,70 +11,40 @@ import (
func (client *Client) processGame(netMsg messages7.NetMessage, response *protocol7.Packet) bool {
switch msg := netMsg.(type) {
case *messages7.SvMotd:
defaultAction := func() {
userMsgCallback(client.Callbacks.GameSvMotd, msg, func() {
if msg.Message != "" {
fmt.Printf("[motd] %s\n", msg.Message)
}
}
if client.Callbacks.GameSvMotd == nil {
defaultAction()
} else {
client.Callbacks.GameSvMotd(msg, defaultAction)
}
})
case *messages7.SvBroadcast:
defaultAction := func() {
userMsgCallback(client.Callbacks.GameSvBroadcast, msg, func() {
fmt.Printf("[broadcast] %s\n", msg.Message)
}
if client.Callbacks.GameSvBroadcast == nil {
defaultAction()
} else {
client.Callbacks.GameSvBroadcast(msg, defaultAction)
}
})
case *messages7.SvChat:
defaultAction := func() {
userMsgCallback(client.Callbacks.GameSvChat, msg, func() {
if msg.ClientId < 0 || msg.ClientId > network7.MaxClients {
fmt.Printf("[chat] *** %s\n", msg.Message)
return
}
name := client.Game.Players[msg.ClientId].Info.Name
fmt.Printf("[chat] <%s> %s\n", name, msg.Message)
}
if client.Callbacks.GameSvChat == nil {
defaultAction()
} else {
client.Callbacks.GameSvChat(msg, defaultAction)
}
})
case *messages7.SvClientInfo:
defaultAction := func() {
userMsgCallback(client.Callbacks.GameSvClientInfo, msg, func() {
client.Game.Players[msg.ClientId].Info = *msg
fmt.Printf("got client info id=%d name=%s\n", msg.ClientId, msg.Name)
}
if client.Callbacks.GameSvClientInfo == nil {
defaultAction()
} else {
client.Callbacks.GameSvClientInfo(msg, defaultAction)
}
})
case *messages7.SvReadyToEnter:
defaultAction := func() {
userMsgCallback(client.Callbacks.GameSvReadyToEnter, msg, func() {
fmt.Println("got ready to enter")
response.Messages = append(response.Messages, &messages7.EnterGame{})
}
if client.Callbacks.GameReadyToEnter == nil {
defaultAction()
} else {
client.Callbacks.GameReadyToEnter(msg, defaultAction)
}
})
case *messages7.Unknown:
defaultAction := func() {
userMsgCallback(client.Callbacks.MsgUnknown, msg, func() {
// TODO: msg id of unknown messages should not be -1
fmt.Println("TODO: why is the msg id -1???")
printUnknownMessage(msg, "unknown game")
}
if client.Callbacks.MsgUnknown == nil {
defaultAction()
} else {
client.Callbacks.MsgUnknown(msg, defaultAction)
}
})
default:
printUnknownMessage(netMsg, "unprocessed game")
return false

View file

@ -38,8 +38,8 @@ func (client *Client) processMessage(msg messages7.NetMessage, response *protoco
}
func (client *Client) processPacket(packet *protocol7.Packet) error {
if client.Callbacks.PacketIn != nil {
if client.Callbacks.PacketIn(packet) == false {
for _, callback := range client.Callbacks.PacketIn {
if callback(packet) == false {
return nil
}
}
@ -55,26 +55,16 @@ func (client *Client) processPacket(packet *protocol7.Packet) error {
// TODO: is this shadow nasty?
switch msg := msg.(type) {
case *messages7.CtrlKeepAlive:
defaultAction := func() {
userMsgCallback(client.Callbacks.CtrlKeepAlive, msg, func() {
fmt.Println("got keep alive")
}
if client.Callbacks.CtrlKeepAlive == nil {
defaultAction()
} else {
client.Callbacks.CtrlKeepAlive(msg, defaultAction)
}
})
case *messages7.CtrlConnect:
defaultAction := func() {
userMsgCallback(client.Callbacks.CtrlConnect, msg, func() {
fmt.Println("we got connect as a client. this should never happen lol.")
fmt.Println("who is tryint to connect to us? We are not a server!")
}
if client.Callbacks.CtrlConnect == nil {
defaultAction()
} else {
client.Callbacks.CtrlConnect(msg, defaultAction)
}
})
case *messages7.CtrlAccept:
defaultAction := func() {
userMsgCallback(client.Callbacks.CtrlAccept, msg, func() {
fmt.Println("got accept")
response.Messages = append(
response.Messages,
@ -85,23 +75,13 @@ func (client *Client) processPacket(packet *protocol7.Packet) error {
},
)
client.SendPacket(response)
}
if client.Callbacks.CtrlAccept == nil {
defaultAction()
} else {
client.Callbacks.CtrlAccept(msg, defaultAction)
}
})
case *messages7.CtrlClose:
defaultAction := func() {
userMsgCallback(client.Callbacks.CtrlClose, msg, func() {
fmt.Printf("disconnected (%s)\n", msg.Reason)
}
if client.Callbacks.CtrlClose == nil {
defaultAction()
} else {
client.Callbacks.CtrlClose(msg, defaultAction)
}
})
case *messages7.CtrlToken:
defaultAction := func() {
userMsgCallback(client.Callbacks.CtrlToken, msg, func() {
fmt.Printf("got server token %x\n", msg.Token)
client.Session.ServerToken = msg.Token
response.Header.Token = msg.Token
@ -112,21 +92,11 @@ func (client *Client) processPacket(packet *protocol7.Packet) error {
},
)
client.SendPacket(response)
}
if client.Callbacks.CtrlToken == nil {
defaultAction()
} else {
client.Callbacks.CtrlToken(msg, defaultAction)
}
})
case *messages7.Unknown:
defaultAction := func() {
userMsgCallback(client.Callbacks.MsgUnknown, msg, func() {
printUnknownMessage(msg, "unknown control")
}
if client.Callbacks.MsgUnknown == nil {
defaultAction()
} else {
client.Callbacks.MsgUnknown(msg, defaultAction)
}
})
return fmt.Errorf("unknown control message: %d\n", msg.MsgId())
default:
return fmt.Errorf("unprocessed control message: %d\n", msg.MsgId())

View file

@ -10,35 +10,20 @@ import (
func (client *Client) processSystem(netMsg messages7.NetMessage, response *protocol7.Packet) bool {
switch msg := netMsg.(type) {
case *messages7.MapChange:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysMapChange, msg, func() {
fmt.Println("got map change")
response.Messages = append(response.Messages, &messages7.Ready{})
}
if client.Callbacks.SysMapChange == nil {
defaultAction()
} else {
client.Callbacks.SysMapChange(msg, defaultAction)
}
})
case *messages7.MapData:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysMapData, msg, func() {
fmt.Printf("got map chunk %x\n", msg.Data)
}
if client.Callbacks.SysMapData == nil {
defaultAction()
} else {
client.Callbacks.SysMapData(msg, defaultAction)
}
})
case *messages7.ServerInfo:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysServerInfo, msg, func() {
fmt.Printf("connected to server with name '%s'\n", msg.Name)
}
if client.Callbacks.SysServerInfo == nil {
defaultAction()
} else {
client.Callbacks.SysServerInfo(msg, defaultAction)
}
})
case *messages7.ConReady:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysConReady, msg, func() {
fmt.Println("connected, sending info")
info := &messages7.ClStartInfo{
Name: client.Name,
@ -64,86 +49,49 @@ func (client *Client) processSystem(netMsg messages7.NetMessage, response *proto
ColorEyes: 0,
}
response.Messages = append(response.Messages, info)
}
if client.Callbacks.SysConReady == nil {
defaultAction()
} else {
client.Callbacks.SysConReady(msg, defaultAction)
}
})
case *messages7.Snap:
// fmt.Printf("got snap tick=%d\n", msg.GameTick)
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
userMsgCallback(client.Callbacks.SysSnap, msg, func() {
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
})
case *messages7.SnapSingle:
// fmt.Printf("got snap single tick=%d\n", msg.GameTick)
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
userMsgCallback(client.Callbacks.SysSnapSingle, msg, func() {
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
})
case *messages7.SnapEmpty:
// fmt.Printf("got snap empty tick=%d\n", msg.GameTick)
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
userMsgCallback(client.Callbacks.SysSnapEmpty, msg, func() {
response.Messages = append(response.Messages, &messages7.CtrlKeepAlive{})
})
case *messages7.InputTiming:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysInputTiming, msg, func() {
fmt.Printf("timing time left=%d\n", msg.TimeLeft)
}
if client.Callbacks.SysInputTiming == nil {
defaultAction()
} else {
client.Callbacks.SysInputTiming(msg, defaultAction)
}
})
case *messages7.RconAuthOn:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysRconAuthOn, msg, func() {
fmt.Println("you are now authenticated in rcon")
}
if client.Callbacks.SysRconAuthOn == nil {
defaultAction()
} else {
client.Callbacks.SysRconAuthOn(msg, defaultAction)
}
})
case *messages7.RconAuthOff:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysRconAuthOff, msg, func() {
fmt.Println("you are no longer authenticated in rcon")
}
if client.Callbacks.SysRconAuthOff == nil {
defaultAction()
} else {
client.Callbacks.SysRconAuthOff(msg, defaultAction)
}
})
case *messages7.RconLine:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysRconLine, msg, func() {
fmt.Printf("[rcon] %s\n", msg.Line)
}
if client.Callbacks.SysRconLine == nil {
defaultAction()
} else {
client.Callbacks.SysRconLine(msg, defaultAction)
}
})
case *messages7.RconCmdAdd:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysRconCmdAdd, msg, func() {
fmt.Printf("got rcon cmd=%s %s %s\n", msg.Name, msg.Params, msg.Help)
}
if client.Callbacks.SysRconCmdAdd == nil {
defaultAction()
} else {
client.Callbacks.SysRconCmdAdd(msg, defaultAction)
}
})
case *messages7.RconCmdRem:
defaultAction := func() {
userMsgCallback(client.Callbacks.SysRconCmdRem, msg, func() {
fmt.Printf("removed cmd=%s\n", msg.Name)
}
if client.Callbacks.SysRconCmdRem == nil {
defaultAction()
} else {
client.Callbacks.SysRconCmdRem(msg, defaultAction)
}
})
case *messages7.Unknown:
defaultAction := func() {
userMsgCallback(client.Callbacks.MsgUnknown, msg, func() {
// TODO: msg id of unknown messages should not be -1
fmt.Println("TODO: why is the msg id -1???")
printUnknownMessage(msg, "unknown system")
}
if client.Callbacks.MsgUnknown == nil {
defaultAction()
} else {
client.Callbacks.MsgUnknown(msg, defaultAction)
}
})
default:
printUnknownMessage(netMsg, "unprocessed system")
return false

View file

@ -62,11 +62,12 @@ func (client *Client) SendPacket(packet *protocol7.Packet) error {
}
client.QueuedMessages = nil
if client.Callbacks.PacketOut != nil {
if client.Callbacks.PacketOut(packet) == false {
for _, callback := range client.Callbacks.PacketOut {
if callback(packet) == false {
return nil
}
}
client.Conn.Write(packet.Pack(&client.Session))
return nil
}

View file

@ -11,8 +11,11 @@ import (
// --------------------------------
// if not implemented by the user the application might throw and exit
func (client *Client) OnError(callback func(err error)) {
client.Callbacks.InternalError = callback
//
// return false to drop the error
// return true if you did not handle the error and it should be passed on (will crash unless someone else catches it)
func (client *Client) OnError(callback func(err error) bool) {
client.Callbacks.InternalError = append(client.Callbacks.InternalError, callback)
}
// inspect outgoing traffic
@ -20,7 +23,7 @@ func (client *Client) OnError(callback func(err error)) {
//
// return false to drop the packet
func (client *Client) OnSend(callback func(packet *protocol7.Packet) bool) {
client.Callbacks.PacketOut = callback
client.Callbacks.PacketOut = append(client.Callbacks.PacketOut, callback)
}
// read incoming traffic
@ -28,17 +31,17 @@ func (client *Client) OnSend(callback func(packet *protocol7.Packet) bool) {
//
// return false to drop the packet
func (client *Client) OnPacket(callback func(packet *protocol7.Packet) bool) {
client.Callbacks.PacketIn = callback
client.Callbacks.PacketIn = append(client.Callbacks.PacketIn, callback)
}
func (client *Client) OnUnknown(callback func(msg *messages7.Unknown, defaultAction DefaultAction)) {
client.Callbacks.MsgUnknown = callback
client.Callbacks.MsgUnknown = append(client.Callbacks.MsgUnknown, callback)
}
// will be called when a snap, snap single or empty snapshot is received
// if you want to know which type of snapshot was received look at OnMsgSnap(), OnMsgSnapEmpty(), OnMsgSnapSingle(), OnMsgSnapSmall()
func (client *Client) OnSnapshot(callback func(snap *snapshot7.Snapshot, defaultAction DefaultAction)) {
client.Callbacks.Snapshot = callback
client.Callbacks.Snapshot = append(client.Callbacks.Snapshot, callback)
}
// --------------------------------
@ -46,24 +49,24 @@ func (client *Client) OnSnapshot(callback func(snap *snapshot7.Snapshot, default
// --------------------------------
func (client *Client) OnKeepAlive(callback func(msg *messages7.CtrlKeepAlive, defaultAction DefaultAction)) {
client.Callbacks.CtrlKeepAlive = callback
client.Callbacks.CtrlKeepAlive = append(client.Callbacks.CtrlKeepAlive, callback)
}
// This is just misleading. It should never be called. This message is only received by the server.
// func (client *Client) OnCtrlConnect(callback func(msg *messages7.CtrlConnect, defaultAction DefaultAction)) {
// client.Callbacks.CtrlConnect = callback
// client.Callbacks.CtrlConnect = append(// client.Callbacks, callback)
// }
func (client *Client) OnAccept(callback func(msg *messages7.CtrlAccept, defaultAction DefaultAction)) {
client.Callbacks.CtrlAccept = callback
client.Callbacks.CtrlAccept = append(client.Callbacks.CtrlAccept, callback)
}
func (client *Client) OnDisconnect(callback func(msg *messages7.CtrlClose, defaultAction DefaultAction)) {
client.Callbacks.CtrlClose = callback
client.Callbacks.CtrlClose = append(client.Callbacks.CtrlClose, callback)
}
func (client *Client) OnToken(callback func(msg *messages7.CtrlToken, defaultAction DefaultAction)) {
client.Callbacks.CtrlToken = callback
client.Callbacks.CtrlToken = append(client.Callbacks.CtrlToken, callback)
}
// --------------------------------
@ -71,19 +74,19 @@ func (client *Client) OnToken(callback func(msg *messages7.CtrlToken, defaultAct
// --------------------------------
func (client *Client) OnMotd(callback func(msg *messages7.SvMotd, defaultAction DefaultAction)) {
client.Callbacks.GameSvMotd = callback
client.Callbacks.GameSvMotd = append(client.Callbacks.GameSvMotd, callback)
}
func (client *Client) OnBroadcast(callback func(msg *messages7.SvBroadcast, defaultAction DefaultAction)) {
client.Callbacks.GameSvBroadcast = callback
client.Callbacks.GameSvBroadcast = append(client.Callbacks.GameSvBroadcast, callback)
}
func (client *Client) OnChat(callback func(msg *messages7.SvChat, defaultAction DefaultAction)) {
client.Callbacks.GameSvChat = callback
client.Callbacks.GameSvChat = append(client.Callbacks.GameSvChat, callback)
}
func (client *Client) OnTeam(callback func(msg *messages7.SvTeam, defaultAction DefaultAction)) {
client.Callbacks.GameSvTeam = callback
client.Callbacks.GameSvTeam = append(client.Callbacks.GameSvTeam, callback)
}
// --------------------------------
@ -91,25 +94,25 @@ func (client *Client) OnTeam(callback func(msg *messages7.SvTeam, defaultAction
// --------------------------------
func (client *Client) OnMapChange(callback func(msg *messages7.MapChange, defaultAction DefaultAction)) {
client.Callbacks.SysMapChange = callback
client.Callbacks.SysMapChange = append(client.Callbacks.SysMapChange, callback)
}
// You probably want to use OnSnapshot() instead
func (client *Client) OnMsgSnap(callback func(msg *messages7.Snap, defaultAction DefaultAction)) {
client.Callbacks.SysSnap = callback
client.Callbacks.SysSnap = append(client.Callbacks.SysSnap, callback)
}
// You probably want to use OnSnapshot() instead
func (client *Client) OnMsgSnapEmpty(callback func(msg *messages7.SnapEmpty, defaultAction DefaultAction)) {
client.Callbacks.SysSnapEmpty = callback
client.Callbacks.SysSnapEmpty = append(client.Callbacks.SysSnapEmpty, callback)
}
// You probably want to use OnSnapshot() instead
func (client *Client) OnMsgSnapSingle(callback func(msg *messages7.SnapSingle, defaultAction DefaultAction)) {
client.Callbacks.SysSnapSingle = callback
client.Callbacks.SysSnapSingle = append(client.Callbacks.SysSnapSingle, callback)
}
// You probably want to use OnSnapshot() instead
func (client *Client) OnMsgSnapSmall(callback func(msg *messages7.SnapSmall, defaultAction DefaultAction)) {
client.Callbacks.SysSnapSmall = callback
client.Callbacks.SysSnapSmall = append(client.Callbacks.SysSnapSmall, callback)
}