diff --git a/core/AEGS_methods.go b/core/AEGS_methods.go index 4adf3cb..ec01da8 100644 --- a/core/AEGS_methods.go +++ b/core/AEGS_methods.go @@ -251,6 +251,25 @@ func (tx *transaction) WriteDB(collection string, raw map[string]interface{}) sh return shared.MakeRPCReturn(nil, err) } +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) +} + 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}}) @@ -296,6 +315,14 @@ func (tx *transaction) RemoveCharInfo(charSlotId int32) shared.RPCReturnType { bson.M{"$pull": bson.M{"charInfo": bson.M{"slotId": charSlotId}}}, ) + if err == nil { + _, err = tx.gs.mongoClient.FindOneAndUpdate( + "Inventory", + bson.M{"_id": playerid}, + bson.M{"$pull": bson.M{"inven": bson.M{"charSlotId": charSlotId}}}, + ) + } + if err == nil { return shared.MakeRPCReturn("update success", err) } else { @@ -317,11 +344,11 @@ func (tx *transaction) UpdateCharInfo(charSlotId int32, raw map[string]interface 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 + var info map[string]interface{} - tx.gs.Logger.Println("new info", info) + if q == nil { + info = raw + info["slotId"] = charSlotId _, _, err = tx.gs.mongoClient.Update("PlayerInfo", bson.M{"_id": playerid}, @@ -331,7 +358,7 @@ func (tx *transaction) UpdateCharInfo(charSlotId int32, raw map[string]interface }, options.Update().SetUpsert(true)) } else { - info := q["charInfo"].(bson.A)[0].(map[string]interface{}) + info = q["charInfo"].(bson.A)[0].(map[string]interface{}) tx.gs.Logger.Println("current info", info) for k, v := range raw { @@ -341,8 +368,6 @@ func (tx *transaction) UpdateCharInfo(charSlotId int32, raw map[string]interface 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{ @@ -351,6 +376,8 @@ func (tx *transaction) UpdateCharInfo(charSlotId int32, raw map[string]interface }) } + tx.gs.Logger.Println("new info", info) + // _, _, err := tx.gs.mongoClient.Update("PlayerInfo", // bson.M{"_id": playerid}, // bson.M{ @@ -359,7 +386,7 @@ func (tx *transaction) UpdateCharInfo(charSlotId int32, raw map[string]interface // }, options.Update().SetUpsert(true)) if err == nil { - return shared.MakeRPCReturn("update success", err) + return shared.MakeRPCReturn(info, err) } else { return shared.MakeRPCReturn(nil, errors.New("invalid body")) } diff --git a/shared/server.go b/shared/server.go index 22d0d23..20687fe 100644 --- a/shared/server.go +++ b/shared/server.go @@ -117,7 +117,10 @@ func (r rpcReturnTypeImpl) Error() error { // Error : RPCReturnType.Error 구현 func (r rpcReturnTypeImpl) Value() interface{} { - return r.value.Interface() + if r.value.IsValid() { + return r.value.Interface() + } + return nil } // MakeRPCReturn : @@ -301,6 +304,7 @@ func ConvertInterface(from interface{}, toType reflect.Type) reflect.Value { // ErrUnmarshalRequestFailed : var ErrUnmarshalRequestFailed = errors.New("Unmarshal failed at rpc handler") +var ErrInvalidContext = errors.New("Invalid context") // CallMethodInternal : func CallMethodInternal(receiver interface{}, context functionCallContext) (interface{}, error) { @@ -351,6 +355,37 @@ func CallMethodInternal(receiver interface{}, context functionCallContext) (inte return nil, errors.New(fmt.Sprint("method is missing :", receiver, context.Method)) } +func CallMethodWithInterface(receiver interface{}, context interface{}) (retval RPCReturnType, err error) { + + if context2, ok := context.(map[string]interface{}); ok { + var meta functionCallContext + if method, ok2 := context2["Method"].(string); ok2 { + meta.Method = method + } else { + return nil, ErrInvalidContext + } + + if args, ok2 := context2["Args"].([]interface{}); ok2 { + meta.Args = args + } else { + return nil, ErrInvalidContext + } + + if v, err := CallMethodInternal(receiver, meta); err == nil { + if cast, ok := v.(RPCReturnType); ok { + if cast.Error() != nil { + return nil, cast.Error() + } + return cast, nil + } else { + return nil, errors.New(fmt.Sprint("method should return only RPCReturnType", meta)) + } + } + } + + return nil, ErrInvalidContext +} + // CallMethod : func CallMethod(receiver interface{}, context []byte) (retval RPCReturnType, err error) { defer func() { @@ -361,27 +396,30 @@ func CallMethod(receiver interface{}, context []byte) (retval RPCReturnType, err } }() - var meta functionCallContext - if err := json.Unmarshal(context, &meta); err != nil { + var raw interface{} + if err := json.Unmarshal(context, &raw); err != nil { fmt.Println(string(context)) return nil, ErrUnmarshalRequestFailed - } else { - fmt.Printf("%+v\n", meta) } - var v interface{} - v, err = CallMethodInternal(receiver, meta) - if err != nil { - return nil, err - } + if meta, ok := raw.(map[string]interface{}); ok { - // v는 RPCReturnType이어야 한다. - if cast, ok := v.(RPCReturnType); ok { - if cast.Error() != nil { - return nil, cast.Error() + if methods, ok := meta["Methods"].([]interface{}); ok { + // calling cascaded methods + body := make([]interface{}, 0, len(methods)) + + for _, meta2 := range methods { + if cast, err := CallMethodWithInterface(receiver, meta2.(map[string]interface{})); err == nil { + body = append(body, cast.Value()) + continue + } + return MakeRPCReturn(nil, err), err + } + return MakeRPCReturn(body, nil), nil + } else { + return CallMethodWithInterface(receiver, meta) } - return cast, nil } - return nil, errors.New(fmt.Sprint("method should return only RPCReturnType", meta)) + return nil, errors.New("Invalid context") }