Compare commits

...

7 Commits

22 changed files with 123 additions and 34 deletions

View File

@ -5,9 +5,11 @@ on:
paths:
- cmd/**
- config/**
- cnet/**
- internal/**
- login/**
- shard/**
- util/**
- go.mod
- go.sum
- .github/workflows/tests.yaml

View File

@ -1,6 +1,6 @@
# gopenfusion
A toy implementation of the [Fusionfall Packet Protocol](https://openpunk.com/pages/fusionfall-openfusion/) and accompanying services, written in Go.
A toy implementation of the [Fusionfall Packet Protocol](https://openpunk.com/pages/fusionfall-openfusion/) (see: `cnet/`) and accompanying services, written in Go.
## Landwalker demo

View File

@ -5,7 +5,7 @@ import (
"flag"
"log"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/login"
"github.com/google/subcommands"
)

View File

@ -6,7 +6,7 @@ import (
"log"
"os"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/internal/db"
"github.com/CPunch/gopenfusion/internal/redis"

View File

@ -5,7 +5,7 @@ import (
"flag"
"log"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/shard"
"github.com/google/subcommands"
)

View File

@ -6,7 +6,7 @@ import (
)
const (
DEFAULT_KEY = "m@rQn~W#"
DEFAULT_KEY = "m@rQn~W#" // if you change this, make sure to update the test data in protocol_test.go
KEY_LENGTH = 8
)
@ -50,13 +50,14 @@ func DecryptData(buff, key []byte) {
}
func CreateNewKey(uTime, iv1, iv2 uint64) []byte {
dEKey := binary.LittleEndian.Uint64([]byte(DEFAULT_KEY))
num := iv1 + 1
num2 := iv2 + 1
dEKey := uint64(binary.LittleEndian.Uint64([]byte(DEFAULT_KEY)))
key := dEKey * (uTime * num * num2)
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, uint64(key))
binary.LittleEndian.PutUint64(buf, key)
return buf
}

View File

@ -42,10 +42,7 @@ func (pkt Packet) encodeStructField(field reflect.StructField, value reflect.Val
buf16 = buf16[:sz]
} else {
// grow
// TODO: probably a better way to do this?
for len(buf16) < sz {
buf16 = append(buf16, 0)
}
buf16 = append(buf16, make([]uint16, sz-len(buf16))...)
}
// write
@ -125,8 +122,7 @@ func (pkt Packet) decodeStructField(field reflect.StructField, value reflect.Val
// consume padding bytes
pad, err := strconv.Atoi(field.Tag.Get("pad"))
if err == nil {
dummy := make([]byte, pad)
if _, err := pkt.readWriter.Read(dummy); err != nil {
if _, err := pkt.readWriter.Read(make([]byte, pad)); err != nil {
return err
}
}

View File

@ -61,7 +61,7 @@ func TestPacketEncode(t *testing.T) {
err := pkt.Encode(testStruct)
is.NoErr(err)
is.True(bytes.Equal(buf.Bytes(), testData[:])) // encoded data should match expected data
is.Equal(buf.Bytes(), testData[:]) // encoded data should match expected data
}
func TestPacketDecode(t *testing.T) {
@ -73,7 +73,7 @@ func TestPacketDecode(t *testing.T) {
var test TestPacketData
err := pkt.Decode(&test)
is.NoErr(err)
is.True(test == testStruct) // decoded data should match testStruct
is.Equal(test, testStruct) // decoded data should match testStruct
}
func TestDataEncrypt(t *testing.T) {
@ -82,8 +82,7 @@ func TestDataEncrypt(t *testing.T) {
copy(buf, testData[:])
protocol.EncryptData(buf, []byte(protocol.DEFAULT_KEY))
is.True(bytes.Equal(buf, encTestData)) // encrypted data should match expected data
is.Equal(buf, encTestData) // encrypted data should match expected data
}
func TestDataDecrypt(t *testing.T) {
@ -92,13 +91,12 @@ func TestDataDecrypt(t *testing.T) {
copy(buf, encTestData)
protocol.DecryptData(buf, []byte(protocol.DEFAULT_KEY))
is.True(bytes.Equal(buf, testData[:])) // decrypted data should match expected data
is.Equal(buf, testData[:]) // decrypted data should match expected data
}
func TestCreateNewKey(t *testing.T) {
is := is.New(t)
key := protocol.CreateNewKey(123456789, 0x1234567890abcdef, 0x1234567890abcdef)
is.True(bytes.Equal(key, []byte{0x0, 0x31, 0xb8, 0xcd, 0xd, 0xc3, 0xad, 0x67})) // key should match expected data
is.Equal(key, []byte{0x0, 0x31, 0xb8, 0xcd, 0xd, 0xc3, 0xad, 0x67}) // key should match expected data
}

View File

@ -11,7 +11,7 @@ import (
"sync"
"github.com/CPunch/gopenfusion/cnet/protocol"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
)
type PacketHandler func(peer *Peer, pkt protocol.Packet) error

3
go.mod
View File

@ -3,6 +3,7 @@ module github.com/CPunch/gopenfusion
go 1.19
require (
github.com/alicebob/miniredis/v2 v2.31.0
github.com/bitcomplete/sqltestutil v1.0.1
github.com/blockloop/scan v1.3.0
github.com/georgysavva/scany/v2 v2.0.0
@ -16,6 +17,7 @@ require (
require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
@ -34,6 +36,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/stretchr/testify v1.8.0 // indirect
github.com/yuin/gopher-lua v1.1.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

12
go.sum
View File

@ -1,7 +1,12 @@
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.31.0 h1:ObEFUNlJwoIiyjxdrYF0QIDE7qXcLc7D3WpSH4c22PU=
github.com/alicebob/miniredis/v2 v2.31.0/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg=
github.com/bitcomplete/sqltestutil v1.0.1 h1:rj/RgrXXyuPB8KYrFmxiSjORb1hrhK6sXHpDPaSEBII=
github.com/bitcomplete/sqltestutil v1.0.1/go.mod h1:ZgpEnW6t2RBsCo9EIEYsAvjxJeZDwOzC8aVYXK0+gdE=
github.com/blockloop/scan v1.3.0 h1:p8xnajpGA3d/V6o23IBFdQ764+JnNJ+PQj+OwT+rkdg=
@ -10,6 +15,9 @@ github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -33,6 +41,7 @@ github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaL
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
@ -79,6 +88,8 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE=
github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -95,6 +106,7 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -4,7 +4,7 @@ import (
"database/sql"
"github.com/CPunch/gopenfusion/cnet/protocol"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/blockloop/scan"
)

View File

@ -10,7 +10,7 @@ import (
_ "embed"
"fmt"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
_ "github.com/lib/pq"
)

View File

@ -5,7 +5,7 @@ import (
"fmt"
"strconv"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
)
type LoginMetadata struct {

View File

@ -7,7 +7,7 @@ package redis
import (
"context"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/redis/go-redis/v9"
)
@ -17,10 +17,6 @@ type RedisHandler struct {
ctx context.Context
}
const (
SHARD_SET = "shards"
)
func OpenRedis(addr string) (*RedisHandler, error) {
client := redis.NewClient(&redis.Options{
Addr: addr,

View File

@ -0,0 +1,77 @@
package redis_test
import (
"os"
"testing"
"github.com/CPunch/gopenfusion/internal/redis"
"github.com/alicebob/miniredis/v2"
"github.com/matryer/is"
)
var (
rh *redis.RedisHandler
)
func TestMain(m *testing.M) {
r, err := miniredis.Run()
if err != nil {
panic(err)
}
defer r.Close()
rh, err = redis.OpenRedis(r.Addr())
if err != nil {
panic(err)
}
defer rh.Close()
os.Exit(m.Run())
}
func TestRedisLogin(t *testing.T) {
is := is.New(t)
// test data
serialKey := int64(1234)
data := redis.LoginMetadata{
FEKey: []byte("test"),
PlayerID: 1,
AccountID: 2,
}
// queue login
is.NoErr(rh.QueueLogin(serialKey, data))
// get login
loginData, err := rh.GetLogin(serialKey)
is.NoErr(err)
// compare
is.Equal(loginData, data) // received data should be the same as sent data
// delete login
is.NoErr(rh.RemoveLogin(serialKey))
// get login
_, err = rh.GetLogin(serialKey)
is.True(err != nil) // should fail to get removed login
}
func TestRedisShard(t *testing.T) {
is := is.New(t)
// test data
shard := redis.ShardMetadata{
IP: "0.0.0.0",
Port: 1234,
}
// register shard
is.NoErr(rh.RegisterShard(shard))
// get shards
shards := rh.GetShards()
is.True(len(shards) == 1) // should only be 1 shard
is.Equal(shards[0], shard) // received data should be the same as sent data
}

View File

@ -7,6 +7,10 @@ type ShardMetadata struct {
Port int
}
const (
SHARD_SET = "shards"
)
func (r *RedisHandler) RegisterShard(shard ShardMetadata) error {
value, err := json.Marshal(shard)
if err != nil {

View File

@ -9,7 +9,7 @@ import (
"github.com/CPunch/gopenfusion/cnet"
"github.com/CPunch/gopenfusion/cnet/protocol"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/internal/db"
"github.com/CPunch/gopenfusion/internal/redis"
"github.com/CPunch/gopenfusion/util"

View File

@ -4,7 +4,7 @@ import (
"log"
"sync"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
)
type ChunkPosition struct {

View File

@ -5,7 +5,7 @@ import (
"log"
"os"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/shard/entity"
)

View File

@ -5,7 +5,7 @@ import (
"github.com/CPunch/gopenfusion/cnet"
"github.com/CPunch/gopenfusion/cnet/protocol"
"github.com/CPunch/gopenfusion/config"
"github.com/CPunch/gopenfusion/internal/config"
"github.com/CPunch/gopenfusion/internal/db"
"github.com/CPunch/gopenfusion/internal/redis"
"github.com/CPunch/gopenfusion/shard/entity"