Blog/utils/MdtInfo.go

144 lines
2.8 KiB
Go
Raw Normal View History

2024-05-22 08:30:01 +00:00
package utils
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"strconv"
"strings"
"time"
)
type GamemodeId int
const (
survival GamemodeId = iota
sandbox
attack
pvp
editor
)
type Gamemode struct {
Name string `json:"name"`
Id GamemodeId `json:"id"`
}
type ServerInfo struct {
Host string `json:"host"`
Port int `json:"port"`
Status string `json:"status"`
Name string `json:"name"`
Maps string `json:"maps"`
Players int `json:"players"`
Version int `json:"version"`
Wave int `json:"wave"`
Vertype string `json:"vertype"`
Gamemode Gamemode `json:"gamemode"`
Description string `json:"description"`
Modename string `json:"modename"`
Limit int `json:"limit"`
Ping int `json:"ping"`
}
type InfoBuffer struct {
*bytes.Reader
}
func (g GamemodeId) Name() string {
switch g {
case survival:
return "生存"
case sandbox:
return "沙盒"
case attack:
return "进攻"
case pvp:
return "PVP"
case editor:
return "编辑"
default:
return "Error"
}
}
func (r *InfoBuffer) New(b []byte) {
r.Reader = bytes.NewReader(b)
}
func (r *InfoBuffer) readString() string {
l, _ := r.ReadByte()
buf := make([]byte, l)
r.Read(buf)
return string(buf)
}
func (r *InfoBuffer) getInt() int {
var t int32
binary.Read(r, binary.BigEndian, &t)
return int(t)
}
func (r *InfoBuffer) get() byte {
b, _ := r.ReadByte()
return b
}
2024-06-03 08:15:23 +00:00
func connectServer(host string) (buf InfoBuffer, ping int64, err error) {
2024-05-22 08:30:01 +00:00
socket, err := net.Dial("udp", host)
if err != nil {
2024-06-03 08:15:23 +00:00
return InfoBuffer{}, -1, err
2024-05-22 08:30:01 +00:00
}
defer socket.Close()
2024-06-03 08:15:23 +00:00
startTime := time.Now()
_, err = socket.Write([]byte{0xFE, 0x01})
2024-05-22 08:30:01 +00:00
if err != nil {
2024-06-03 08:15:23 +00:00
return InfoBuffer{}, -1, err
2024-05-22 08:30:01 +00:00
}
2024-06-03 08:15:23 +00:00
data := make([]byte, 500)
socket.SetReadDeadline(time.Now().Add(2 * time.Second))
_, err = socket.Read(data)
2024-05-22 08:30:01 +00:00
if err != nil {
2024-06-03 08:15:23 +00:00
return InfoBuffer{}, -1, err
2024-05-22 08:30:01 +00:00
}
2024-06-03 08:15:23 +00:00
ping = time.Since(startTime).Milliseconds()
buf.New(data)
return buf, ping, nil
2024-05-22 08:30:01 +00:00
}
func GetServerInfo(host string) (ServerInfo, error) {
var info ServerInfo
ip := strings.Split(host, ":")
if len(ip) == 1 {
info.Host = host
info.Port = 6567
} else {
info.Host = ip[0]
port, err := strconv.Atoi(ip[1])
if err != nil {
return info, err
}
info.Port = port
}
add := fmt.Sprintf("%s:%d", info.Host, info.Port)
2024-06-03 08:15:23 +00:00
buf, ping, err := connectServer(add)
2024-05-22 08:30:01 +00:00
if err != nil {
info.Status = "Offline"
return info, err
}
2024-06-03 08:15:23 +00:00
info.Ping = int(ping)
2024-05-22 08:30:01 +00:00
info.Status = "Online"
info.Name = buf.readString()
info.Maps = buf.readString()
info.Players = buf.getInt()
info.Wave = buf.getInt()
info.Version = buf.getInt()
info.Vertype = buf.readString()
info.Gamemode.Id = GamemodeId(buf.get())
info.Gamemode.Name = info.Gamemode.Id.Name()
info.Limit = buf.getInt()
info.Description = buf.readString()
info.Modename = buf.readString()
return info, nil
}