Skip to content

Commit 8f2a581

Browse files
committed
feat: add feature auto download mmdb database; editing readme
1 parent 991c56c commit 8f2a581

2 files changed

Lines changed: 110 additions & 6 deletions

File tree

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ GOWebServer is a web server for Growtopia Private Server. It is written in Go an
1717

1818
## Build
1919

20+
### Using Pre-built Binary
21+
22+
Download the pre-built binary for your operating system from the [releases page](https://github.com/yoruakio/GOWebServer/releases):
23+
24+
- **Windows**: Download `GOWebServer-windows-amd64.zip`
25+
- **Linux**: Download `GOWebServer-linux-amd64.zip`
26+
- **macOS**: Download `GOWebServer-darwin-amd64.zip`
27+
28+
Extract the archive and run the executable.
29+
30+
### Building from Source
31+
2032
The following are required to build and run GOWebServer:
2133

2234
- [Golang](https://golang.org/dl/) (1.16+) - The Go Programming Language
@@ -27,8 +39,8 @@ Building the server is simple, just run the following command:
2739
1. Clone the repository:
2840

2941
```bash
30-
# Clone the repository and its submodules for the requirements of geo location detection
31-
git clone https://github.com/yoruakio/GOWebServer.git --recursive
42+
git clone https://github.com/yoruakio/GOWebServer.git
43+
cd GOWebServer
3244
```
3345

3446
2. Build the server:

http/http.go

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package http
33
import (
44
"encoding/json"
55
"fmt"
6+
"io"
67
"log"
78
"net"
89
"net/http"
@@ -67,6 +68,80 @@ var (
6768
}
6869
)
6970

71+
const geoLite2URL = "https://codeberg.org/Vo/GOWebServer-Depedencies/raw/branch/main/GeoLite2-City.mmdb"
72+
73+
// @note progress writer for tracking download progress
74+
type progressWriter struct {
75+
total int64
76+
downloaded int64
77+
startTime time.Time
78+
lastUpdate time.Time
79+
}
80+
81+
func (pw *progressWriter) Write(p []byte) (int, error) {
82+
n := len(p)
83+
pw.downloaded += int64(n)
84+
85+
now := time.Now()
86+
if now.Sub(pw.lastUpdate) >= 500*time.Millisecond || pw.downloaded == pw.total {
87+
elapsed := now.Sub(pw.startTime).Seconds()
88+
speed := float64(pw.downloaded) / elapsed / 1024 / 1024
89+
progress := float64(pw.downloaded) / float64(pw.total) * 100
90+
91+
downloadedMB := float64(pw.downloaded) / 1024 / 1024
92+
totalMB := float64(pw.total) / 1024 / 1024
93+
94+
logger.Infof("Downloading: %.2f/%.2f MB (%.1f%%) - %.2f MB/s",
95+
downloadedMB, totalMB, progress, speed)
96+
97+
pw.lastUpdate = now
98+
}
99+
100+
return n, nil
101+
}
102+
103+
// @note download GeoLite2 database from remote repository
104+
func downloadGeoLite2DB(filepath string) error {
105+
dir := "mmdb/GOWebServer-Depedencies"
106+
if err := os.MkdirAll(dir, 0755); err != nil {
107+
return fmt.Errorf("failed to create directory: %w", err)
108+
}
109+
110+
client := &http.Client{
111+
Timeout: 120 * time.Second,
112+
}
113+
114+
resp, err := client.Get(geoLite2URL)
115+
if err != nil {
116+
return fmt.Errorf("failed to download: %w", err)
117+
}
118+
defer resp.Body.Close()
119+
120+
if resp.StatusCode != http.StatusOK {
121+
return fmt.Errorf("download failed with status: %d", resp.StatusCode)
122+
}
123+
124+
out, err := os.Create(filepath)
125+
if err != nil {
126+
return fmt.Errorf("failed to create file: %w", err)
127+
}
128+
defer out.Close()
129+
130+
pw := &progressWriter{
131+
total: resp.ContentLength,
132+
startTime: time.Now(),
133+
lastUpdate: time.Now(),
134+
}
135+
136+
writer := io.MultiWriter(out, pw)
137+
138+
if _, err := io.Copy(writer, resp.Body); err != nil {
139+
return fmt.Errorf("failed to write file: %w", err)
140+
}
141+
142+
return nil
143+
}
144+
70145
type IPAPIResponse struct {
71146
Query string `json:"query"`
72147
Status string `json:"status"`
@@ -291,10 +366,27 @@ func Initialize() *fiber.App {
291366
var err error
292367

293368
if config.EnableGeo {
294-
if db, err = geoip2.Open("mmdb/GOWebServer-Depedencies/GeoLite2-City.mmdb"); err != nil {
295-
logger.Error("Failed to open GeoLite2-City.mmdb: ", err)
296-
logger.Error("Did you use --recursive when cloning? See README.md")
297-
config.EnableGeo = false
369+
mmdbPath := "mmdb/GOWebServer-Depedencies/GeoLite2-City.mmdb"
370+
371+
if _, err := os.Stat(mmdbPath); os.IsNotExist(err) {
372+
logger.Info("GeoLite2-City.mmdb not found, attempting to download...")
373+
if err := downloadGeoLite2DB(mmdbPath); err != nil {
374+
logger.Error("Failed to download GeoLite2-City.mmdb: ", err)
375+
logger.Info("Geo Location will be disabled")
376+
config.EnableGeo = false
377+
} else {
378+
logger.Info("GeoLite2-City.mmdb downloaded successfully")
379+
}
380+
}
381+
382+
if config.EnableGeo {
383+
if db, err = geoip2.Open(mmdbPath); err != nil {
384+
logger.Error("Failed to open GeoLite2-City.mmdb: ", err)
385+
logger.Info("Deleting corrupted database file...")
386+
os.Remove(mmdbPath)
387+
logger.Info("Geo Location will be disabled")
388+
config.EnableGeo = false
389+
}
298390
}
299391
}
300392

0 commit comments

Comments
 (0)