This repository has been archived by the owner on Apr 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
457 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dev.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,97 @@ | ||
# palworld-query-api | ||
|
||
query palworld with rcon! | ||
Streamlined web API for effortlessly managing and querying Palworld game servers using the RCON protocol. | ||
|
||
## Features | ||
|
||
- Supports querying multiple Palworld game servers. | ||
- Dynamic routing for retrieving server data by name. | ||
|
||
## Installation | ||
|
||
To install and run *palworld-query-api*, follow these steps: | ||
|
||
1. Clone the repository: `git clone https://github.com/xstar97/palworld-query-api.git` | ||
2. Navigate to the project directory: `cd palworld-query-api` | ||
3. Build the project: `go build cmd/main.go` | ||
4. Run the compiled binary: `./palworld-query-api` | ||
|
||
Make sure you have Go installed and properly configured on your system before proceeding. | ||
|
||
### Command-Line Installation | ||
|
||
To install and run *palworld-query-api* from the command line, follow these steps: | ||
|
||
1. Clone the repository: `git clone https://github.com/xstar97/palworld-query-api.git` | ||
2. Navigate to the project directory: `cd palworld-query-api` | ||
3. Build the project: `go build` | ||
4. Run the compiled binary: `./palworld-query-api` | ||
|
||
Make sure you have Go installed and properly configured on your system before proceeding. | ||
|
||
#### Command-Line Flags | ||
|
||
You can customize the behavior of *palworld-query-api* using the following command-line flags: | ||
|
||
| Flag | Description | Default Value | | ||
|--------------------|---------------------------------------|--------------------| | ||
| `-port` | Web port | `3000` | | ||
| `-cli-root` | Root path to rcon file | `/app/rcon/rcon` | | ||
| `-cli-config` | Root path to rcon.yaml | `/config/rcon.yaml`| | ||
| `-logs-path` | Logs path | `/logs` | | ||
|
||
Replace the default values as needed when running the binary. | ||
|
||
### Docker Installation | ||
|
||
Alternatively, you can use the Docker image hosted on GitHub. Use the following `docker-compose.yml` file: | ||
|
||
```yaml | ||
version: '3.8' | ||
|
||
services: | ||
palworld-query-api: | ||
image: ghcr.io/xstar97/palworld-query-api:latest | ||
environment: | ||
- PORT=3000 | ||
# default values; really dont need to be changed! | ||
# - CLI_ROOT=/app/rcon/rcon | ||
# - CLI_CONFIG=/config/rcon.yaml | ||
# - LOGS_PATH=/logs | ||
# generates the yaml from this json array (optional, but recommended) | ||
# - CONFIG_JSON='{"servers":[{"name":"default","address":"localhost:25575","password":"1234567890","type":"rcon","timeout":"10s"}]}' | ||
ports: | ||
- "3000:3000" | ||
volumes: | ||
- ./config:/config | ||
- ./logs:/logs | ||
``` | ||
an env variable `CONFIG_JSON` can be set to automatically create the rcon.yaml file needed for the rcon-cli tool. | ||
|
||
```json | ||
{ | ||
"servers": [ | ||
{ | ||
"name": "default", | ||
"address": "localhost:25575", | ||
"password": "1234567890", | ||
"type": "rcon", | ||
"timeout": "60s" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
### License | ||
|
||
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! Please see the [CONTRIBUTING.md](./CONTRIBUTING.md) file for more details. | ||
|
||
## Acknowledgements | ||
|
||
- [rcon-cli](https://github.com/gorcon/rcon-cli) - The underlying CLI tool for RCON communication. | ||
- [palworld](https://palworld.gg/) - The game server platform supported by this tool. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,22 @@ | ||
// main.go | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"palworld-query-api/internal/config" | ||
"palworld-query-api/internal/server" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"palworld-query-api/internal/config" | ||
"palworld-query-api/internal/routes" | ||
) | ||
|
||
func main() { | ||
cfg := config.ParseFlags() | ||
port := fmt.Sprintf(":%s", config.CONFIG.PORT) | ||
|
||
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { | ||
// Respond with 200 OK status | ||
w.WriteHeader(http.StatusOK) | ||
}) | ||
// Register healthz route | ||
http.HandleFunc(config.ROUTES.HEALTH, routes.HealthzHandler) | ||
|
||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||
log.Println("Received API request") | ||
serverData, err := server.GetServerData(cfg) | ||
if err != nil { | ||
log.Printf("Error getting server data: %v\n", err) | ||
http.Error(w, "Error getting server data", http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(serverData) | ||
log.Println("Sent server data to client") | ||
}) | ||
|
||
log.Printf("server listening on port %d\n", cfg.Port) | ||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", cfg.Port), nil)) | ||
// Register servers route | ||
http.HandleFunc(config.ROUTES.SERVERS, routes.IndexHandler) | ||
|
||
log.Printf("server listening on port %s\n", port) | ||
log.Fatal(http.ListenAndServe(port, nil)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= | ||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= | ||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= | ||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,111 @@ | ||
// internal/config/config.go | ||
package config | ||
|
||
import ( | ||
"flag" | ||
"log" | ||
"os" | ||
"palworld-query-api/internal/utils" | ||
"strconv" | ||
) | ||
|
||
type Config struct { | ||
RconCLIPath string | ||
RconCLIConfig string | ||
Port int | ||
LogsPath string // New field for logs directory | ||
type ConfigServer struct { | ||
Address string `json:"address"` | ||
Password string `json:"password"` | ||
Type string `json:"type"` | ||
Timeout string `json:"timeout"` | ||
} | ||
|
||
func ParseFlags() *Config { | ||
var config Config | ||
type JsonServerConfig struct { | ||
Name string `json:"name"` | ||
Address string `json:"address"` | ||
Password string `json:"password"` | ||
Type string `json:"type"` | ||
Timeout string `json:"timeout"` | ||
} | ||
|
||
// Check environment variables | ||
config.RconCLIPath = os.Getenv("RCON_CLI_PATH") | ||
config.RconCLIConfig = os.Getenv("RCON_CLI_CONFIG") | ||
config.LogsPath = os.Getenv("LOGS_PATH") // Read the LOGS_PATH environment variable | ||
portEnv := os.Getenv("PORT") | ||
if portEnv != "" { | ||
p, err := strconv.Atoi(portEnv) | ||
if err != nil { | ||
log.Fatalf("Invalid value for PORT environment variable: %v", err) | ||
} | ||
config.Port = p | ||
} | ||
type JsonConfigData struct { | ||
Servers []JsonServerConfig `json:"servers"` | ||
} | ||
|
||
// Parse flags if environment variables not set | ||
flag.StringVar(&config.RconCLIPath, "rcon-cli-path", "/app/rcon/rcon", "Path to the rcon-cli executable") | ||
flag.StringVar(&config.RconCLIConfig, "rcon-cli-config", "/config/rcon.yaml", "Path to the rcon-cli config file") | ||
flag.IntVar(&config.Port, "port", 3000, "server port") | ||
flag.StringVar(&config.LogsPath, "logs-path", "/logs", "Path to the directory for log files") // Add logs-path flag | ||
flag.Parse() | ||
// Constants for routes | ||
var ROUTES = struct { | ||
SERVERS string | ||
HEALTH string | ||
}{ | ||
SERVERS: "/servers/", | ||
HEALTH: "/healthz", | ||
} | ||
|
||
// Check if RconCLIPath exists | ||
if _, err := os.Stat(config.RconCLIPath); os.IsNotExist(err) { | ||
log.Fatalf("RconCLIPath '%s' does not exist", config.RconCLIPath) | ||
} | ||
// Configuration constants | ||
var CONFIG = struct { | ||
// Web port | ||
PORT string | ||
// Root path to rcon file | ||
CLI_ROOT string | ||
// Root path to rcon.yaml | ||
CLI_CONFIG string | ||
// Default rcon env | ||
CLI_DEFAULT_SERVER string | ||
// Default rcon env | ||
LOGS_PATH string | ||
}{} | ||
|
||
// Constants for commands | ||
var COMMANDS = struct { | ||
ENV string | ||
CONFIG string | ||
}{ | ||
ENV: "--env", | ||
CONFIG: "--config", | ||
} | ||
|
||
// Constants for commands | ||
var PALWORLD_RCON_COMMANDS = struct { | ||
INFO string | ||
SHOW_PLAYERS string | ||
}{ | ||
INFO: "info", | ||
SHOW_PLAYERS: "showplayers", | ||
} | ||
|
||
// Function to set configuration from environment variables | ||
func setConfigFromEnv() { | ||
setIfNotEmpty := func(key string, value *string) { | ||
if env := os.Getenv(key); env != "" { | ||
*value = env | ||
} | ||
} | ||
|
||
setIfNotEmpty("PORT", &CONFIG.PORT) | ||
setIfNotEmpty("CLI_ROOT", &CONFIG.CLI_ROOT) | ||
setIfNotEmpty("CLI_CONFIG", &CONFIG.CLI_CONFIG) | ||
setIfNotEmpty("CLI_DEFAULT_SERVER", &CONFIG.CLI_DEFAULT_SERVER) | ||
setIfNotEmpty("LOGS_PATH", &CONFIG.LOGS_PATH) | ||
} | ||
|
||
// Parse flags | ||
func init() { | ||
// Set configuration from environment variables | ||
setConfigFromEnv() | ||
|
||
flag.StringVar(&CONFIG.PORT, "port", "3000", "Server port") | ||
flag.StringVar(&CONFIG.CLI_ROOT, "cli-root", "/app/rcon/rcon", "Root path to rcon file") | ||
flag.StringVar(&CONFIG.CLI_CONFIG, "cli-config", "/config/rcon.yaml", "Root path to rcon.yaml") | ||
flag.StringVar(&CONFIG.CLI_DEFAULT_SERVER, "cli-def-server", "default", "Default rcon env") | ||
flag.StringVar(&CONFIG.LOGS_PATH, "logs-path", "/logs", "Logs path") | ||
flag.Parse() | ||
|
||
// Check if CONFIG_JSON is set | ||
configJSON := os.Getenv("CONFIG_JSON") | ||
if configJSON != "" { | ||
// Update the existing config file if it exists, otherwise create a new one | ||
err := utils.GenerateConfigFromJSON(configJSON, config.RconCLIConfig, config.LogsPath) | ||
err := GenerateConfigFromJSON(configJSON, CONFIG.CLI_CONFIG, CONFIG.LOGS_PATH) | ||
if err != nil { | ||
log.Fatalf("Error generating config from JSON: %v", err) | ||
} | ||
} | ||
|
||
return &config | ||
// Log the set flags | ||
log.Printf("Server port: %s", CONFIG.PORT) | ||
log.Printf("Root path to rcon file: %s", CONFIG.CLI_ROOT) | ||
log.Printf("Root path to rcon.yaml: %s", CONFIG.CLI_CONFIG) | ||
log.Printf("Default rcon env: %s", CONFIG.CLI_DEFAULT_SERVER) | ||
log.Printf("Logs path: %s", CONFIG.LOGS_PATH) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.