From bf764be450ac3c72d039b9668bf51df5a8a73cc2 Mon Sep 17 00:00:00 2001 From: Kigen Date: Sun, 13 Nov 2022 07:40:38 -0600 Subject: [PATCH] Add missing options and methods. (#1) Added MasterServer.Ping() method. Added timeout option to Query() method. Added local address option to Query() method. --- game.go | 40 ++++++++++++++++++++++++++++++---------- game_test.go | 2 +- master.go | 46 ++++++++++++++++++++++++++++++++++++---------- master_test.go | 2 +- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/game.go b/game.go index 3897c9d..4d4b0ca 100644 --- a/game.go +++ b/game.go @@ -71,6 +71,12 @@ func (g *GameServer) Ping() time.Duration { return g.ping } +func (g *GameServer) QueryTime() time.Time { + g.mutex.RLock() + defer g.mutex.RUnlock() + return g.queryTime +} + func (g *GameServer) Name() string { g.mutex.RLock() defer g.mutex.RUnlock() @@ -173,24 +179,38 @@ func (g *GameServer) Players() []Player { return g.players } -func (g *GameServer) Query() error { - g.mutex.Lock() - defer g.mutex.Unlock() +func (g *GameServer) Query(timeout time.Duration, localAddress string) error { + if timeout == 0 { + timeout = 5 * time.Second + } + + var localAddr *net.UDPAddr + var err error - s, err := net.ResolveUDPAddr("udp4", g.address) + if len(localAddress) != 0 { + localAddr, err = net.ResolveUDPAddr("udp4", localAddress) + if err != nil { + return err + } + } + + remoteAddr, err := net.ResolveUDPAddr("udp4", g.address) if err != nil { return err } - g.ip = s.IP - g.port = s.Port + g.mutex.Lock() + defer g.mutex.Unlock() + + g.ip = remoteAddr.IP + g.port = remoteAddr.Port g.numTeams = 0 g.numPlayers = 0 g.maxPlayers = 0 g.teams = nil g.players = nil - c, err := net.DialUDP("udp4", nil, s) + c, err := net.DialUDP("udp4", localAddr, remoteAddr) if err != nil { return err } @@ -214,7 +234,7 @@ func (g *GameServer) Query() error { } readBuffer := make([]byte, 2048) - err = c.SetDeadline(time.Now().Add(5 * time.Second)) + err = c.SetDeadline(time.Now().Add(timeout)) if err != nil { return err } @@ -225,8 +245,8 @@ func (g *GameServer) Query() error { g.ping = time.Since(g.queryTime) - if !addr.IP.Equal(s.IP) || addr.Port != s.Port { - return fmt.Errorf("t1net.GameServer.Query: Reply address mismatch: %s != %s", s.String(), addr.String()) + if !addr.IP.Equal(remoteAddr.IP) || addr.Port != remoteAddr.Port { + return fmt.Errorf("t1net.GameServer.Query: Reply address mismatch: %s != %s", remoteAddr.String(), addr.String()) } if n < 20 { diff --git a/game_test.go b/game_test.go index e731c93..ab467ef 100644 --- a/game_test.go +++ b/game_test.go @@ -123,7 +123,7 @@ func TestGameServer(t *testing.T) { } }() - err = game.Query() + err = game.Query(0, "") if err != nil { t.Fatal(err) } diff --git a/master.go b/master.go index c96d320..16c5f3a 100644 --- a/master.go +++ b/master.go @@ -40,6 +40,18 @@ type MasterServer struct { totalPackets int } +func (m *MasterServer) Ping() time.Duration { + m.mutex.RLock() + defer m.mutex.RUnlock() + return m.ping +} + +func (m *MasterServer) QueryTime() time.Time { + m.mutex.RLock() + defer m.mutex.RUnlock() + return m.queryTime +} + func (m *MasterServer) Name() string { m.mutex.RLock() defer m.mutex.RUnlock() @@ -64,21 +76,35 @@ func (m *MasterServer) Servers() []string { return m.servers } -func (m *MasterServer) Query() error { - m.mutex.Lock() - defer m.mutex.Unlock() +func (m *MasterServer) Query(timeout time.Duration, localAddress string) error { + if timeout == 0 { + timeout = 5 * time.Second + } + + var localAddr *net.UDPAddr + var err error + + if len(localAddress) != 0 { + localAddr, err = net.ResolveUDPAddr("udp4", localAddress) + if err != nil { + return err + } + } - s, err := net.ResolveUDPAddr("udp4", m.address) + remoteAddr, err := net.ResolveUDPAddr("udp4", m.address) if err != nil { return err } - m.ip = s.IP - m.port = s.Port + m.mutex.Lock() + defer m.mutex.Unlock() + + m.ip = remoteAddr.IP + m.port = remoteAddr.Port m.serverCount = 0 m.servers = nil - c, err := net.DialUDP("udp4", nil, s) + c, err := net.DialUDP("udp4", localAddr, remoteAddr) if err != nil { return err } @@ -105,7 +131,7 @@ func (m *MasterServer) Query() error { recvBuf := make([]byte, 1024) m.totalPackets = 1 for p := 0; p < m.totalPackets; p++ { - err := c.SetDeadline(time.Now().Add(5 * time.Second)) + err := c.SetDeadline(time.Now().Add(timeout)) if err != nil { return err } @@ -114,8 +140,8 @@ func (m *MasterServer) Query() error { return err } - if !addr.IP.Equal(s.IP) || addr.Port != s.Port { - return fmt.Errorf("t1net.MasterServer.Query: Reply address mismatch: %s != %s", s.String(), addr.String()) + if !addr.IP.Equal(remoteAddr.IP) || addr.Port != remoteAddr.Port { + return fmt.Errorf("t1net.MasterServer.Query: Reply address mismatch: %s != %s", remoteAddr.String(), addr.String()) } if !pingCalculated { diff --git a/master_test.go b/master_test.go index 7cbecc7..cb89bdc 100644 --- a/master_test.go +++ b/master_test.go @@ -151,7 +151,7 @@ func TestMasterServer(t *testing.T) { } }() - err = master.Query() + err = master.Query(0, "") if err != nil { t.Fatal(err) }