쫓아내기 버그 수정 / 채팅 채널 expire되는 문제 수정

This commit is contained in:
2023-08-02 00:55:36 +09:00
parent 2b0e60a06a
commit 12ddd2cbfb
2 changed files with 86 additions and 32 deletions

View File

@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"time"
"github.com/go-redis/redis/v8"
@ -38,6 +39,16 @@ func makeTid(gid groupID, in accountID) string {
return out.Hex()
}
func midFromTid(gid groupID, in string) accountID {
h, _ := primitive.ObjectIDFromHex(in)
var out accountID
for i := range h {
out[12-i-1] = gid[i] ^ h[12-i-1]
}
return out
}
type Invitation struct {
GroupID groupID `json:"_gid"`
TicketID string `json:"_tid"`
@ -181,15 +192,33 @@ func (gd *groupDoc) addMember(mid accountID, doc bson.M) (bson.M, error) {
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()
return gd.loadMemberFull(tid)
}
func (gd *groupDoc) removeMember(mid accountID) error {
_, err := gd.rh.JSONDel(gd.strid(), "$._members."+gd.tid(mid))
func (gd *groupDoc) removeMemberByTid(tid string) error {
_, err := gd.rh.JSONDel(gd.strid(), "$._members."+tid)
if err != nil {
return err
}
counts, err := gd.rh.JSONObjLen(gd.strid(), "$._members")
if err != nil {
return err
}
if len(counts) > 0 && counts[0] == 0 {
_, err = gd.rh.Del(gd.rh.Context(), gd.strid()).Result()
}
return err
}
func (gd *groupDoc) removeMember(mid accountID) error {
return gd.removeMemberByTid(gd.tid(mid))
}
func (gd *groupDoc) getMembers() (map[string]any, error) {
res, err := gd.rh.JSONGet(gd.strid(), "$._members")
if err != nil {
@ -220,10 +249,10 @@ type partyConfig struct {
type groupParty struct {
partyConfig
sendUpstreamMessage func(*wshandler.UpstreamMessage)
enterRoom func(groupID, accountID)
leaveRoom func(groupID, accountID)
rh *gocommon.RedisonHandler
sendUpstreamMessage func(*wshandler.UpstreamMessage)
enterRoom func(groupID, accountID)
leaveRoom func(groupID, accountID)
rh *gocommon.RedisonHandler
}
func (gp *groupParty) Initialize(sub *subTavern, cfg configDocument) error {
@ -439,8 +468,7 @@ func (gp *groupParty) AcceptPartyInvitation(w http.ResponseWriter, r *http.Reque
w.WriteHeader(http.StatusInternalServerError)
return
}
cnt, err := gp.rh.Del(context.Background(), mid.Hex()).Result()
cnt, err := gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
if err != nil {
logger.Error("AcceptPartyInvitation failed. gp.rh.Del returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
@ -487,7 +515,7 @@ func (gp *groupParty) DenyPartyInvitation(w http.ResponseWriter, r *http.Request
gid, _ := gocommon.ReadObjectIDFormValue(r.Form, "gid")
mid, _ := gocommon.ReadObjectIDFormValue(r.Form, "mid")
gp.rh.Del(context.Background(), mid.Hex()).Result()
gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
gd := groupDoc{
id: gid,
rh: gp.rh,
@ -529,23 +557,58 @@ func (gp *groupParty) LeaveParty(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
return
}
tid, tidok := gocommon.ReadStringFormValue(r.Form, "tid")
gd := groupDoc{
id: gid,
rh: gp.rh,
}
if err := gd.removeMember(mid); err != nil {
var err error
if tidok {
if tid != gd.tid(mid) {
// mid가 incharge여야 한다. 그래야 tid를 쫓아낼 수 있음
incharge, err := gp.rh.JSONGet(gd.strid(), "$._incharge")
if err != nil {
logger.Println("LeaveParty failed. gp.rh.JSONGet returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if !strings.Contains(incharge.(string), gd.tid(mid)) {
// incharge가 아니네?
logger.Println("LeaveParty failed. mid is not incharge")
w.WriteHeader(http.StatusBadRequest)
return
}
mid = midFromTid(gd.id, tid)
}
err = gd.removeMemberByTid(tid)
} else {
err = gd.removeMember(mid)
}
if err != nil {
logger.Println("LeaveParty failed. gd.removeMember returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// 한테는 빈 GroupDocFull을 보낸다. 그러면 지워짐
// mid한테는 빈 GroupDocFull을 보낸다. 그러면 지워짐
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "@" + mid.Hex(),
Body: bson.M{"gid": gid},
Tag: []string{"GroupDocFull", gid.Hex()},
})
// gid에는 제거 메시지 보냄
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "#" + gd.strid(),
Body: bson.M{
tid: bson.M{},
},
Tag: []string{"MemberDocFull"},
})
gp.leaveRoom(gid, mid)
}
@ -722,18 +785,15 @@ func (gp *groupParty) memberDisconnected(room string, mid primitive.ObjectID) {
rh: gp.rh,
}
tid := gd.tid(mid)
deleted, _ := gp.rh.JSONDel(room, "$._members."+tid)
if deleted > 0 {
// 퇴장을 알림
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "#" + room,
Body: bson.M{
tid: bson.M{},
},
Tag: []string{"MemberDocFull"},
})
}
gd.removeMember(mid)
// 퇴장을 알림
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "#" + room,
Body: bson.M{
gd.tid(mid): bson.M{},
},
Tag: []string{"MemberDocFull"},
})
}
func (gp *groupParty) ClientMessageReceived(sender *wshandler.Sender, mt wshandler.WebSocketMessageType, message any) {