diff --git a/.gitignore b/.gitignore index eaffb3b..ae904b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.log *.exe +.vscode \ No newline at end of file diff --git a/core/AEGS_methods.go b/core/AEGS_methods.go index 94dc50b..4adf3cb 100644 --- a/core/AEGS_methods.go +++ b/core/AEGS_methods.go @@ -258,7 +258,52 @@ func (tx *transaction) RemoveDB(collection string, keys []interface{}) shared.RP return shared.MakeRPCReturn(count, err) } -func (tx *transaction) UpdatePlayerInfo(raw map[string]interface{}) shared.RPCReturnType { +// Player info/Character info + +func (tx *transaction) GetAllCharInfo() 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.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")) + } +} + +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", + bson.M{"_id": playerid}, + bson.M{"$pull": bson.M{"charInfo": bson.M{"slotId": charSlotId}}}, + ) + + 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 { @@ -269,12 +314,49 @@ func (tx *transaction) UpdatePlayerInfo(raw map[string]interface{}) shared.RPCRe 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)) + q, err := tx.gs.mongoClient.FindOne("PlayerInfo", bson.M{"_id": playerid, "charInfo.slotId": charSlotId}, + options.FindOne().SetProjection(bson.M{"charInfo.$": 1})) + + if q == nil { + info := raw + info["slotId"] = charSlotId + + tx.gs.Logger.Println("new info", info) + + _, _, 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 { + info := q["charInfo"].(bson.A)[0].(map[string]interface{}) + tx.gs.Logger.Println("current info", info) + + for k, v := range raw { + if k == "slotId" { + continue + } + info[k] = v + } + + tx.gs.Logger.Println("new info", info) + + _, _, 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}, + }) + } + + // _, _, 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) @@ -283,7 +365,7 @@ func (tx *transaction) UpdatePlayerInfo(raw map[string]interface{}) shared.RPCRe } } -func (tx *transaction) GetPlayerInfo() shared.RPCReturnType { +func (tx *transaction) GetCharInfo(charSlotId int32) shared.RPCReturnType { var playerid string if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 { @@ -292,25 +374,149 @@ func (tx *transaction) GetPlayerInfo() shared.RPCReturnType { 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)) + 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}}})) - tx.gs.Logger.Println("db read : ", playerid, raw) + // 계정 정보가 아예 없을 때 + 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 { - return shared.MakeRPCReturn(raw, err) + 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) UpdateInventory(charId int32, raw map[string]interface{}) shared.RPCReturnType { +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 + + raw, err := tx.gs.mongoClient.FindOneAndUpdate("PlayerInfo", + bson.M{"_id": playerid}, + bson.M{ + "$setOnInsert": bson.M{ + "_id": playerid, + "currentSlotId": initialSlotId, + "charInfo": bson.A{bson.M{"slotId": initialSlotId, "charId": initialCharId}}}, + }, + options.FindOneAndUpdate().SetReturnDocument(options.After), + options.FindOneAndUpdate().SetUpsert(true)) + + 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}}}), + ) + + if err == nil { + tx.gs.Logger.Println("current character slot :", q["charInfo"].(bson.A)[0]) + return shared.MakeRPCReturn(q["charInfo"].(bson.A)[0], nil) + } else { + return shared.MakeRPCReturn(nil, errors.New("not matched")) + } +} + +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 { var playerid string if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 { @@ -323,7 +529,7 @@ func (tx *transaction) UpdateInventory(charId int32, raw map[string]interface{}) var err error - q, _ := tx.gs.mongoClient.FindOne("Inventory", bson.M{"_id": playerid, "inven.charId": charId}, + q, _ := tx.gs.mongoClient.FindOne("Inventory", bson.M{"_id": playerid, "inven.charSlotId": charSlotId}, options.FindOne().SetProjection(bson.M{"inven.$": 1})) if q == nil { @@ -331,7 +537,7 @@ func (tx *transaction) UpdateInventory(charId int32, raw map[string]interface{}) bson.M{"_id": playerid}, bson.M{ "$currentDate": bson.M{"_ts": true}, - "$addToSet": bson.M{"inven": bson.M{"charId": charId, "slots": raw}}, + "$addToSet": bson.M{"inven": bson.M{"charSlotId": charSlotId, "slots": raw}}, }, options.Update().SetUpsert(true)) } else { @@ -354,7 +560,7 @@ func (tx *transaction) UpdateInventory(charId int32, raw map[string]interface{}) tx.gs.Logger.Println("new inventory", slots) _, _, err = tx.gs.mongoClient.Update("Inventory", - bson.M{"_id": playerid, "inven.charId": charId}, + bson.M{"_id": playerid, "inven.charSlotId": charSlotId}, bson.M{ "$currentDate": bson.M{"_ts": true}, "$set": bson.M{"inven.$.slots": slots}, @@ -370,7 +576,7 @@ func (tx *transaction) UpdateInventory(charId int32, raw map[string]interface{}) } } -func (tx *transaction) GetInventory(charId int32) shared.RPCReturnType { +func (tx *transaction) GetInventory(charSlotId int32) shared.RPCReturnType { var playerid string if v, ok := tx.r.Header["Player-Id"]; ok && len(v) > 0 { @@ -380,7 +586,7 @@ func (tx *transaction) GetInventory(charId int32) shared.RPCReturnType { } raw, err := tx.gs.mongoClient.FindOne("Inventory", - bson.M{"_id": playerid, "inven.charId": charId}, + bson.M{"_id": playerid, "inven.charSlotId": charSlotId}, options.FindOne().SetProjection(bson.M{"inven.$": 1})) if raw == nil { @@ -395,9 +601,9 @@ func (tx *transaction) GetInventory(charId int32) shared.RPCReturnType { bson.M{"_id": playerid}, bson.M{ "$currentDate": bson.M{"_ts": true}, - "$addToSet": bson.M{"inven": bson.M{"charId": charId, "slots": bson.M{}}}, + "$addToSet": bson.M{"inven": bson.M{"charSlotId": charSlotId, "slots": bson.M{}}}, }, - options.FindOneAndUpdate().SetProjection(bson.M{"inven": bson.M{"$elemMatch": bson.M{"charId": charId}}}), + options.FindOneAndUpdate().SetProjection(bson.M{"inven": bson.M{"$elemMatch": bson.M{"charSlotId": charSlotId}}}), options.FindOneAndUpdate().SetReturnDocument(options.After), options.FindOneAndUpdate().SetUpsert(true)) } @@ -413,7 +619,7 @@ func (tx *transaction) GetInventory(charId int32) shared.RPCReturnType { if err == nil { slots := raw["inven"].(bson.A)[0].(map[string]interface{})["slots"] - tx.gs.Logger.Println("inventory read : ", playerid, slots) + tx.gs.Logger.Println("inventory :", playerid, charSlotId, slots) return shared.MakeRPCReturn(slots, err) } else { return shared.MakeRPCReturn(nil, errors.New("not matched")) diff --git a/shared/server.go b/shared/server.go index 3d9c3c7..22d0d23 100644 --- a/shared/server.go +++ b/shared/server.go @@ -45,6 +45,7 @@ type functionCallContext struct { // RPCReturnType : RPC 호출 가능한 함수가 유일하게 리턴할 수 있는 타입 type RPCReturnType interface { Serialize(io.Writer) error + Value() interface{} Error() error } @@ -114,6 +115,11 @@ func (r rpcReturnTypeImpl) Error() error { return r.err } +// Error : RPCReturnType.Error 구현 +func (r rpcReturnTypeImpl) Value() interface{} { + return r.value.Interface() +} + // MakeRPCReturn : func MakeRPCReturn(value interface{}, err error) RPCReturnType { return rpcReturnTypeImpl{