Files
GameServer/core/AEGS_methods.go

655 lines
18 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)
}
2022-12-19 15:36:27 +09:00
func (tx *transaction) WriteMany(collection string, rawArray []interface{}) shared.RPCReturnType {
for _, raw := range rawArray {
parsed := raw.(map[string]interface{})
_, _, err := tx.gs.mongoClient.Update(shared.CollectionName(collection),
bson.M{"_id": parsed["_id"]},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$set": parsed,
}, options.Update().SetUpsert(true))
if err != nil {
shared.MakeRPCReturn(nil, err)
}
}
return shared.MakeRPCReturn(nil, nil)
}
2022-10-18 11:50:10 +09:00
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)
}
2022-11-10 20:41:41 +09:00
// Player info/Character info
func (tx *transaction) GetAllCharInfo() shared.RPCReturnType {
2022-10-18 11:50:10 +09:00
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"))
}
2022-11-10 20:41:41 +09:00
q, err := tx.gs.mongoClient.FindOne("PlayerInfo", bson.M{"_id": playerid},
options.FindOne().SetProjection(bson.M{"_id": 0, "_ts": 0}))
if err == nil {
tx.gs.Logger.Println("charInfo dump : ", q)
return shared.MakeRPCReturn(q, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("invalid body"))
}
}
2022-10-18 11:50:10 +09:00
2022-11-10 20:41:41 +09:00
func (tx *transaction) RemoveCharInfo(charSlotId 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"))
}
_, err := tx.gs.mongoClient.FindOneAndUpdate(
"PlayerInfo",
2022-10-18 11:50:10 +09:00
bson.M{"_id": playerid},
2022-11-10 20:41:41 +09:00
bson.M{"$pull": bson.M{"charInfo": bson.M{"slotId": charSlotId}}},
)
2022-12-19 15:36:27 +09:00
if err == nil {
_, err = tx.gs.mongoClient.FindOneAndUpdate(
"Inventory",
bson.M{"_id": playerid},
bson.M{"$pull": bson.M{"inven": bson.M{"charSlotId": charSlotId}}},
)
}
2022-11-10 20:41:41 +09:00
if err == nil {
return shared.MakeRPCReturn("update success", err)
} else {
return shared.MakeRPCReturn(nil, errors.New("invalid body"))
}
}
func (tx *transaction) UpdateCharInfo(charSlotId 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("db write : ", playerid, raw)
q, err := tx.gs.mongoClient.FindOne("PlayerInfo", bson.M{"_id": playerid, "charInfo.slotId": charSlotId},
options.FindOne().SetProjection(bson.M{"charInfo.$": 1}))
2022-12-19 15:36:27 +09:00
var info map[string]interface{}
2022-11-10 20:41:41 +09:00
if q == nil {
2022-12-19 15:36:27 +09:00
info = raw
2022-11-10 20:41:41 +09:00
info["slotId"] = charSlotId
_, _, err = tx.gs.mongoClient.Update("PlayerInfo",
bson.M{"_id": playerid},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$addToSet": bson.M{"charInfo": info},
},
options.Update().SetUpsert(true))
} else {
2022-12-19 15:36:27 +09:00
info = q["charInfo"].(bson.A)[0].(map[string]interface{})
2022-11-10 20:41:41 +09:00
tx.gs.Logger.Println("current info", info)
for k, v := range raw {
if k == "slotId" {
continue
}
info[k] = v
}
_, _, err = tx.gs.mongoClient.Update("PlayerInfo",
bson.M{"_id": playerid, "charInfo.slotId": charSlotId},
bson.M{
"$currentDate": bson.M{"_ts": true},
"$set": bson.M{"charInfo.$": info},
})
}
2022-12-19 15:36:27 +09:00
tx.gs.Logger.Println("new info", info)
2022-11-10 20:41:41 +09:00
// _, _, err := tx.gs.mongoClient.Update("PlayerInfo",
// bson.M{"_id": playerid},
// bson.M{
// "$currentDate": bson.M{"_ts": true},
// "$set": raw,
// }, options.Update().SetUpsert(true))
2022-10-18 11:50:10 +09:00
if err == nil {
2022-12-19 15:36:27 +09:00
return shared.MakeRPCReturn(info, err)
2022-10-18 11:50:10 +09:00
} else {
return shared.MakeRPCReturn(nil, errors.New("invalid body"))
}
}
2022-11-10 20:41:41 +09:00
func (tx *transaction) GetCharInfo(charSlotId int32) shared.RPCReturnType {
2022-10-18 11:50:10 +09:00
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"))
}
2022-11-10 20:41:41 +09:00
raw, err := tx.gs.mongoClient.FindOne("PlayerInfo",
bson.M{"_id": playerid, "charInfo.slotId": charSlotId},
options.FindOne().SetProjection(bson.M{"charInfo": bson.M{"$elemMatch": bson.M{"slotId": charSlotId}}}))
// 계정 정보가 아예 없을 때
if raw == nil {
_, err = tx.GetCurrentCharSlotIdImpl(playerid)
// 다시 찾음
if err == nil {
raw, err = tx.gs.mongoClient.FindOne("PlayerInfo",
bson.M{"_id": playerid, "charInfo.slotId": charSlotId},
options.FindOne().SetProjection(bson.M{"charInfo": bson.M{"$elemMatch": bson.M{"slotId": charSlotId}}}))
}
}
// 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))
if err == nil {
tx.gs.Logger.Println("character info :", playerid, charSlotId, raw["charInfo"].(bson.A)[0])
return shared.MakeRPCReturn(raw["charInfo"].(bson.A)[0], err)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}
func (tx *transaction) GetCurrentCharInfo() 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"))
}
retval, err := tx.GetCurrentCharSlotIdImpl(playerid)
if err == nil {
tx.gs.Logger.Println("current character slot id : ", retval)
rt := tx.GetCharInfo(retval)
if rt.Error() == nil {
return shared.MakeRPCReturn(rt.Value(), nil)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
} else {
return shared.MakeRPCReturn(nil, err)
}
}
func (tx *transaction) UpdateCurrentCharInfo(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"))
}
retval, err := tx.GetCurrentCharSlotIdImpl(playerid)
if err == nil {
return tx.UpdateCharInfo(retval, raw)
} else {
return shared.MakeRPCReturn(nil, err)
}
}
func (tx *transaction) GetCurrentCharSlotIdImpl(playerid string) (int32, error) {
initialSlotId := 1
initialCharId := 1002
2022-10-18 11:50:10 +09:00
raw, err := tx.gs.mongoClient.FindOneAndUpdate("PlayerInfo",
bson.M{"_id": playerid},
bson.M{
2022-11-10 20:41:41 +09:00
"$setOnInsert": bson.M{
"_id": playerid,
"currentSlotId": initialSlotId,
"charInfo": bson.A{bson.M{"slotId": initialSlotId, "charId": initialCharId}}},
2022-10-18 11:50:10 +09:00
},
options.FindOneAndUpdate().SetReturnDocument(options.After),
options.FindOneAndUpdate().SetUpsert(true))
2022-11-10 20:41:41 +09:00
if err == nil {
return raw["currentSlotId"].(int32), nil
} else {
return 0, err
}
}
func (tx *transaction) SetCurrentCharSlotId(charSlotId 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"))
}
q, err := tx.gs.mongoClient.FindOneAndUpdate("PlayerInfo",
bson.M{"_id": playerid, "charInfo.slotId": charSlotId},
bson.M{"$set": bson.M{"currentSlotId": charSlotId}},
options.FindOneAndUpdate().SetProjection(bson.M{"_id": 0, "currentSlotId": 1, "charInfo": bson.M{"$elemMatch": bson.M{"slotId": charSlotId}}}),
)
2022-10-18 11:50:10 +09:00
if err == nil {
2022-11-10 20:41:41 +09:00
tx.gs.Logger.Println("current character slot :", q["charInfo"].(bson.A)[0])
return shared.MakeRPCReturn(q["charInfo"].(bson.A)[0], nil)
2022-10-18 11:50:10 +09:00
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}
2022-11-10 20:41:41 +09:00
func (tx *transaction) GetCurrentCharSlotId() 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"))
}
slotId, err := tx.GetCurrentCharSlotIdImpl(playerid)
if err == nil {
return shared.MakeRPCReturn(slotId, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}
// inventory
func (tx *transaction) UpdateInventory(charSlotId int32, raw map[string]interface{}) shared.RPCReturnType {
2022-10-18 11:50:10 +09:00
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
2022-11-10 20:41:41 +09:00
q, _ := tx.gs.mongoClient.FindOne("Inventory", bson.M{"_id": playerid, "inven.charSlotId": charSlotId},
2022-10-18 11:50:10 +09:00
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},
2022-11-10 20:41:41 +09:00
"$addToSet": bson.M{"inven": bson.M{"charSlotId": charSlotId, "slots": raw}},
2022-10-18 11:50:10 +09:00
},
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",
2022-11-10 20:41:41 +09:00
bson.M{"_id": playerid, "inven.charSlotId": charSlotId},
2022-10-18 11:50:10 +09:00
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"))
}
}
2022-11-10 20:41:41 +09:00
func (tx *transaction) GetInventory(charSlotId int32) shared.RPCReturnType {
2022-10-18 11:50:10 +09:00
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",
2022-11-10 20:41:41 +09:00
bson.M{"_id": playerid, "inven.charSlotId": charSlotId},
2022-10-18 11:50:10 +09:00
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},
2022-11-10 20:41:41 +09:00
"$addToSet": bson.M{"inven": bson.M{"charSlotId": charSlotId, "slots": bson.M{}}},
2022-10-18 11:50:10 +09:00
},
2022-11-10 20:41:41 +09:00
options.FindOneAndUpdate().SetProjection(bson.M{"inven": bson.M{"$elemMatch": bson.M{"charSlotId": charSlotId}}}),
2022-10-18 11:50:10 +09:00
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"]
2022-11-10 20:41:41 +09:00
tx.gs.Logger.Println("inventory :", playerid, charSlotId, slots)
2022-10-18 11:50:10 +09:00
return shared.MakeRPCReturn(slots, err)
} else {
return shared.MakeRPCReturn(nil, errors.New("not matched"))
}
}