Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
shutterbug2000 committed Jun 25, 2024
0 parents commit 8bd9c2c
Show file tree
Hide file tree
Showing 24 changed files with 1,601 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# custom
.env
*.key
go.work
go.work.sum

# built server
build

# logs
log
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# TODO - Assumes a UNIX-like OS

RED := $(shell tput setaf 1)
BLUE := $(shell tput setaf 4)
CYAN := $(shell tput setaf 14)
ORANGE := $(shell tput setaf 202)
YELLOW := $(shell tput setaf 214)
RESET := $(shell tput sgr0)

ifeq ($(shell which go),)
# TODO - Read contents from .git folder instead?
$(error "$(RED)go command not found. Install go to continue $(BLUE)https://go.dev/doc/install$(RESET)")
endif

ifneq ($(wildcard .git),)
# * .git folder exists, build server build string from repo info
ifeq ($(shell which git),)
# TODO - Read contents from .git folder instead?
$(error "$(RED)git command not found. Install git to continue $(ORANGE)https://git-scm.com/downloads$(RESET)")
endif
$(info "$(CYAN)Building server build string from repository info$(RESET)")
# * Build server build string from repo info
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
REMOTE_ORIGIN := $(shell git config --get remote.origin.url)

# * Handle multiple origin URL formats
HTTPS_PREFIX_CHECK := $(shell echo $(REMOTE_ORIGIN) | head -c 8)
HTTP_PREFIX_CHECK := $(shell echo $(REMOTE_ORIGIN) | head -c 7)
GIT@_PREFIX_CHECK := $(shell echo $(REMOTE_ORIGIN) | head -c 4)

ifeq ($(HTTPS_PREFIX_CHECK), https://)
REMOTE_PATH := $(shell echo $(REMOTE_ORIGIN) | cut -d/ -f4-)
else ifeq ($(HTTP_PREFIX_CHECK), http://)
REMOTE_PATH := $(shell echo $(REMOTE_ORIGIN) | cut -d/ -f4-)
else ifeq ($(GIT@_PREFIX_CHECK), git@)
REMOTE_PATH := $(shell echo $(REMOTE_ORIGIN) | cut -d: -f2-)
else
REMOTE_PATH := $(shell echo $(REMOTE_ORIGIN) | cut -d/ -f2-)
endif

HASH := $(shell git rev-parse --short HEAD)
SERVER_BUILD := $(BRANCH):$(REMOTE_PATH)@$(HASH)

else
# * .git folder not present, assume downloaded from zip file and just use folder name
$(info "$(CYAN)git repository not found. Building server build string from folder name$(RESET)")
SERVER_BUILD := dr-luigi
endif

# * Final build string
DATE_TIME := $(shell date --iso=seconds)
BUILD_STRING := $(SERVER_BUILD), $(DATE_TIME)

default:
ifeq ($(wildcard .env),)
$(warning "$(YELLOW).env file not found, environment variables may not be populated correctly$(RESET)")
endif
go get -u
go mod tidy
go build -ldflags "-X 'main.serverBuildString=$(BUILD_STRING)'" -o ./build/dr-luigi
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Dr. Luigi replacement server
Includes both the authentication and secure servers

## Compiling

### Setup
Install [Go](https://go.dev/doc/install) and [git](https://git-scm.com/downloads), then clone and enter the repository

```bash
$ git clone https://github.com/PretendoNetwork/dr-luigi
$ cd dr-luigi
```

### Compiling using `go`
To compile using Go, `go get` the required modules and then `go build` to your desired location. You may also want to tidy the go modules, though this is optional

```bash
$ go get -u
$ go mod tidy
$ go build -o build/dr-luigi
```

The server is now built to `build/dr-luigi`

When compiling with only Go, the authentication servers build string is not automatically set. This should not cause any issues with gameplay, but it means that the server build will not be visible in any packet dumps or logs a title may produce

To compile the servers with the authentication server build string, add `-ldflags "-X 'main.serverBuildString=BUILD_STRING_HERE'"` to the build command, or use `make` to compile the server

### Compiling using `make`
Compiling using `make` will read the local `.git` directory to create a dynamic authentication server build string, based on your repositories remote origin and current commit

Install `make` either through your systems package manager or the [official download](https://www.gnu.org/software/make/). We provide a `default` rule which compiles [using `go`](#compiling-using-go)

To build using `go`

```bash
$ make
```

The server is now built to `build/dr-luigi`

## Configuration
All configuration options are handled via environment variables

`.env` files are supported

| Name | Description | Required |
|-------------------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
| `PN_POSTGRES_URI` | Fully qualified URI to your Postgres server (Example `postgres://username:password@localhost/mk7?sslmode=disable`) | Yes |
| `PN_KERBEROS_PASSWORD` | Password used as part of the internal server data in Kerberos tickets | No (Default password `password` will be used) |
| `PN_AUTHENTICATION_SERVER_PORT` | Port for the authentication server | Yes |
| `PN_SECURE_SERVER_HOST` | Host name for the secure server (should point to the same address as the authentication server) | Yes |
| `PN_SECURE_SERVER_PORT` | Port for the secure server | Yes |
| `PN_ACCOUNT_GRPC_HOST` | Host name for your account server gRPC service | Yes |
| `PN_ACCOUNT_GRPC_PORT` | Port for your account server gRPC service | Yes |
| `PN_ACCOUNT_GRPC_API_KEY` | API key for your account server gRPC service | No (Assumed to be an open gRPC API) |
| `PN_ACCESS_KEY` | NEX Access Key | Yes |
| `PN_NEX_VERSION_MAJOR` | NEX Library Major version | Yes |
| `PN_NEX_VERSION_MINOR` | NEX Library Minor version | Yes |
| `PN_NEX_VERSION_PATCH` | NEX Library Patch version | Yes |
25 changes: 25 additions & 0 deletions database/connect_postgres.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package database

import (
"database/sql"
"os"

_ "github.com/lib/pq"

"github.com/PretendoNetwork/dr-luigi/globals"
)

var Postgres *sql.DB

func ConnectPostgres() {
var err error

Postgres, err = sql.Open("postgres", os.Getenv("PN_POSTGRES_URI"))
if err != nil {
globals.Logger.Critical(err.Error())
}

globals.Logger.Success("Connected to Postgres!")

initPostgres()
}
79 changes: 79 additions & 0 deletions database/get_rankings_by_category_and_ranking_order_param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package database

import (
"database/sql"

ranking_types "github.com/PretendoNetwork/nex-protocols-go/v2/ranking/types"
"github.com/PretendoNetwork/dr-luigi/globals"

"github.com/PretendoNetwork/nex-go/v2/types"
)

func GetRankingsAndCountByCategoryAndRankingOrderParam(category *types.PrimitiveU32, rankingOrderParam *ranking_types.RankingOrderParam) (*types.List[*ranking_types.RankingRankData], uint32, error) {
rankings := types.NewList[*ranking_types.RankingRankData]()

rows, err := Postgres.Query(`
SELECT
owner_pid,
score,
groups,
param
FROM rankings WHERE category=$1 ORDER BY score DESC LIMIT $2 OFFSET $3`,
category.Value,
rankingOrderParam.Length.Value,
rankingOrderParam.Offset.Value,
)
if err != nil {
return rankings, 0, err
}

row := 1
for rows.Next() {
rankingRankData := ranking_types.NewRankingRankData()
rankingRankData.UniqueID = types.NewPrimitiveU64(0)
rankingRankData.Order = types.NewPrimitiveU32(uint32(row))
rankingRankData.Category = category

var pid uint64
err := rows.Scan(
&pid,
&rankingRankData.Score.Value,
&rankingRankData.Groups.Value,
&rankingRankData.Param.Value,
)

if err != nil && err != sql.ErrNoRows {
globals.Logger.Critical(err.Error())
}

commonDataRows, err := Postgres.Query(`
SELECT
common_data
FROM common_datas WHERE owner_pid=$1 AND unique_id=$2`,
pid,
rankingRankData.UniqueID.Value,
)
if err != nil {
globals.Logger.Critical(err.Error())
return rankings, 0, err
}
commonDataRows.Next()
err = commonDataRows.Scan(
&rankingRankData.CommonData.Value,
)

if err != nil && err != sql.ErrNoRows {
globals.Logger.Critical(err.Error())
}

rankingRankData.PrincipalID = types.NewPID(pid)

if err == nil {
rankings.Append(rankingRankData)

row += 1
}
}

return rankings, uint32(rankings.Length()), nil
}
12 changes: 12 additions & 0 deletions database/get_total_rankings_by_category.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package database

func GetTotalRankingsByCategory(category uint32) (error, uint32) {
var total uint32

err := Postgres.QueryRow(`SELECT COUNT(*) FROM rankings WHERE category=$1`, category).Scan(&total)
if err != nil {
return err, 0
}

return nil, total
}
38 changes: 38 additions & 0 deletions database/init_postgres.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package database

import "github.com/PretendoNetwork/dr-luigi/globals"

func initPostgres() {
var err error

_, err = Postgres.Exec(`CREATE TABLE IF NOT EXISTS rankings (
owner_pid integer,
unique_id bigint,
category integer,
score integer,
order_by integer,
update_mode integer,
groups bytea,
param bigint,
created_at bigint,
PRIMARY KEY (unique_id, owner_pid, category)
)`)
if err != nil {
globals.Logger.Critical(err.Error())
return
}

_, err = Postgres.Exec(`CREATE TABLE IF NOT EXISTS common_datas (
unique_id bigserial,
owner_pid integer,
common_data bytea,
created_at bigint,
PRIMARY KEY (unique_id, owner_pid)
)`)
if err != nil {
globals.Logger.Critical(err.Error())
return
}

globals.Logger.Success("Postgres tables created")
}
44 changes: 44 additions & 0 deletions database/insert_ranking_by_pid_and_ranking_score_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package database

import (
"time"

ranking_types "github.com/PretendoNetwork/nex-protocols-go/v2/ranking/types"

"github.com/PretendoNetwork/nex-go/v2/types"
)

func InsertRankingByPIDAndRankingScoreData(pid *types.PID, rankingScoreData *ranking_types.RankingScoreData, uniqueID *types.PrimitiveU64) error {
now := time.Now().UnixNano()
if(rankingScoreData.Score.Value == 0){
return nil
}

_, err := Postgres.Exec(`
INSERT INTO rankings (
owner_pid,
category,
score,
order_by,
update_mode,
groups,
param,
unique_id,
created_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (owner_pid, unique_id, category) DO UPDATE
SET score = excluded.score;`,
pid.Value(),
rankingScoreData.Category.Value,
rankingScoreData.Score.Value,
rankingScoreData.OrderBy.Value,
rankingScoreData.UpdateMode.Value,
rankingScoreData.Groups.Value,
rankingScoreData.Param.Value & 0x7FFFFFFFFFFFFFFF,
uniqueID.Value,
now,
)

return err
}
29 changes: 29 additions & 0 deletions database/upload_common_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package database

import (
"time"

"github.com/PretendoNetwork/nex-go/v2/types"
)

func UploadCommonData(pid *types.PID, uniqueID *types.PrimitiveU64, commonData *types.Buffer) error {
now := time.Now().UnixNano()

_, err := Postgres.Exec(`
INSERT INTO common_datas (
owner_pid,
unique_id,
common_data,
created_at
)
VALUES ($1, $2, $3, $4)
ON CONFLICT (owner_pid, unique_id) DO UPDATE
SET common_data = excluded.common_data;`,
pid.Value(),
uniqueID.Value,
commonData.Value,
now,
)

return err
}
Loading

0 comments on commit 8bd9c2c

Please sign in to comment.