Compare commits

..

No commits in common. "96130ddc8dfdaefbd6175c91d4083adaace0ae4d" and "f4b17906cea21f62b8b7a19176de5980677ec088" have entirely different histories.

6 changed files with 84 additions and 81 deletions

1
go.mod
View File

@ -8,7 +8,6 @@ require (
github.com/georgysavva/scany/v2 v2.0.0 github.com/georgysavva/scany/v2 v2.0.0
github.com/google/subcommands v1.2.0 github.com/google/subcommands v1.2.0
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/matryer/is v1.4.1
github.com/redis/go-redis/v9 v9.0.5 github.com/redis/go-redis/v9 v9.0.5
golang.org/x/crypto v0.7.0 golang.org/x/crypto v0.7.0
) )

2
go.sum
View File

@ -48,8 +48,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=

View File

@ -6,8 +6,6 @@ import (
"os" "os"
"testing" "testing"
"github.com/matryer/is"
"github.com/CPunch/gopenfusion/internal/db" "github.com/CPunch/gopenfusion/internal/db"
"github.com/CPunch/gopenfusion/internal/protocol" "github.com/CPunch/gopenfusion/internal/protocol"
"github.com/bitcomplete/sqltestutil" "github.com/bitcomplete/sqltestutil"
@ -39,20 +37,23 @@ func TestMain(m *testing.M) {
} }
func TestDBAccount(t *testing.T) { func TestDBAccount(t *testing.T) {
is := is.New(t) if _, err := testDB.NewAccount("test", "test"); err != nil {
t.Error(err)
// create new account }
_, err := testDB.NewAccount("test", "test")
is.NoErr(err)
// now try to retrieve account data // now try to retrieve account data
acc, err := testDB.TryLogin("test", "test") acc, err := testDB.TryLogin("test", "test")
is.NoErr(err) if err != nil {
t.Error(err)
}
_, err = testDB.TryLogin("test", "wrongpassword") if acc.Login != "test" {
t.Error("account username is not test")
}
is.True(acc.Login == "test") // login data should match created account if _, err = testDB.TryLogin("test", "wrongpassword"); !errors.Is(err, db.ErrLoginInvalidPassword) {
is.True(errors.Is(err, db.ErrLoginInvalidPassword)) // wrong password passed to TryLogin() should fail with ErrLoginInvalidPassword t.Error("expected ErrLoginInvalidPassword")
}
} }
/* /*
@ -80,18 +81,22 @@ gopenfusion=# SELECT * FROM Inventory;
*/ */
func TestDBPlayer(t *testing.T) { func TestDBPlayer(t *testing.T) {
is := is.New(t) if _, err := testDB.NewAccount("testplayer", "test"); err != nil {
_, err := testDB.NewAccount("testplayer", "test") t.Error(err)
is.NoErr(err) }
// now try to retrieve account data // now try to retrieve account data
acc, err := testDB.TryLogin("testplayer", "test") acc, err := testDB.TryLogin("testplayer", "test")
is.NoErr(err) if err != nil {
t.Error(err)
}
plrID, err := testDB.NewPlayer(acc.AccountID, "Neil", "Mcscout", 1) plrID, err := testDB.NewPlayer(acc.AccountID, "Neil", "Mcscout", 1)
is.NoErr(err) if err != nil {
t.Error(err)
}
err = testDB.FinishPlayer(&protocol.SP_CL2LS_REQ_CHAR_CREATE{ if err = testDB.FinishPlayer(&protocol.SP_CL2LS_REQ_CHAR_CREATE{
PCStyle: protocol.SPCStyle{ PCStyle: protocol.SPCStyle{
IPC_UID: int64(plrID), IPC_UID: int64(plrID),
INameCheck: 1, INameCheck: 1,
@ -111,9 +116,11 @@ func TestDBPlayer(t *testing.T) {
IEquipLBID: 359, IEquipLBID: 359,
IEquipFootID: 194, IEquipFootID: 194,
}, },
}, acc.AccountID) }, acc.AccountID); err != nil {
is.NoErr(err) t.Error(err)
}
err = testDB.FinishTutorial(plrID, acc.AccountID)
is.NoErr(err) if err = testDB.FinishTutorial(plrID, acc.AccountID); err != nil {
t.Error(err)
}
} }

View File

@ -4,11 +4,9 @@ import (
"testing" "testing"
"github.com/CPunch/gopenfusion/internal/entity" "github.com/CPunch/gopenfusion/internal/entity"
"github.com/matryer/is"
) )
func TestChunkSliceDifference(t *testing.T) { func TestChunkSliceDifference(t *testing.T) {
is := is.New(t)
chunks := []*entity.Chunk{ chunks := []*entity.Chunk{
entity.NewChunk(entity.MakeChunkPosition(0, 0)), entity.NewChunk(entity.MakeChunkPosition(0, 0)),
entity.NewChunk(entity.MakeChunkPosition(0, 1)), entity.NewChunk(entity.MakeChunkPosition(0, 1)),
@ -30,7 +28,13 @@ func TestChunkSliceDifference(t *testing.T) {
} }
diff := entity.ChunkSliceDifference(c1, c2) diff := entity.ChunkSliceDifference(c1, c2)
if len(diff) != 1 {
is.True(len(diff) == 1) // should be 1 chunk in difference t.Logf("%+v", diff)
is.True(diff[0] == chunks[3]) // should be chunks[3] in difference t.Error("expected 1 chunk in difference")
}
if diff[0] != chunks[3] {
t.Logf("%+v", diff)
t.Error("wrong difference")
}
} }

View File

@ -5,7 +5,6 @@ import (
"testing" "testing"
"github.com/CPunch/gopenfusion/internal/protocol" "github.com/CPunch/gopenfusion/internal/protocol"
"github.com/matryer/is"
) )
type TestPacketData struct { type TestPacketData struct {
@ -54,51 +53,59 @@ var (
) )
func TestPacketEncode(t *testing.T) { func TestPacketEncode(t *testing.T) {
is := is.New(t)
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
pkt := protocol.NewPacket(buf) pkt := protocol.NewPacket(buf)
err := pkt.Encode(testStruct) if err := pkt.Encode(testStruct); err != nil {
is.NoErr(err) t.Error(err)
}
is.True(bytes.Equal(buf.Bytes(), testData[:])) // encoded data should match expected data if !bytes.Equal(buf.Bytes(), testData[:]) {
t.Error("packet data does not match!")
}
} }
func TestPacketDecode(t *testing.T) { func TestPacketDecode(t *testing.T) {
is := is.New(t)
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
pkt := protocol.NewPacket(buf) pkt := protocol.NewPacket(buf)
buf.Write(testData[:]) buf.Write(testData[:])
var test TestPacketData var test TestPacketData
err := pkt.Decode(&test) if err := pkt.Decode(&test); err != nil {
is.NoErr(err) t.Error(err)
is.True(test == testStruct) // decoded data should match testStruct }
if test != testStruct {
t.Error("packet data does not match!")
}
} }
func TestDataEncrypt(t *testing.T) { func TestDataEncrypt(t *testing.T) {
is := is.New(t)
buf := make([]byte, len(testData)) buf := make([]byte, len(testData))
copy(buf, testData[:]) copy(buf, testData[:])
protocol.EncryptData(buf, []byte(protocol.DEFAULT_KEY)) protocol.EncryptData(buf, []byte(protocol.DEFAULT_KEY))
is.True(bytes.Equal(buf, encTestData)) // encrypted data should match expected data if !bytes.Equal(buf, encTestData) {
t.Error("encrypted data does not match!")
}
} }
func TestDataDecrypt(t *testing.T) { func TestDataDecrypt(t *testing.T) {
is := is.New(t)
buf := make([]byte, len(encTestData)) buf := make([]byte, len(encTestData))
copy(buf, encTestData) copy(buf, encTestData)
protocol.DecryptData(buf, []byte(protocol.DEFAULT_KEY)) protocol.DecryptData(buf, []byte(protocol.DEFAULT_KEY))
is.True(bytes.Equal(buf, testData[:])) // decrypted data should match expected data if !bytes.Equal(buf, testData[:]) {
t.Error("decrypted data does not match!")
}
} }
func TestCreateNewKey(t *testing.T) { func TestCreateNewKey(t *testing.T) {
is := is.New(t)
key := protocol.CreateNewKey(123456789, 0x1234567890abcdef, 0x1234567890abcdef) 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 if !bytes.Equal(key, []byte{0x0, 0x31, 0xb8, 0xcd, 0xd, 0xc3, 0xad, 0x67}) {
t.Error("key does not match!")
}
} }

View File

@ -12,7 +12,6 @@ import (
"github.com/CPunch/gopenfusion/internal/protocol" "github.com/CPunch/gopenfusion/internal/protocol"
"github.com/CPunch/gopenfusion/internal/service" "github.com/CPunch/gopenfusion/internal/service"
"github.com/matryer/is"
) )
var ( var (
@ -24,15 +23,6 @@ const (
maxDummyPeers = 5 maxDummyPeers = 5
) )
func selectWithTimeout(ch <-chan struct{}, seconds int) bool {
select {
case <-ch:
return true
case <-time.After(time.Duration(seconds) * time.Second):
return false
}
}
func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool { func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool {
done := make(chan struct{}) done := make(chan struct{})
go func() { go func() {
@ -40,7 +30,12 @@ func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool {
wg.Wait() wg.Wait()
}() }()
return selectWithTimeout(done, seconds) select {
case <-done:
return true
case <-time.After(time.Duration(seconds) * time.Second):
return false
}
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -54,48 +49,34 @@ func TestMain(m *testing.M) {
} }
func TestService(t *testing.T) { func TestService(t *testing.T) {
is := is.New(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
srvc := service.NewService(ctx, "TEST", srvcPort) srvc := service.NewService(ctx, "TEST", srvcPort)
// waitgroup to wait for test packet handler to be called
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
// shutdown service when test is done
defer func() {
cancel()
is.True(selectWithTimeout(srvc.Stopped(), timeout)) // wait for service to stop with timeout
}()
// our dummy packet handler
srvc.AddPacketHandler(0x1234, func(peer *protocol.CNPeer, pkt protocol.Packet) error { srvc.AddPacketHandler(0x1234, func(peer *protocol.CNPeer, pkt protocol.Packet) error {
log.Printf("Received packet %#v", pkt) log.Printf("Received packet %#v", pkt)
wg.Done() wg.Done()
return nil return nil
}) })
// wait for all dummy peers to connect and disconnect
wg.Add(maxDummyPeers)
srvc.OnConnect = func(peer *protocol.CNPeer) {
wg.Done()
}
wg.Add(maxDummyPeers)
srvc.OnDisconnect = func(peer *protocol.CNPeer) {
wg.Done()
}
// run service
go func() { go func() {
is.NoErr(srvc.Start()) // srvc.Start error if err := srvc.Start(); err != nil {
t.Error(err)
}
}() }()
is.True(selectWithTimeout(srvc.Started(), timeout)) // wait for service to start with timeout // wait for service to start
<-srvc.Started()
wg.Add(maxDummyPeers * 3) // 3 wg.Done() calls per dummy peer. 2 per peer for receiving packets, 1 for Handler() exit wg.Add(maxDummyPeers * 3) // 2 wg.Done() calls per dummy peer
for i := 0; i < maxDummyPeers; i++ { for i := 0; i < maxDummyPeers; i++ {
go func() { go func() {
// make dummy client // make dummy client
conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", srvcPort)) conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", srvcPort))
is.NoErr(err) // net.Dial error if err != nil {
t.Error(err)
}
peer := protocol.NewCNPeer(ctx, conn) peer := protocol.NewCNPeer(ctx, conn)
go func() { go func() {
@ -103,7 +84,9 @@ func TestService(t *testing.T) {
// send dummy packets // send dummy packets
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
is.NoErr(peer.Send(0x1234)) // peer.Send error if err := peer.Send(0x1234); err != nil {
t.Error(err)
}
} }
}() }()
@ -113,5 +96,10 @@ func TestService(t *testing.T) {
}() }()
} }
is.True(waitWithTimeout(&wg, timeout)) // wait for all dummy peers to be done with timeout if !waitWithTimeout(&wg, timeout) {
t.Error("failed to wait for packet handler to be called")
}
cancel()
<-srvc.Stopped()
} }