Compare commits

...

2 Commits

Author SHA1 Message Date
1da82ac750 include AccountID in loginMetadata 2023-06-22 18:12:31 -05:00
d42a34535b split redis.go 2023-06-22 18:05:02 -05:00
6 changed files with 91 additions and 80 deletions

View File

@ -24,7 +24,7 @@ services:
links: links:
- postgresql - postgresql
- redis - redis
shard0: shard:
restart: on-failure restart: on-failure
build: . build: .
hostname: shard hostname: shard

52
core/redis/login.go Normal file
View File

@ -0,0 +1,52 @@
package redis
import (
"encoding/json"
"fmt"
"strconv"
"github.com/CPunch/gopenfusion/config"
)
type LoginMetadata struct {
FEKey []byte `json:",omitempty"`
PlayerID int32 `json:",omitempty"`
AccountID int `json:",omitempty"`
}
// we store login queues into redis with the name "loginMetadata_<serialKey>"
// set to expire after config.LOGIN_TIMEOUT duration. this way we can easily
// have a shared pool of active serial keys & player login data which any
// shard can pull from
func makeLoginMetadataKey(serialKey int64) string {
return fmt.Sprintf("loginMetadata_%s", strconv.Itoa(int(serialKey)))
}
func (r *RedisHandler) QueueLogin(serialKey int64, data LoginMetadata) error {
value, err := json.Marshal(data)
if err != nil {
return err
}
// add to table
return r.client.Set(r.ctx, makeLoginMetadataKey(serialKey), value, config.LOGIN_TIMEOUT).Err()
}
func (r *RedisHandler) GetLogin(serialKey int64) (LoginMetadata, error) {
value, err := r.client.Get(r.ctx, makeLoginMetadataKey(serialKey)).Result()
if err != nil {
return LoginMetadata{}, err
}
var data LoginMetadata
if err := json.Unmarshal([]byte(value), &data); err != nil {
return LoginMetadata{}, err
}
return data, nil
}
func (r *RedisHandler) RemoveLogin(serialKey int64) error {
return r.client.Del(r.ctx, makeLoginMetadataKey(serialKey)).Err()
}

View File

@ -6,9 +6,6 @@ package redis
import ( import (
"context" "context"
"encoding/json"
"fmt"
"strconv"
"github.com/CPunch/gopenfusion/config" "github.com/CPunch/gopenfusion/config"
@ -20,16 +17,6 @@ type RedisHandler struct {
ctx context.Context ctx context.Context
} }
type LoginMetadata struct {
FEKey []byte `json:",omitempty"`
PlayerID int32 `json:",omitempty"`
}
type ShardMetadata struct {
IP string
Port int
}
const ( const (
SHARD_SET = "shards" SHARD_SET = "shards"
) )
@ -47,66 +34,3 @@ func OpenRedis(addr string) (*RedisHandler, error) {
func (r *RedisHandler) Close() error { func (r *RedisHandler) Close() error {
return r.client.Close() return r.client.Close()
} }
// we store login queues into redis with the name "loginMetadata_<serialKey>"
// set to expire after config.LOGIN_TIMEOUT duration. this way we can easily
// have a shared pool of active serial keys & player login data which any
// shard can pull from
func makeLoginMetadataKey(serialKey int64) string {
return fmt.Sprintf("loginMetadata_%s", strconv.Itoa(int(serialKey)))
}
func (r *RedisHandler) QueueLogin(serialKey int64, data LoginMetadata) error {
value, err := json.Marshal(data)
if err != nil {
return err
}
// add to table
return r.client.Set(r.ctx, makeLoginMetadataKey(serialKey), value, config.LOGIN_TIMEOUT).Err()
}
func (r *RedisHandler) GetLogin(serialKey int64) (LoginMetadata, error) {
value, err := r.client.Get(r.ctx, makeLoginMetadataKey(serialKey)).Result()
if err != nil {
return LoginMetadata{}, err
}
var data LoginMetadata
if err := json.Unmarshal([]byte(value), &data); err != nil {
return LoginMetadata{}, err
}
return data, nil
}
func (r *RedisHandler) RemoveLogin(serialKey int64) error {
return r.client.Del(r.ctx, makeLoginMetadataKey(serialKey)).Err()
}
func (r *RedisHandler) RegisterShard(shard ShardMetadata) error {
value, err := json.Marshal(shard)
if err != nil {
return err
}
return r.client.SAdd(r.ctx, SHARD_SET, value).Err()
}
func (r *RedisHandler) GetShards() []ShardMetadata {
shardData := r.client.SMembers(r.ctx, SHARD_SET).Val()
// unmarshal all shards
shards := make([]ShardMetadata, 0, len(shardData))
for _, data := range shardData {
var shard ShardMetadata
if err := json.Unmarshal([]byte(data), &shard); err != nil {
continue
}
shards = append(shards, shard)
}
return shards
}

34
core/redis/shard.go Normal file
View File

@ -0,0 +1,34 @@
package redis
import "encoding/json"
type ShardMetadata struct {
IP string
Port int
}
func (r *RedisHandler) RegisterShard(shard ShardMetadata) error {
value, err := json.Marshal(shard)
if err != nil {
return err
}
return r.client.SAdd(r.ctx, SHARD_SET, value).Err()
}
func (r *RedisHandler) GetShards() []ShardMetadata {
shardData := r.client.SMembers(r.ctx, SHARD_SET).Val()
// unmarshal all shards
shards := make([]ShardMetadata, 0, len(shardData))
for _, data := range shardData {
var shard ShardMetadata
if err := json.Unmarshal([]byte(data), &shard); err != nil {
continue
}
shards = append(shards, shard)
}
return shards
}

View File

@ -286,8 +286,9 @@ func (server *LoginServer) ShardSelect(peer *protocol.CNPeer, pkt protocol.Packe
// share the login attempt // share the login attempt
server.redisHndlr.QueueLogin(key, redis.LoginMetadata{ server.redisHndlr.QueueLogin(key, redis.LoginMetadata{
FEKey: peer.FE_key, FEKey: peer.FE_key,
PlayerID: int32(selection.IPC_UID), PlayerID: int32(selection.IPC_UID),
AccountID: peer.AccountID,
}) })
// craft response // craft response

View File

@ -49,7 +49,7 @@ func (server *ShardServer) RequestEnter(peer *protocol.CNPeer, pkt protocol.Pack
peer.FE_key = loginData.FEKey peer.FE_key = loginData.FEKey
peer.SetActiveKey(protocol.USE_FE) peer.SetActiveKey(protocol.USE_FE)
log.Printf("Player %d (AccountID %d) entered\n", resp.IID, loginData.PlayerID) log.Printf("Player %d (AccountID %d) entered\n", resp.IID, loginData.AccountID)
return peer.Send(protocol.P_FE2CL_REP_PC_ENTER_SUCC, resp) return peer.Send(protocol.P_FE2CL_REP_PC_ENTER_SUCC, resp)
} }