Skip to content

Commit

Permalink
start reload config api endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
realDragonium committed Aug 7, 2021
1 parent 472f784 commit 16e4343
Show file tree
Hide file tree
Showing 11 changed files with 384 additions and 147 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ultraviolet - Alpha v0.11
# Ultraviolet - Alpha v0.11.1

## What is Ultraviolet?
[infrared](https://github.com/haveachin/infrared) but different.
Expand Down Expand Up @@ -39,9 +39,10 @@ Every server config needs to end with `.json`. Server config files will be searc

## How does some stuff work
### rate limiting
With rate limiting Ultraviolet will allow a specific number of connections to be made to the backend within a given time frame. It will reset when the time frame `rateCooldown` has passed. When the number has been exceeded but the cooldown isnt over yet, Ultraviolet will behave like the server is offline.
~~With rate limiting Ultraviolet will allow a specific number of connections to be made to the backend within a given time frame. It will reset when the time frame `rateCooldown` has passed. When the number has been exceeded but the cooldown isnt over yet, Ultraviolet will behave like the server is offline.
By default status request arent rate limited but you can turn this on. When its turned on and the connection rate exceeds the rate limit it can still send the status of the to the player when cache status is turned on.
Disabling rate limiting can be done by setting it to 0 and allows as many connections as it can to be created. (There is no difference in rate limiting disconnect and offline disconnect packets yet.)
Disabling rate limiting can be done by setting it to 0 and allows as many connections as it can to be created. (There is no difference in rate limiting disconnect and offline disconnect packets yet.)~~
It works differently now, based on playernames and ips instead of absolute connections. Status request will never be blocked, if you want to prevent spam from those turn on the status caching. (Later more detail explanation)

### state update Cooldown
To prevent a lot of calls being made to the backend without a reason Ultraviolet will keep track of the state from the backend. The state is currently being based on whether or not the backend will accept an tcp connection or not. When this happened and ultraviolet knows that the backend is `ONLINE` or `OFFLINE` it will wait the time `stateUpdateCooldown` is set to before it will check the state of the backend again.
Expand Down Expand Up @@ -87,6 +88,8 @@ jar -uf path/to/jarfile -C path/to/dir/in/jar path/to/file
|offlineStatus|[this](#status-config-value)|The status it will send the player when the server is offline.|
|rateLimit|0|The number of connections it will allow to be made to the backend in the given `rateCooldown` time. 0 will disable rate limiting.|
|rateCooldown|"1s"|rateCooldown is the time which it will take before the rateLimit will be reset.|
|banListCooldown|"5m"|The amount of time someone an ip will need to wait (when its banned) before it will get unbanned from joining a specific server.|
|reconnectMsg|"Please reconnect to verify yourself"|The message the player will be shown when its trying to join a server which is above its rate limit.|
|stateUpdateCooldown|"1s"|The time it will assume that the state of the server isnt changed (that server isnt offline now while it was online the last time we checked). |
|cacheStatus|false|Turn on or off whether it should cache the online cache of the server. If the server is recognized as `OFFLINE` it will send the offline status to the player.|
|validProtocol|0|validProtocol is the protocol integer the handshake will have when sending the handshake to the backend. Its only necessary to have this when `cacheStatus` is on.|
Expand Down
3 changes: 2 additions & 1 deletion config/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func ReadServerConfigs(path string) ([]ServerConfig, error) {
if filepath.Ext(path) != ".json" {
return nil
}
if info.Name() == "ultraviolet" {
if info.Name() == "ultraviolet.json" {
return nil
}
filePaths = append(filePaths, path)
Expand Down Expand Up @@ -169,6 +169,7 @@ func generateKeys(cfg ServerConfig) *ecdsa.PrivateKey {
func FileToWorkerConfig(cfg ServerConfig) (WorkerServerConfig, error) {
name := cfg.Name
if name == "" {
log.Println(cfg.FilePath)
name = cfg.Domains[0]
}
workerCfg := WorkerServerConfig{
Expand Down
23 changes: 11 additions & 12 deletions config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,18 @@ type ServerConfig struct {

func DefaultServerConfig() ServerConfig {
return ServerConfig{
ProxyBind: "",
DialTimeout: "1s",
OldRealIP: false,
NewRealIP: false,
SendProxyProtocol: false,
DisconnectMessage: "Server is offline",
CacheStatus: false,
RateLimit: 5,
RateDuration: "1s",
ProxyBind: "",
DialTimeout: "1s",
OldRealIP: false,
NewRealIP: false,
SendProxyProtocol: false,
DisconnectMessage: "Server is offline",
CacheStatus: false,
RateLimit: 5,
RateDuration: "1s",
RateBanListCooldown: "5m",
RateDisconMsg: "Please reconnect to verify yourself",
RateDisconMsg: "Please reconnect to verify yourself",
StateUpdateCooldown: "1s",

}
}

Expand Down Expand Up @@ -107,7 +106,7 @@ type WorkerServerConfig struct {
RateLimitStatus bool
RateLimitDuration time.Duration
RateBanListCooldown time.Duration
RateDisconPk mc.Packet
RateDisconPk mc.Packet
}

func DefaultWorkerConfig() WorkerConfig {
Expand Down
35 changes: 35 additions & 0 deletions config/verify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package config

import (
"fmt"
)

type DuplicateDomain struct {
Cfg1Path string
Cfg2Path string
Domain string
}

func (err *DuplicateDomain) Error() string {
return fmt.Sprintf("'%s' has been found in %s and %s", err.Domain, err.Cfg1Path, err.Cfg2Path)
}

func VerifyConfigs(cfgs []ServerConfig) []error {
errors := []error{}
domains := make(map[string]int)
for index, cfg := range cfgs {
for _, domain := range cfg.Domains {
otherIndex, ok := domains[domain]
if ok {
errors = append(errors, &DuplicateDomain{
Domain: domain,
Cfg1Path: cfg.FilePath,
Cfg2Path: cfgs[otherIndex].FilePath,
})
continue
}
domains[domain] = index
}
}
return errors
}
56 changes: 56 additions & 0 deletions config/verify_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package config_test

import (
"testing"

"github.com/realDragonium/Ultraviolet/config"
)

func TestVerifyConfigs(t *testing.T) {
t.Run("can detect duplicate domains", func(t *testing.T) {
domain := "uv"
cfgs := []config.ServerConfig{
{
FilePath: "uv1",
Domains: []string{domain},
},
{
FilePath: "uv2",
Domains: []string{domain},
},
}

errs := config.VerifyConfigs(cfgs)
if len(errs) != 1 {
t.Log(errs)
t.Fatalf("expected 1 errors but got %d", len(errs))
}
_, ok := errs[0].(*config.DuplicateDomain)
if !ok {
t.Errorf("expected DuplicateDomain but got %T", errs[0])
}
})

t.Run("can detect multiple duplicate domains", func(t *testing.T) {
domain := "uv"
cfgs := []config.ServerConfig{
{
FilePath: "uv1",
Domains: []string{domain},
},
{
FilePath: "uv2",
Domains: []string{domain},
},
{
FilePath: "uv3",
Domains: []string{domain},
},
}

errs := config.VerifyConfigs(cfgs)
if len(errs) != 2 {
t.Fatalf("expected 2 errors but got %d", len(errs))
}
})
}
Loading

0 comments on commit 16e4343

Please sign in to comment.