// GetUptime returns the uptime of the server in seconds. func (s *Server) GetUptime() (uptime int, err error) { var response *cubecode.Packet response, err = s.queryServer(buildRequest(InfoTypeExtended, ExtInfoTypeUptime, 0)) if err != nil { return } uptime, err = response.ReadInt() return }
// GetBasicInfoRaw queries a Sauerbraten server at addr on port and returns the raw response or an error in case something went wrong. Raw response means that the int values sent as game mode and master mode are NOT translated into the human readable name. func (s *Server) GetBasicInfoRaw() (basicInfoRaw BasicInfoRaw, err error) { var response *cubecode.Packet response, err = s.queryServer(buildRequest(InfoTypeBasic, 0, 0)) if err != nil { return } // first int is pong _, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading pong value: " + err.Error()) return } basicInfoRaw.NumberOfClients, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading number of connected clients: " + err.Error()) return } // next int is always 5 or 7, the number of additional attributes after the clientcount and before the strings for map and description sevenAttributes := false numberOfAttributes, err := response.ReadInt() if err != nil { err = errors.New("extinfo: error reading number of following values: " + err.Error()) return } if numberOfAttributes == 7 { sevenAttributes = true } basicInfoRaw.ProtocolVersion, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading protocol version: " + err.Error()) return } basicInfoRaw.GameMode, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading game mode: " + err.Error()) return } basicInfoRaw.SecsLeft, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading time left: " + err.Error()) return } basicInfoRaw.MaxNumberOfClients, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading maximum number of clients: " + err.Error()) return } basicInfoRaw.MasterMode, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading master mode: " + err.Error()) return } if sevenAttributes { var isPausedValue int isPausedValue, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading paused value: " + err.Error()) return } if isPausedValue == 1 { basicInfoRaw.Paused = true } basicInfoRaw.GameSpeed, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading game speed: " + err.Error()) return } } else { basicInfoRaw.GameSpeed = 100 } basicInfoRaw.Map, err = response.ReadString() if err != nil { err = errors.New("extinfo: error reading map name: " + err.Error()) return } basicInfoRaw.Description, err = response.ReadString() if err != nil { err = errors.New("extinfo: error reading server description: " + err.Error()) return } return }
// own function, because it is used in GetClientInfo() & GetAllClientInfo() func parseClientInfoResponse(response *cubecode.Packet) (clientInfoRaw ClientInfoRaw, err error) { // omit 7 first bytes: EXTENDED_INFO, EXTENDED_INFO_CLIENT_INFO, CN, EXTENDED_INFO_ACK, EXTENDED_INFO_VERSION, EXTENDED_INFO_NO_ERROR, EXTENDED_INFO_CLIENT_INFO_RESPONSE_INFO for i := 0; i < 7; i++ { _, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error skipping response header: " + err.Error()) return } } clientInfoRaw.ClientNum, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading client number: " + err.Error()) return } clientInfoRaw.Ping, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading ping: " + err.Error()) return } clientInfoRaw.Name, err = response.ReadString() if err != nil { err = errors.New("extinfo: error reading client name: " + err.Error()) return } clientInfoRaw.Team, err = response.ReadString() if err != nil { err = errors.New("extinfo: error reading team: " + err.Error()) return } clientInfoRaw.Frags, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading frags: " + err.Error()) return } clientInfoRaw.Flags, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading flags: " + err.Error()) return } clientInfoRaw.Deaths, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading deaths: " + err.Error()) return } clientInfoRaw.Teamkills, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading teamkills: " + err.Error()) return } clientInfoRaw.Accuracy, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading accuracy: " + err.Error()) return } clientInfoRaw.Health, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading health: " + err.Error()) return } clientInfoRaw.Armour, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading armour: " + err.Error()) return } clientInfoRaw.Weapon, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading weapon in use: " + err.Error()) return } clientInfoRaw.Privilege, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading client privilege: " + err.Error()) return } clientInfoRaw.State, err = response.ReadInt() if err != nil { err = errors.New("extinfo: error reading client state: " + err.Error()) return } // IP from next 4 bytes var ipByte1, ipByte2, ipByte3, ipByte4 byte ipByte1, err = response.ReadByte() if err != nil { err = errors.New("extinfo: error reading first IP byte: " + err.Error()) return } ipByte2, err = response.ReadByte() if err != nil { err = errors.New("extinfo: error reading second IP byte: " + err.Error()) return } ipByte3, err = response.ReadByte() if err != nil { err = errors.New("extinfo: error reading third IP byte: " + err.Error()) return } ipByte4 = 0 // sauer never sends 4th IP byte for privacy reasons clientInfoRaw.IP = net.IPv4(ipByte1, ipByte2, ipByte3, ipByte4) return }