쫓아내기 버그 수정 / 채팅 채널 expire되는 문제 수정
This commit is contained in:
@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user