mirror of
				https://github.com/onyx-and-iris/q3rcon.git
				synced 2025-10-30 21:11:48 +00:00 
			
		
		
		
	move listen() into Rcon
rename channel variables
This commit is contained in:
		
							parent
							
								
									dd1d530d44
								
							
						
					
					
						commit
						8c1bc0f04c
					
				| @ -1,19 +1,15 @@ | ||||
| package conn | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/onyx-and-iris/q3rcon/internal/packet" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| type UDPConn struct { | ||||
| 	conn     *net.UDPConn | ||||
| 	response packet.Response | ||||
| 	conn *net.UDPConn | ||||
| } | ||||
| 
 | ||||
| func New(host string, port int) (UDPConn, error) { | ||||
| @ -28,8 +24,7 @@ func New(host string, port int) (UDPConn, error) { | ||||
| 	log.Infof("Outgoing address %s", conn.RemoteAddr()) | ||||
| 
 | ||||
| 	return UDPConn{ | ||||
| 		conn:     conn, | ||||
| 		response: packet.NewResponse(), | ||||
| 		conn: conn, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| @ -42,39 +37,13 @@ func (c UDPConn) Write(buf []byte) (int, error) { | ||||
| 	return n, nil | ||||
| } | ||||
| 
 | ||||
| func (c UDPConn) Listen(timeout time.Duration, resp chan<- string, errChan chan<- error) { | ||||
| 	c.conn.SetReadDeadline(time.Now().Add(timeout)) | ||||
| 	done := make(chan struct{}) | ||||
| 	var sb strings.Builder | ||||
| 	buf := make([]byte, 2048) | ||||
| 
 | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-done: | ||||
| 			resp <- sb.String() | ||||
| 			return | ||||
| 		default: | ||||
| 			rlen, _, err := c.conn.ReadFromUDP(buf) | ||||
| 			if err != nil { | ||||
| 				e, ok := err.(net.Error) | ||||
| 				if ok { | ||||
| 					if e.Timeout() { | ||||
| 						close(done) | ||||
| 					} else { | ||||
| 						errChan <- e | ||||
| 						return | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if rlen < len(c.response.Header()) { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			if bytes.HasPrefix(buf, c.response.Header()) { | ||||
| 				sb.Write(buf[len(c.response.Header()):rlen]) | ||||
| 			} | ||||
| 		} | ||||
| func (c UDPConn) ReadUntil(timeout time.Time, buf []byte) (int, error) { | ||||
| 	c.conn.SetReadDeadline(timeout) | ||||
| 	rlen, _, err := c.conn.ReadFromUDP(buf) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return rlen, nil | ||||
| } | ||||
| 
 | ||||
| func (c UDPConn) Close() error { | ||||
|  | ||||
							
								
								
									
										77
									
								
								q3rcon.go
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								q3rcon.go
									
									
									
									
									
								
							| @ -1,7 +1,9 @@ | ||||
| package q3rcon | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| @ -9,29 +11,7 @@ import ( | ||||
| 	"github.com/onyx-and-iris/q3rcon/internal/packet" | ||||
| ) | ||||
| 
 | ||||
| // Option is a functional option type that allows us to configure the VbanTxt. | ||||
| type Option func(*Rcon) | ||||
| 
 | ||||
| // WithLoginTimeout is a functional option to set the login timeout | ||||
| func WithLoginTimeout(timeout time.Duration) Option { | ||||
| 	return func(rcon *Rcon) { | ||||
| 		rcon.loginTimeout = timeout | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WithDefaultTimeout is a functional option to set the default response timeout | ||||
| func WithDefaultTimeout(timeout time.Duration) Option { | ||||
| 	return func(rcon *Rcon) { | ||||
| 		rcon.defaultTimeout = timeout | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WithTimeouts is a functional option to set the timeouts for responses per command | ||||
| func WithTimeouts(timeouts map[string]time.Duration) Option { | ||||
| 	return func(rcon *Rcon) { | ||||
| 		rcon.timeouts = timeouts | ||||
| 	} | ||||
| } | ||||
| const respBufSiz = 2048 | ||||
| 
 | ||||
| type Rcon struct { | ||||
| 	conn     conn.UDPConn | ||||
| @ -41,8 +21,6 @@ type Rcon struct { | ||||
| 	loginTimeout   time.Duration | ||||
| 	defaultTimeout time.Duration | ||||
| 	timeouts       map[string]time.Duration | ||||
| 
 | ||||
| 	resp chan string | ||||
| } | ||||
| 
 | ||||
| func New(host string, port int, password string, options ...Option) (*Rcon, error) { | ||||
| @ -56,9 +34,10 @@ func New(host string, port int, password string, options ...Option) (*Rcon, erro | ||||
| 	} | ||||
| 
 | ||||
| 	r := &Rcon{ | ||||
| 		conn:           conn, | ||||
| 		request:        packet.NewRequest(password), | ||||
| 		resp:           make(chan string), | ||||
| 		conn:     conn, | ||||
| 		request:  packet.NewRequest(password), | ||||
| 		response: packet.NewResponse(), | ||||
| 
 | ||||
| 		loginTimeout:   5 * time.Second, | ||||
| 		defaultTimeout: 20 * time.Millisecond, | ||||
| 		timeouts:       make(map[string]time.Duration), | ||||
| @ -105,21 +84,55 @@ func (r Rcon) Send(cmd string) (string, error) { | ||||
| 		timeout = r.defaultTimeout | ||||
| 	} | ||||
| 
 | ||||
| 	e := make(chan error) | ||||
| 	go r.conn.Listen(timeout, r.resp, e) | ||||
| 	respChan := make(chan string) | ||||
| 	errChan := make(chan error) | ||||
| 	go r.listen(timeout, respChan, errChan) | ||||
| 	_, err := r.conn.Write(r.request.Encode(cmd)) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	select { | ||||
| 	case err := <-e: | ||||
| 	case err := <-errChan: | ||||
| 		return "", err | ||||
| 	case resp := <-r.resp: | ||||
| 	case resp := <-respChan: | ||||
| 		return strings.TrimPrefix(resp, string(r.response.Header())), nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (r Rcon) listen(timeout time.Duration, respChan chan<- string, errChan chan<- error) { | ||||
| 	done := make(chan struct{}) | ||||
| 	respBuf := make([]byte, respBufSiz) | ||||
| 	var sb strings.Builder | ||||
| 
 | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-done: | ||||
| 			respChan <- sb.String() | ||||
| 			return | ||||
| 		default: | ||||
| 			rlen, err := r.conn.ReadUntil(time.Now().Add(timeout), respBuf) | ||||
| 			if err != nil { | ||||
| 				e, ok := err.(net.Error) | ||||
| 				if ok { | ||||
| 					if e.Timeout() { | ||||
| 						close(done) | ||||
| 					} else { | ||||
| 						errChan <- e | ||||
| 						return | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if rlen > len(r.response.Header()) { | ||||
| 				if bytes.HasPrefix(respBuf, r.response.Header()) { | ||||
| 					sb.Write(respBuf[len(r.response.Header()):rlen]) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (r Rcon) Close() { | ||||
| 	r.conn.Close() | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user