diff --git a/core/group_party.go b/core/group_party.go index b50f530..abe3660 100644 --- a/core/group_party.go +++ b/core/group_party.go @@ -176,16 +176,22 @@ func (gd *partyDoc) addInvite(mid accountID, body bson.M, ttl time.Duration, max return newdoc, err } -func (gd *partyDoc) addMember(mid accountID, character bson.M) (bson.M, error) { +func (gd *partyDoc) addMember(mid accountID, character bson.M, option string) (bson.M, error) { tid := gd.tid(mid) prefix := "$._members." + tid - if _, err := gd.rh.JSONSet(gd.strid(), prefix+"._body", character, gocommon.RedisonSetOptionXX); err != nil { - return nil, err - } + if option == gocommon.RedisonSetOptionNX { + if _, err := gd.rh.JSONSet(gd.strid(), prefix, bson.M{"_body": character}, gocommon.RedisonSetOptionNX); err != nil { + return nil, err + } + } else { + if _, err := gd.rh.JSONSet(gd.strid(), prefix+"._body", character, gocommon.RedisonSetOptionXX); err != nil { + return nil, err + } - if err := gd.rh.JSONMDel(gd.strid(), []string{prefix + "._invite", prefix + "._invite_exp"}); err != nil { - return nil, err + if err := gd.rh.JSONMDel(gd.strid(), []string{prefix + "._invite", prefix + "._invite_exp"}); err != nil { + return nil, err + } } gd.rh.Persist(gd.rh.Context(), gd.strid()).Result() @@ -276,6 +282,7 @@ func (gp *groupParty) Initialize(tv *Tavern, cfg configDocument) error { tv.wsh.EnterRoom(gid.Hex(), accid) } gp.leaveRoom = func(gid groupID, accid accountID) { + gp.rh.JSONDel(accid.Hex(), "$.party.state") tv.wsh.LeaveRoom(gid.Hex(), accid) } @@ -291,8 +298,8 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) { var data struct { Gid primitive.ObjectID Mid primitive.ObjectID - First bool Character bson.M + Option string } if err := gocommon.MakeDecoder(r).Decode(&data); err != nil { logger.Println("JoinParty failed. DecodeGob returns err :", err) @@ -300,9 +307,12 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) { return } + // Option : ["NX" | "XX" | ""] + character := data.Character gid := data.Gid mid := data.Mid + option := strings.ToUpper(data.Option) if gid.IsZero() || mid.IsZero() { logger.Println("JoinParty failed. mid should be exist") @@ -323,7 +333,7 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) { } // 내 정보 업데이트할 때에도 사용됨 - if !data.First { + if option == "XX" { // 이미 멤버여야 재입장 가능 path := "$._members." + gd.tid(mid) + "._body" if _, err := gd.rh.JSONSet(gd.strid(), path, character, gocommon.RedisonSetOptionXX); err != nil { @@ -334,7 +344,7 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) { } gp.rh.JSONSet(mid.Hex(), "$.party", bson.M{"id": gid.Hex()}) - memdoc, err := gd.addMember(mid, character) + memdoc, err := gd.addMember(mid, character, option) if err != nil { logger.Println("JoinParty failed :", err) w.WriteHeader(http.StatusInternalServerError) @@ -361,6 +371,26 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) { gocommon.MakeEncoder(w, r).Encode(gd.strid()) } +func (gp *groupParty) ForceClearPartyMember(w http.ResponseWriter, r *http.Request) { + var doc struct { + Gid primitive.ObjectID + Mid primitive.ObjectID + } + + if err := gocommon.MakeDecoder(r).Decode(&doc); err != nil { + logger.Println("ConditionalClearPartyMember failed. DecodeGob returns err :", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + gd := partyDoc{ + id: doc.Gid, + rh: gp.rh, + } + + gd.removeMember(doc.Mid) +} + func (gp *groupParty) ConditionalClearPartyMember(w http.ResponseWriter, r *http.Request) { var doc struct { Gid string @@ -604,7 +634,7 @@ func (gp *groupParty) AcceptPartyInvitation(w http.ResponseWriter, r *http.Reque rh: gp.rh, } - memberDoc, err := gd.addMember(mid, member) + memberDoc, err := gd.addMember(mid, member, "XX") if err == nil { // 기존 멤버에게 새 멤버를 알림 gp.sendUpstreamMessage(&wshandler.UpstreamMessage{