diff --git a/session/processor.go b/session/processor.go index 69391f7..2bd60ad 100644 --- a/session/processor.go +++ b/session/processor.go @@ -49,6 +49,12 @@ type Processor interface { ProcessCache(ctx *Context, new *[]byte) // ProcessDisconnection is called when the player disconnects from the proxy. ProcessDisconnection(ctx *Context, message *string) + // ProcessPreFallback is called before transferring the player to a fallback server. + ProcessPreFallback(ctx *Context, origin *string, target *string) + // ProcessFallbackFailure is called when the fallback transfer fails. + ProcessFallbackFailure(ctx *Context, origin *string, target *string, err error) + // ProcessPostFallback is called after transferring the player to a fallback server. + ProcessPostFallback(ctx *Context, origin *string, target *string) } // NopProcessor is a no-operation implementation of the Processor interface. @@ -57,14 +63,17 @@ type NopProcessor struct{} // Ensure that NopProcessor satisfies the Processor interface. var _ Processor = NopProcessor{} -func (NopProcessor) ProcessStartGame(_ *Context, _ *minecraft.GameData) {} -func (NopProcessor) ProcessServer(_ *Context, _ *packet.Packet) {} -func (NopProcessor) ProcessServerEncoded(_ *Context, _ *[]byte) {} -func (NopProcessor) ProcessClient(_ *Context, _ *packet.Packet) {} -func (NopProcessor) ProcessClientEncoded(_ *Context, _ *[]byte) {} -func (NopProcessor) ProcessFlush(_ *Context) {} -func (NopProcessor) ProcessPreTransfer(_ *Context, _ *string, _ *string) {} -func (NopProcessor) ProcessTransferFailure(_ *Context, _ *string, _ *string) {} -func (NopProcessor) ProcessPostTransfer(_ *Context, _ *string, _ *string) {} -func (NopProcessor) ProcessCache(_ *Context, _ *[]byte) {} -func (NopProcessor) ProcessDisconnection(_ *Context, _ *string) {} +func (NopProcessor) ProcessStartGame(_ *Context, _ *minecraft.GameData) {} +func (NopProcessor) ProcessServer(_ *Context, _ *packet.Packet) {} +func (NopProcessor) ProcessServerEncoded(_ *Context, _ *[]byte) {} +func (NopProcessor) ProcessClient(_ *Context, _ *packet.Packet) {} +func (NopProcessor) ProcessClientEncoded(_ *Context, _ *[]byte) {} +func (NopProcessor) ProcessFlush(_ *Context) {} +func (NopProcessor) ProcessPreTransfer(_ *Context, _ *string, _ *string) {} +func (NopProcessor) ProcessTransferFailure(_ *Context, _ *string, _ *string) {} +func (NopProcessor) ProcessPostTransfer(_ *Context, _ *string, _ *string) {} +func (NopProcessor) ProcessCache(_ *Context, _ *[]byte) {} +func (NopProcessor) ProcessDisconnection(_ *Context, _ *string) {} +func (NopProcessor) ProcessPreFallback(_ *Context, _ *string, _ *string) {} +func (NopProcessor) ProcessFallbackFailure(_ *Context, _ *string, _ *string, _ error) {} +func (NopProcessor) ProcessPostFallback(_ *Context, _ *string, _ *string) {} diff --git a/session/session.go b/session/session.go index c4129ab..fce5475 100644 --- a/session/session.go +++ b/session/session.go @@ -321,15 +321,30 @@ func (s *Session) fallback() error { return errors.New("already in fallback") } + s.serverMu.RLock() + origin := s.serverAddr + s.serverMu.RUnlock() + + processorCtx := NewContext() + addr, err := s.discovery.DiscoverFallback(s.client) if err != nil { + s.Processor().ProcessFallbackFailure(processorCtx, &origin, nil, err) return fmt.Errorf("discovery failed: %w", err) } + s.Processor().ProcessPreFallback(processorCtx, &origin, &addr) + if processorCtx.Cancelled() { + return errors.New("processor failed") + } + s.logger.Debug("transferring session to a fallback server", "addr", addr) if err := s.Transfer(addr); err != nil { + s.Processor().ProcessFallbackFailure(processorCtx, &origin, &addr, err) return fmt.Errorf("transfer failed: %w", err) } + + s.Processor().ProcessPostFallback(processorCtx, &origin, &addr) return nil }