Files
GameServer/core/AEGS_methods.go

422 lines
11 KiB
Go
Raw Normal View History

2022-10-18 11:50:10 +09:00
package core
import (
"anvil/shared"
"errors"
"net"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
/*
func (gs *AeGameServer) LobbyCheckIn(ip net.IP, inSocketPort int32) {
gs.lock.Lock()
defer gs.lock.Unlock()
gs.LobbyIp = ip
gs.LobbyPort = inSocketPort
}
func (gs *AeGameServer) GetUrlLobbyChekedIn() string {
gs.lock.Lock()
defer gs.lock.Unlock()
if len(gs.LobbyIp) != 0 {
return fmt.Sprintf("%s:%d", gs.LobbyIp.String(), gs.LobbyPort)
} else {
return ""
}
}
func (gs *AeGameServer) WorldCheckIn(ip net.IP, inSocketPort int32) {
gs.lock.Lock()
defer gs.lock.Unlock()
gs.WorldIp = ip
gs.WorldPort = inSocketPort
}
func (gs *AeGameServer) GetUrlWorldChekedIn() string {
gs.lock.Lock()
defer gs.lock.Unlock()
if len(gs.WorldIp) != 0 {
return fmt.Sprintf("%s:%d", gs.WorldIp.String(), gs.LobbyPort)
} else {
return ""
}
}
*/
func (gs *AeGameServer) FindDsCheckedIn(Type int32, Version string) string {
gs.lock.Lock()
defer gs.lock.Unlock()
var priority float32 = 0
url := ""
for _, s := range gs.sockets {
if s.IsCompatible(Type, Version) {
if tmpUrl := s.GetUrlChekedIn(); tmpUrl != "" {
tmpPriority := s.GetPriority()
if tmpPriority >= priority {
url = tmpUrl
priority = tmpPriority
}
}
}
}
return url
}
func (tx *transaction) Hello() shared.RPCReturnType {
tx.gs.Logger.Println("hello, too")
return shared.MakeRPCReturn("hello, too.", nil)
}
func externalIP() (net.IP, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip == nil {
continue // not an ipv4 address
}
return ip, nil
}
}
return nil, errors.New("are you connected to the network?")
}
/*
func (tx *transaction) LobbyCheckIn(inSocketPort int32) shared.RPCReturnType {
// list.Append(test)
tx.gs.Logger.Printf("remoteaddr %s : %d", tx.r.RemoteAddr, inSocketPort)
ip, _, err := net.SplitHostPort(tx.r.RemoteAddr)
if err != nil {
tx.gs.Logger.Printf("userip: %q is not IP:port", tx.r.RemoteAddr)
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
userIP := net.ParseIP(ip)
if userIP == nil {
tx.gs.Logger.Printf("userip: %q is not IP:port", tx.r.RemoteAddr)
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
if userIP.IsLoopback() {
if tmpIp, err := externalIP(); err == nil {
userIP = tmpIp
} else {
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
}
tx.gs.LobbyCheckIn(userIP, inSocketPort)
return shared.MakeRPCReturn("lobby checked in.", nil)
}
func (tx *transaction) WorldCheckIn(inSocketPort int32) shared.RPCReturnType {
// list.Append(test)
tx.gs.Logger.Printf("remoteaddr %s : %d", tx.r.RemoteAddr, inSocketPort)
ip, _, err := net.SplitHostPort(tx.r.RemoteAddr)
if err != nil {
tx.gs.Logger.Printf("userip: %q is not IP:port", tx.r.RemoteAddr)
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
userIP := net.ParseIP(ip)
if userIP == nil {
tx.gs.Logger.Printf("userip: %q is not IP:port", tx.r.RemoteAddr)
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
if userIP.IsLoopback() {
if tmpIp, err := externalIP(); err == nil {
userIP = tmpIp
} else {
return shared.MakeRPCReturn(nil, errors.New("IP invalid"))
}
}
tx.gs.WorldCheckIn(userIP, inSocketPort)
return shared.MakeRPCReturn("world checked in.", nil)
}
*/
func (tx *transaction) GetCheckedIn(Type int32, Version string) shared.RPCReturnType {
// url := tx.gs.GetUrlLobbyChekedIn()
url := tx.gs.FindDsCheckedIn(Type, Version)
tx.gs.Logger.Println("lobby url checked in : ", url)
if url == "" {
return shared.MakeRPCReturn(nil, errors.New("no url"))
} else {
return shared.MakeRPCReturn(url, nil)
}
}
// func (tx *transaction) GetLobbyCheckedIn() shared.RPCReturnType {
// // url := tx.gs.GetUrlLobbyChekedIn()
// url := tx.gs.FindDsCheckedIn(2)
// tx.gs.Logger.Println("lobby url checked in : ", url)
// if url == "" {
// return shared.MakeRPCReturn(nil, errors.New("no url"))
// } else {
// return shared.MakeRPCReturn(url, nil)
// }
// }
// func (tx *transaction) GetWorldCheckedIn() shared.RPCReturnType {
// // url := tx.gs.GetUrlWorldChekedIn()
// url := tx.gs.FindDsCheckedIn(1)
// tx.gs.Logger.Println("world url checked in : ", url)
// if url == "" {
// return shared.MakeRPCReturn(nil, errors.New("no url"))
// } else {
// return shared.MakeRPCReturn(url, nil)
// }
// }
func (tx *transaction) ReadDB(collection string, _id interface{}) shared.RPCReturnType {
raw, err := tx.gs.mongoClient.FindOneAndUpdate(shared.CollectionName(collection),
bson.M{"_id": _id},
bson.M{
"$setOnInsert": bson.M{"_id": _id},
},
options.FindOneAndUpdate().SetProjection(bson.M{"_id": 0, "_ts": 0}),
options.FindOneAndUpdate().SetReturnDocument(options.After),
options.FindOneAndUpdate().SetUpsert(true))
tx.gs.Logger.Println("db read : ", _id, raw)
return shared.MakeRPCReturn(raw, err)
}
func (tx *transaction) ReadMany(collection string, in []interface{}) shared.RPCReturnType {
raw, err := tx.gs.mongoClient.FindAll(shared.CollectionName(collection), bson.M{"_id": bson.M{"$in": in}},
options.Find().SetProjection(bson.M{"_ts": 0}))
tx.gs.Logger.Println("db read : ", raw)
return shared.MakeRPCReturn(raw, err)
}
func (tx *transaction) WriteDB(collection string, raw map[string]interface{}) shared.RPCReturnType {
tx.gs.Logger.Println("db access in collection : ", collection, raw)
_, _, err := tx.gs.mongoClient.Update(shared.CollectionName(collection),
bson.M{"_id": raw["_id"]},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$set": raw,
}, options.Update().SetUpsert(true))
return shared.MakeRPCReturn(nil, err)
}
func (tx *transaction) RemoveDB(collection string, keys []interface{}) shared.RPCReturnType {
count, err := tx.gs.mongoClient.DeleteMany(shared.CollectionName(collection), bson.M{"_id": bson.M{"$in": keys}})
return shared.MakeRPCReturn(count, err)
}
func (tx *transaction) UpdatePlayerInfo(raw map[string]interface{}) shared.RPCReturnType {
var playerid string
if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 {
playerid = v[0]
} else {
return shared.MakeRPCReturn(nil, errors.New("no player id"))
}
tx.gs.Logger.Println("db write : ", playerid, raw)
_, _, err := tx.gs.mongoClient.Update("PlayerInfo",
bson.M{"_id": playerid},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$set": raw,
}, options.Update().SetUpsert(true))
if err == nil {
return shared.MakeRPCReturn("update success", err)
} else {
return shared.MakeRPCReturn(nil, errors.New("invalid body"))
}
}
func (tx *transaction) GetPlayerInfo() shared.RPCReturnType {
var playerid string
if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 {
playerid = v[0]
} else {
return shared.MakeRPCReturn(nil, errors.New("no player id"))
}
raw, err := tx.gs.mongoClient.FindOneAndUpdate("PlayerInfo",
bson.M{"_id": playerid},
bson.M{
"$setOnInsert": bson.M{"_id": playerid, "charId": 101},
},
options.FindOneAndUpdate().SetProjection(bson.M{"_id": 0, "_ts": 0}),
options.FindOneAndUpdate().SetReturnDocument(options.After),
options.FindOneAndUpdate().SetUpsert(true))
tx.gs.Logger.Println("db read : ", playerid, raw)
if err == nil {
return shared.MakeRPCReturn(raw, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}
func (tx *transaction) UpdateInventory(charId int32, raw map[string]interface{}) shared.RPCReturnType {
var playerid string
if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 {
playerid = v[0]
} else {
return shared.MakeRPCReturn(nil, errors.New("no player id"))
}
tx.gs.Logger.Println("inventory write : ", playerid, raw)
var err error
q, _ := tx.gs.mongoClient.FindOne("Inventory", bson.M{"_id": playerid, "inven.charId": charId},
options.FindOne().SetProjection(bson.M{"inven.$": 1}))
if q == nil {
_, _, err = tx.gs.mongoClient.Update("Inventory",
bson.M{"_id": playerid},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$addToSet": bson.M{"inven": bson.M{"charId": charId, "slots": raw}},
},
options.Update().SetUpsert(true))
} else {
// _, _, err = tx.gs.mongoClient.Update("Inventory",
// bson.M{"_id": playerid},
// bson.M{
// "$currentDate": bson.M{"_ts": true},
// "$set": bson.M{"inven.$[x].slots": raw},
// },
// options.Update().SetArrayFilters(options.ArrayFilters{Filters: bson.A{bson.M{"x.charId": charId}}}),
// options.Update().SetUpsert(true))
slots := q["inven"].(bson.A)[0].(map[string]interface{})["slots"].(map[string]interface{})
tx.gs.Logger.Println("current inventory", slots)
for k, v := range raw {
slots[k] = v
}
tx.gs.Logger.Println("new inventory", slots)
_, _, err = tx.gs.mongoClient.Update("Inventory",
bson.M{"_id": playerid, "inven.charId": charId},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$set": bson.M{"inven.$.slots": slots},
})
}
if err == nil {
tx.gs.Logger.Println("inventory write success")
return shared.MakeRPCReturn(raw, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("invalid body"))
}
}
func (tx *transaction) GetInventory(charId int32) shared.RPCReturnType {
var playerid string
if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 {
playerid = v[0]
} else {
return shared.MakeRPCReturn(nil, errors.New("no player id"))
}
raw, err := tx.gs.mongoClient.FindOne("Inventory",
bson.M{"_id": playerid, "inven.charId": charId},
options.FindOne().SetProjection(bson.M{"inven.$": 1}))
if raw == nil {
_, err = tx.gs.mongoClient.FindOneAndUpdate("Inventory",
bson.M{"_id": playerid},
bson.M{
"$setOnInsert": bson.M{"_id": playerid, "inven": bson.A{}},
},
options.FindOneAndUpdate().SetUpsert(true))
raw, err = tx.gs.mongoClient.FindOneAndUpdate("Inventory",
bson.M{"_id": playerid},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$addToSet": bson.M{"inven": bson.M{"charId": charId, "slots": bson.M{}}},
},
options.FindOneAndUpdate().SetProjection(bson.M{"inven": bson.M{"$elemMatch": bson.M{"charId": charId}}}),
options.FindOneAndUpdate().SetReturnDocument(options.After),
options.FindOneAndUpdate().SetUpsert(true))
}
// raw, err := tx.gs.mongoClient.FindOneAndUpdate("Inventory",
// bson.M{"_id": playerid, "inven.charId": charId},
// bson.M{
// "$setOnInsert": bson.M{"_id": playerid, "inven": bson.A{bson.M{"charId": charId, "slots": bson.M{}}}},
// },
// options.FindOneAndUpdate().SetProjection(bson.M{"inven.$": 1}),
// options.FindOneAndUpdate().SetReturnDocument(options.After),
// options.FindOneAndUpdate().SetUpsert(true))
if err == nil {
slots := raw["inven"].(bson.A)[0].(map[string]interface{})["slots"]
tx.gs.Logger.Println("inventory read : ", playerid, slots)
return shared.MakeRPCReturn(slots, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}