From 4d02a6bedd8d700ef2aa87c14e4e392094794115 Mon Sep 17 00:00:00 2001 From: tursom Date: Thu, 3 Oct 2024 19:14:32 +0800 Subject: [PATCH] init commit --- .gitignore | 2 + cmd/gateway/main.go | 140 ++++++++++++++++++++++++++++++++++++++++++++ config.example.json | 8 +++ go.mod | 3 + 4 files changed, 153 insertions(+) create mode 100644 .gitignore create mode 100644 cmd/gateway/main.go create mode 100644 config.example.json create mode 100644 go.mod diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c622d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +config.json +/gateway diff --git a/cmd/gateway/main.go b/cmd/gateway/main.go new file mode 100644 index 0000000..1bc71d8 --- /dev/null +++ b/cmd/gateway/main.go @@ -0,0 +1,140 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "net" + "os" + "sync" +) + +type Config struct { + Port int `json:"port"` + Hosts map[string]string `json:"hosts"` + Default string `json:"default"` +} + +var config Config + +func loadConfig() error { + file, err := os.Open("config.json") + if err != nil { + return err + } + defer file.Close() + + byteValue, err := io.ReadAll(file) + if err != nil { + return err + } + + return json.Unmarshal(byteValue, &config) +} + +func main() { + if err := loadConfig(); err != nil { + panic(err) + } + + // 监听TCP端口 + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", config.Port)) + if err != nil { + panic(err) + } + defer listener.Close() + fmt.Println("Listening on :25565") + + for { + // 接受传入的连接 + conn, err := listener.Accept() + if err != nil { + fmt.Println("Error accepting:", err.Error()) + continue + } + // 处理连接 + go handleRequest(conn) + } +} + +func handleRequest(conn net.Conn) { + // 确保连接关闭 + defer conn.Close() + + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil { + fmt.Println("Error reading:", err.Error()) + return + } + mc_host := GetMcHost(buf[:n]) + host, ok := config.Hosts[mc_host] + if !ok { + host = config.Default + } + + client, err := net.Dial("tcp", host) + if err != nil { + fmt.Println("Error dialing:", err.Error()) + return + } + defer client.Close() + + client.Write(buf[:n]) + + var wg sync.WaitGroup + wg.Add(2) + + go handleRead(client, conn, &wg) + go handleWrite(client, conn, &wg) + + wg.Wait() +} + +func handleRead(srv, cli net.Conn, wg *sync.WaitGroup) { + defer func() { + wg.Done() + srv.Close() + cli.Close() + }() + + buf := make([]byte, 1024) + + for { + n, err := srv.Read(buf) + if err != nil { + return + } + + cli.Write(buf[:n]) + } +} + +func handleWrite(srv, cli net.Conn, wg *sync.WaitGroup) { + defer func() { + wg.Done() + srv.Close() + cli.Close() + }() + + buf := make([]byte, 1024) + + for { + n, err := cli.Read(buf) + if err != nil { + return + } + + srv.Write(buf[:n]) + } +} + +func GetMcHost(buf []byte) string { + buf = buf[4:] + host_len := buf[0] + if len(buf)+1 < int(host_len) { + return "" + } + + return string(buf[1 : host_len+1]) +} diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..c6b818a --- /dev/null +++ b/config.example.json @@ -0,0 +1,8 @@ +{ + "port": 25565, + "default": "mc1:25565", + "hosts": { + "dev": "mc1:25565", + "dev.lan": "mc1:25568" + } +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..43eeab2 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/tursom/mc-gateway + +go 1.23.1