서버간 api 호출 간소화
This commit is contained in:
@ -1,56 +1,9 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
||||||
"repositories.action2quare.com/ayo/gocommon/wshandler"
|
"repositories.action2quare.com/ayo/gocommon/wshandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
var groupTypes map[string]reflect.Type
|
|
||||||
|
|
||||||
func groupTypeContainer() map[string]reflect.Type {
|
|
||||||
if groupTypes == nil {
|
|
||||||
groupTypes = make(map[string]reflect.Type)
|
|
||||||
}
|
|
||||||
return groupTypes
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiFuncType func(http.ResponseWriter, *http.Request)
|
|
||||||
type apiFuncsContainer struct {
|
|
||||||
normfuncs map[string]apiFuncType
|
|
||||||
funcs map[string][]apiFuncType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afc *apiFuncsContainer) registApiFunction(name string, f apiFuncType) {
|
|
||||||
afc.funcs[name] = append(afc.funcs[name], f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afc *apiFuncsContainer) normalize() {
|
|
||||||
for k, v := range afc.funcs {
|
|
||||||
if len(v) == 1 {
|
|
||||||
afc.normfuncs[k] = v[0]
|
|
||||||
} else {
|
|
||||||
afc.normfuncs[k] = func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
for _, f := range v {
|
|
||||||
f(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
afc.funcs = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afc *apiFuncsContainer) call(fn string, w http.ResponseWriter, r *http.Request) {
|
|
||||||
f := afc.normfuncs[fn]
|
|
||||||
if f != nil {
|
|
||||||
f(w, r)
|
|
||||||
} else {
|
|
||||||
logger.Println("api func is missing :", fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type configDocument map[string]any
|
type configDocument map[string]any
|
||||||
type group interface {
|
type group interface {
|
||||||
Initialize(*Tavern, configDocument) error
|
Initialize(*Tavern, configDocument) error
|
||||||
|
|||||||
@ -3,24 +3,17 @@ package core
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"repositories.action2quare.com/ayo/gocommon"
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
"repositories.action2quare.com/ayo/gocommon/wshandler"
|
"repositories.action2quare.com/ayo/gocommon/wshandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
groupTypeContainer()["chat"] = reflect.TypeOf(&groupChat{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type channelID = string
|
type channelID = string
|
||||||
type channelConfig struct {
|
type channelConfig struct {
|
||||||
Capacity int64 `json:"capacity"`
|
Capacity int64 `json:"capacity"`
|
||||||
@ -63,10 +56,6 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error {
|
|||||||
|
|
||||||
gc.rh = tv.redison
|
gc.rh = tv.redison
|
||||||
|
|
||||||
tv.apiFuncs.registApiFunction("FetchChattingChannels", gc.FetchChattingChannels)
|
|
||||||
tv.apiFuncs.registApiFunction("BroadcastMessageOnChannel", gc.BroadcastMessageOnChannel)
|
|
||||||
tv.apiFuncs.registApiFunction("QueryPlayerChattingChannel", gc.QueryPlayerChattingChannel)
|
|
||||||
tv.apiFuncs.registApiFunction("SendMessageOnChannel", gc.SendMessageOnChannel)
|
|
||||||
for name, cfg := range gc.chatConfig.Channels {
|
for name, cfg := range gc.chatConfig.Channels {
|
||||||
if cfg.Capacity == 0 {
|
if cfg.Capacity == 0 {
|
||||||
cfg.Capacity = gc.chatConfig.DefaultCapacity
|
cfg.Capacity = gc.chatConfig.DefaultCapacity
|
||||||
@ -223,7 +212,16 @@ func (gc *groupChat) ClientMessageReceived(sender *wshandler.Sender, mt wshandle
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gc *groupChat) FetchChattingChannels(w http.ResponseWriter, r *http.Request) {
|
func (gc *groupChat) FetchChattingChannels(w http.ResponseWriter, r *http.Request) {
|
||||||
prefix, _ := gocommon.ReadStringFormValue(r.URL.Query(), "prefix")
|
var data struct {
|
||||||
|
Prefix string `bson:"prefix"`
|
||||||
|
}
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("FetchChattingChannels failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := data.Prefix
|
||||||
if len(prefix) == 0 {
|
if len(prefix) == 0 {
|
||||||
logger.Println("FetchChattingChannel failed. prefix is missing")
|
logger.Println("FetchChattingChannel failed. prefix is missing")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
@ -269,8 +267,18 @@ func (gc *groupChat) FetchChattingChannels(w http.ResponseWriter, r *http.Reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gc *groupChat) QueryPlayerChattingChannel(w http.ResponseWriter, r *http.Request) {
|
func (gc *groupChat) QueryPlayerChattingChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
accid, _ := gocommon.ReadStringFormValue(r.URL.Query(), "accid")
|
var data struct {
|
||||||
typename, _ := gocommon.ReadStringFormValue(r.URL.Query(), "typename")
|
Accid string `bson:"accid"`
|
||||||
|
Typename string `bson:"typename"`
|
||||||
|
}
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("QueryPlayerChattingChannel failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
accid := data.Accid
|
||||||
|
typename := data.Typename
|
||||||
|
|
||||||
var fields []string
|
var fields []string
|
||||||
if len(typename) == 0 {
|
if len(typename) == 0 {
|
||||||
@ -298,60 +306,12 @@ func (gc *groupChat) QueryPlayerChattingChannel(w http.ResponseWriter, r *http.R
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gc *groupChat) SendMessageOnChannel(w http.ResponseWriter, r *http.Request) {
|
func (gc *groupChat) SendMessageOnChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
channel, _ := gocommon.ReadStringFormValue(r.URL.Query(), "channel")
|
var msg wshandler.UpstreamMessage
|
||||||
target, _ := gocommon.ReadStringFormValue(r.URL.Query(), "target")
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &msg); err != nil {
|
||||||
tag, _ := gocommon.ReadStringFormValue(r.URL.Query(), "tag")
|
logger.Println("SendMessageOnChannel failed. ReadBsonDocumentFromBody return err :", err)
|
||||||
if len(channel) == 0 || len(target) == 0 || len(tag) == 0 {
|
|
||||||
logger.Println("SendMessageOnChannel failed. channel or target or tag is empty")
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var doc map[string]any
|
gc.sendUpstreamMessage(&msg)
|
||||||
bt, err := io.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
logger.Println("SendMessageOnChannel failed. io.ReadAll returns err :", err)
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(bt) > 0 {
|
|
||||||
if err := bson.Unmarshal(bt, &doc); err != nil {
|
|
||||||
logger.Println("SendMessageOnChannel failed. decode returns err :", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
|
||||||
Target: fmt.Sprintf("%s@%s", target, channel),
|
|
||||||
Body: doc,
|
|
||||||
Tag: []string{tag},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gc *groupChat) BroadcastMessageOnChannel(w http.ResponseWriter, r *http.Request) {
|
|
||||||
nickname, _ := gocommon.ReadStringFormValue(r.URL.Query(), "nickname")
|
|
||||||
channel, _ := gocommon.ReadStringFormValue(r.URL.Query(), "channel")
|
|
||||||
tag, _ := gocommon.ReadStringFormValue(r.URL.Query(), "tag")
|
|
||||||
text, _ := io.ReadAll(r.Body)
|
|
||||||
|
|
||||||
if len(tag) > 0 {
|
|
||||||
var doc map[string]any
|
|
||||||
if err := bson.Unmarshal(text, &doc); err == nil {
|
|
||||||
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
|
||||||
Target: "#" + channel,
|
|
||||||
Body: doc,
|
|
||||||
Tag: []string{tag},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
logger.Println("BroadcastMessageOnChannel failed :", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
|
||||||
Target: "#" + channel,
|
|
||||||
Body: map[string]any{"sender": nickname, "msg": string(text)},
|
|
||||||
Tag: []string{"TextMessage"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,9 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/gob"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -22,15 +20,6 @@ import (
|
|||||||
type accountID = primitive.ObjectID
|
type accountID = primitive.ObjectID
|
||||||
type groupID = primitive.ObjectID
|
type groupID = primitive.ObjectID
|
||||||
|
|
||||||
func init() {
|
|
||||||
gob.Register(memberDoc{})
|
|
||||||
gob.Register(groupDoc{})
|
|
||||||
gob.Register(Invitation{})
|
|
||||||
gob.Register(InvitationFail{})
|
|
||||||
|
|
||||||
groupTypeContainer()["party"] = reflect.TypeOf(&groupParty{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeTid(gid groupID, in accountID) string {
|
func makeTid(gid groupID, in accountID) string {
|
||||||
var out primitive.ObjectID
|
var out primitive.ObjectID
|
||||||
for i := range in {
|
for i := range in {
|
||||||
@ -127,9 +116,9 @@ func (gd *groupDoc) mid(tid string) accountID {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gd *groupDoc) addInvite(inviteeDoc bson.M, ttl time.Duration, max int) (*memberDoc, error) {
|
func (gd *groupDoc) addInvite(mid accountID, body bson.M, ttl time.Duration, max int) (*memberDoc, error) {
|
||||||
targetmid := inviteeDoc["_mid"].(accountID)
|
targetmid := mid
|
||||||
targetbody := inviteeDoc["body"].(bson.M)
|
targetbody := body
|
||||||
|
|
||||||
// 초대 가능한 빈 자리가 있나
|
// 초대 가능한 빈 자리가 있나
|
||||||
tids, err := gd.rh.JSONObjKeys(gd.strid(), "$._members")
|
tids, err := gd.rh.JSONObjKeys(gd.strid(), "$._members")
|
||||||
@ -181,11 +170,11 @@ func (gd *groupDoc) addInvite(inviteeDoc bson.M, ttl time.Duration, max int) (*m
|
|||||||
return newdoc, err
|
return newdoc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gd *groupDoc) addMember(mid accountID, doc bson.M) (bson.M, error) {
|
func (gd *groupDoc) addMember(mid accountID, character bson.M) (bson.M, error) {
|
||||||
tid := gd.tid(mid)
|
tid := gd.tid(mid)
|
||||||
prefix := "$._members." + tid
|
prefix := "$._members." + tid
|
||||||
|
|
||||||
if _, err := gd.rh.JSONMerge(gd.strid(), prefix+"._body", doc, gocommon.RedisonSetOptionXX); err != nil {
|
if _, err := gd.rh.JSONMerge(gd.strid(), prefix+"._body", character, gocommon.RedisonSetOptionXX); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,15 +262,15 @@ func (gp *groupParty) Initialize(tv *Tavern, cfg configDocument) error {
|
|||||||
tv.wsh.LeaveRoom(gid.Hex(), accid)
|
tv.wsh.LeaveRoom(gid.Hex(), accid)
|
||||||
}
|
}
|
||||||
|
|
||||||
tv.apiFuncs.registApiFunction("JoinParty", gp.JoinParty)
|
// tv.apiFuncs.registApiFunction("JoinParty", gp.JoinParty)
|
||||||
tv.apiFuncs.registApiFunction("InviteToParty", gp.InviteToParty)
|
// tv.apiFuncs.registApiFunction("InviteToParty", gp.InviteToParty)
|
||||||
tv.apiFuncs.registApiFunction("AcceptPartyInvitation", gp.AcceptPartyInvitation)
|
// tv.apiFuncs.registApiFunction("AcceptPartyInvitation", gp.AcceptPartyInvitation)
|
||||||
tv.apiFuncs.registApiFunction("DenyPartyInvitation", gp.DenyPartyInvitation)
|
// tv.apiFuncs.registApiFunction("DenyPartyInvitation", gp.DenyPartyInvitation)
|
||||||
tv.apiFuncs.registApiFunction("QueryPartyMemberState", gp.QueryPartyMemberState)
|
// tv.apiFuncs.registApiFunction("QueryPartyMemberState", gp.QueryPartyMemberState)
|
||||||
tv.apiFuncs.registApiFunction("LeaveParty", gp.LeaveParty)
|
// tv.apiFuncs.registApiFunction("LeaveParty", gp.LeaveParty)
|
||||||
tv.apiFuncs.registApiFunction("UpdatePartyMemberDocument", gp.UpdatePartyMemberDocument)
|
// tv.apiFuncs.registApiFunction("UpdatePartyMemberDocument", gp.UpdatePartyMemberDocument)
|
||||||
tv.apiFuncs.registApiFunction("UpdatePartyDocument", gp.UpdatePartyDocument)
|
// tv.apiFuncs.registApiFunction("UpdatePartyDocument", gp.UpdatePartyDocument)
|
||||||
tv.apiFuncs.registApiFunction("QueryPartyMembers", gp.QueryPartyMembers)
|
// tv.apiFuncs.registApiFunction("QueryPartyMembers", gp.QueryPartyMembers)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -296,20 +285,22 @@ func (gp *groupParty) RegisterApiFunctions() {
|
|||||||
// - member_id : 참가 멤버의 아이디
|
// - member_id : 참가 멤버의 아이디
|
||||||
// - body : 멤버의 속성 bson document
|
// - body : 멤버의 속성 bson document
|
||||||
func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) {
|
||||||
doc := bson.M{}
|
var data struct {
|
||||||
if err := readBsonDoc(r.Body, &doc); err != nil {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Error("JoinParty failed. readBsonDoc returns err :", err)
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
Character bson.M `bson:"character"`
|
||||||
|
}
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("JoinParty failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
|
||||||
if !ok {
|
doc := data.Character
|
||||||
logger.Println("JoinParty failed. gid is missing :", r.URL.Query())
|
gid := data.Gid
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
mid := data.Mid
|
||||||
return
|
|
||||||
}
|
if gid.IsZero() || mid.IsZero() {
|
||||||
mid, midok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
|
||||||
if !midok {
|
|
||||||
logger.Println("JoinParty failed. mid should be exist")
|
logger.Println("JoinParty failed. mid should be exist")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
@ -328,7 +319,7 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 내 정보 업데이트할 때에도 사용됨
|
// 내 정보 업데이트할 때에도 사용됨
|
||||||
if memdoc, err := gd.addMember(mid, doc); err == nil {
|
if memdoc, err := gd.addMember(mid, doc["character"].(map[string]any)); err == nil {
|
||||||
// 기존 유저에게 새 유저 알림
|
// 기존 유저에게 새 유저 알림
|
||||||
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
||||||
Target: "#" + gid.Hex(),
|
Target: "#" + gid.Hex(),
|
||||||
@ -363,35 +354,23 @@ func (gp *groupParty) JoinParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
// - timeout : 초대 유지시간(optional. 없으면 config 기본 값)
|
// - timeout : 초대 유지시간(optional. 없으면 config 기본 값)
|
||||||
// - (body) : 검색시 노출되는 document
|
// - (body) : 검색시 노출되는 document
|
||||||
func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var doc struct {
|
||||||
if !ok {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Println("InviteToParty failed. gid is missing :", r)
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
Targetid primitive.ObjectID `bson:"targetid"`
|
||||||
return
|
Inviter bson.M `bson:"inviter"`
|
||||||
}
|
Invitee bson.M `bson:"invitee"`
|
||||||
mid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
|
||||||
if !ok {
|
|
||||||
logger.Println("InviteToParty failed. mid is missing :", r)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var reqdoc struct {
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &doc); err != nil {
|
||||||
Inviter bson.M `bson:"inviter"`
|
logger.Println("InviteToParty failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
Invitee bson.M `bson:"invitee"`
|
|
||||||
}
|
|
||||||
if err := readBsonDoc(r.Body, &reqdoc); err != nil {
|
|
||||||
logger.Println("InviteToParty failed. readBsonDoc returns err :", err)
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
targetid, ok := reqdoc.Invitee["_mid"].(accountID)
|
targetid := doc.Targetid
|
||||||
if !ok {
|
gid := doc.Gid
|
||||||
logger.Println("InviteToParty failed. invitee mid is missing :", r)
|
mid := doc.Mid
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// targetid에 초대한 mid가 들어있다.
|
// targetid에 초대한 mid가 들어있다.
|
||||||
success, err := gp.rh.SetNX(context.Background(), "inv."+targetid.Hex(), mid.Hex(), time.Duration(gp.InviteExpire)*time.Second).Result()
|
success, err := gp.rh.SetNX(context.Background(), "inv."+targetid.Hex(), mid.Hex(), time.Duration(gp.InviteExpire)*time.Second).Result()
|
||||||
@ -406,7 +385,7 @@ func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
// inviter한테 알려줘야 한다.
|
// inviter한테 알려줘야 한다.
|
||||||
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
gp.sendUpstreamMessage(&wshandler.UpstreamMessage{
|
||||||
Target: mid.Hex(),
|
Target: mid.Hex(),
|
||||||
Body: reqdoc.Invitee,
|
Body: doc.Invitee,
|
||||||
Tag: []string{"InvitationFail"},
|
Tag: []string{"InvitationFail"},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -420,7 +399,7 @@ func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if gd == nil {
|
if gd == nil {
|
||||||
gd, err = gp.createGroup(gid, mid, reqdoc.Inviter)
|
gd, err = gp.createGroup(gid, mid, doc.Inviter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Println("InviteToParty failed. gp.createGroup() return err :", err)
|
logger.Println("InviteToParty failed. gp.createGroup() return err :", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
@ -436,7 +415,7 @@ func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
newdoc, err := gd.addInvite(reqdoc.Invitee, time.Duration(gp.InviteExpire+1)*time.Second, gp.MaxMember)
|
newdoc, err := gd.addInvite(targetid, doc.Invitee, time.Duration(gp.InviteExpire+1)*time.Second, gp.MaxMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Println("InviteToParty failed. gp.addInvite() return err :", err)
|
logger.Println("InviteToParty failed. gp.addInvite() return err :", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
@ -449,7 +428,7 @@ func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
Body: Invitation{
|
Body: Invitation{
|
||||||
GroupID: gid,
|
GroupID: gid,
|
||||||
TicketID: gd.tid(targetid),
|
TicketID: gd.tid(targetid),
|
||||||
Inviter: reqdoc.Inviter,
|
Inviter: doc.Inviter,
|
||||||
ExpireAtUTC: newdoc.InviteExpire,
|
ExpireAtUTC: newdoc.InviteExpire,
|
||||||
},
|
},
|
||||||
Tag: []string{"Invitation"},
|
Tag: []string{"Invitation"},
|
||||||
@ -459,15 +438,22 @@ func (gp *groupParty) InviteToParty(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) AcceptPartyInvitation(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) AcceptPartyInvitation(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, _ := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var doc struct {
|
||||||
mid, _ := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
var member bson.M
|
Tid string `bson:"tid"`
|
||||||
if err := readBsonDoc(r.Body, &member); err != nil {
|
Character bson.M `bson:"character"`
|
||||||
logger.Error("AcceptPartyInvitation failed. readBsonDoc returns err :", err)
|
}
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &doc); err != nil {
|
||||||
|
logger.Println("AcceptPartyInvitation failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gid := doc.Gid
|
||||||
|
mid := doc.Mid
|
||||||
|
member := doc.Character
|
||||||
|
|
||||||
cnt, err := gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
|
cnt, err := gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("AcceptPartyInvitation failed. gp.rh.Del returns err :", err)
|
logger.Error("AcceptPartyInvitation failed. gp.rh.Del returns err :", err)
|
||||||
@ -543,8 +529,19 @@ func (gp *groupParty) AcceptPartyInvitation(w http.ResponseWriter, r *http.Reque
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) DenyPartyInvitation(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) DenyPartyInvitation(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, _ := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var data struct {
|
||||||
mid, _ := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("DenyPartyInvitation failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
gid := data.Gid
|
||||||
|
mid := data.Mid
|
||||||
|
|
||||||
gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
|
gp.rh.Del(context.Background(), "inv."+mid.Hex()).Result()
|
||||||
gd := groupDoc{
|
gd := groupDoc{
|
||||||
@ -555,14 +552,18 @@ func (gp *groupParty) DenyPartyInvitation(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) QueryPartyMemberState(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) QueryPartyMemberState(w http.ResponseWriter, r *http.Request) {
|
||||||
mid, ok := gocommon.ReadStringFormValue(r.URL.Query(), "mid")
|
var data struct {
|
||||||
if !ok {
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
logger.Println("IsOnline failed. mid is missing :", r.URL.Query())
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
states, err := gp.rh.JSONGetString(mid, "$.party.state")
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("DenyPartyInvitation failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mid := data.Mid
|
||||||
|
|
||||||
|
states, err := gp.rh.JSONGetString(mid.Hex(), "$.party.state")
|
||||||
if err == redis.Nil {
|
if err == redis.Nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -579,26 +580,28 @@ func (gp *groupParty) QueryPartyMemberState(w http.ResponseWriter, r *http.Reque
|
|||||||
// - 그룹 타입에 맞는 키(주로 _id)
|
// - 그룹 타입에 맞는 키(주로 _id)
|
||||||
// - member_id : 나갈 멤버의 아이디
|
// - member_id : 나갈 멤버의 아이디
|
||||||
func (gp *groupParty) LeaveParty(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) LeaveParty(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var data struct {
|
||||||
if !ok {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Println("LeaveParty failed. gid is missing :", r.URL.Query())
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
Tid string `bson:"tid"`
|
||||||
|
}
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("LeaveParty failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mid, midok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
|
||||||
if !midok {
|
gid := data.Gid
|
||||||
logger.Println("LeaveParty failed. mid is missing")
|
mid := data.Mid
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
tid := data.Tid
|
||||||
return
|
|
||||||
}
|
|
||||||
tid, tidok := gocommon.ReadStringFormValue(r.URL.Query(), "tid")
|
|
||||||
gd := groupDoc{
|
gd := groupDoc{
|
||||||
id: gid,
|
id: gid,
|
||||||
rh: gp.rh,
|
rh: gp.rh,
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if tidok {
|
if len(tid) > 0 {
|
||||||
if tid != gd.tid(mid) {
|
if tid != gd.tid(mid) {
|
||||||
// mid가 incharge여야 한다. 그래야 tid를 쫓아낼 수 있음
|
// mid가 incharge여야 한다. 그래야 tid를 쫓아낼 수 있음
|
||||||
incharge, err := gp.rh.JSONGet(gd.strid(), "$._incharge")
|
incharge, err := gp.rh.JSONGet(gd.strid(), "$._incharge")
|
||||||
@ -674,26 +677,21 @@ func (gp *groupParty) updateMemberDocument(gid groupID, mid accountID, doc bson.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) UpdatePartyMemberDocument(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) UpdatePartyMemberDocument(w http.ResponseWriter, r *http.Request) {
|
||||||
mid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "mid")
|
var data struct {
|
||||||
if !ok {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Println("UpdatePartyMemberDocument failed. member_id is missing")
|
Mid primitive.ObjectID `bson:"mid"`
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
Doc bson.M `bson:"doc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("UpdatePartyMemberDocument failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
mid := data.Mid
|
||||||
if !ok {
|
gid := data.Gid
|
||||||
logger.Println("UpdatePartyMemberDocument failed. _id is missing")
|
updatedoc := data.Doc
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var updatedoc bson.M
|
|
||||||
if err := readBsonDoc(r.Body, &updatedoc); err != nil {
|
|
||||||
logger.Error("UpdatePartyMemberDocument failed. body decoding error :", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gp.updateMemberDocument(gid, mid, updatedoc); err != nil {
|
if err := gp.updateMemberDocument(gid, mid, updatedoc); err != nil {
|
||||||
logger.Println("UpdatePartyMemberDocument failed :", err)
|
logger.Println("UpdatePartyMemberDocument failed :", err)
|
||||||
@ -720,19 +718,19 @@ func (gp *groupParty) updatePartyDocument(gid groupID, frag bson.M) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) UpdatePartyDocument(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) UpdatePartyDocument(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var data struct {
|
||||||
if !ok {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Println("UpdatePartyDocument failed. gid is missing")
|
Doc bson.M `bson:"doc"`
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
}
|
||||||
|
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("UpdatePartyDocument failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var frag bson.M
|
gid := data.Gid
|
||||||
if err := readBsonDoc(r.Body, &frag); err != nil {
|
frag := data.Doc
|
||||||
logger.Error("UpdatePartyDocument failed. readBsonDoc err :", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gp.updatePartyDocument(gid, frag); err != nil {
|
if err := gp.updatePartyDocument(gid, frag); err != nil {
|
||||||
logger.Error("UpdatePartyDocument failed. group.UpdatePartyDocument returns err :", err)
|
logger.Error("UpdatePartyDocument failed. group.UpdatePartyDocument returns err :", err)
|
||||||
@ -742,13 +740,17 @@ func (gp *groupParty) UpdatePartyDocument(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gp *groupParty) QueryPartyMembers(w http.ResponseWriter, r *http.Request) {
|
func (gp *groupParty) QueryPartyMembers(w http.ResponseWriter, r *http.Request) {
|
||||||
gid, ok := gocommon.ReadObjectIDFormValue(r.URL.Query(), "gid")
|
var data struct {
|
||||||
if !ok {
|
Gid primitive.ObjectID `bson:"gid"`
|
||||||
logger.Println("QueryPartyMembers failed. gid is missing")
|
}
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
|
if err := gocommon.ReadBsonDocumentFromBody(r.Body, &data); err != nil {
|
||||||
|
logger.Println("QueryPartyMembers failed. ReadBsonDocumentFromBody returns err :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gid := data.Gid
|
||||||
gd := groupDoc{
|
gd := groupDoc{
|
||||||
id: gid,
|
id: gid,
|
||||||
rh: gp.rh,
|
rh: gp.rh,
|
||||||
|
|||||||
@ -4,11 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -39,29 +37,6 @@ func writeBsonDoc[T any](w io.Writer, src T) error {
|
|||||||
return enc.Encode(src)
|
return enc.Encode(src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readBsonDoc(r io.Reader, src any) error {
|
|
||||||
body, err := io.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(body) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = decoder.Decode(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type TavernConfig struct {
|
type TavernConfig struct {
|
||||||
session.SessionConfig `json:",inline"`
|
session.SessionConfig `json:",inline"`
|
||||||
gocommon.StorageAddr `json:"storage"`
|
gocommon.StorageAddr `json:"storage"`
|
||||||
@ -75,11 +50,11 @@ type TavernConfig struct {
|
|||||||
var config TavernConfig
|
var config TavernConfig
|
||||||
|
|
||||||
type Tavern struct {
|
type Tavern struct {
|
||||||
wsh *wshandler.WebsocketHandler
|
wsh *wshandler.WebsocketHandler
|
||||||
mongoClient gocommon.MongoClient
|
mongoClient gocommon.MongoClient
|
||||||
redison *gocommon.RedisonHandler
|
redison *gocommon.RedisonHandler
|
||||||
groups map[string]group
|
groups map[string]group
|
||||||
apiFuncs *apiFuncsContainer
|
apiReceivers gocommon.HttpApiHandlerContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMacAddr() (string, error) {
|
func getMacAddr() (string, error) {
|
||||||
@ -116,10 +91,6 @@ func New(context context.Context, wsh *wshandler.WebsocketHandler, inconfig *Tav
|
|||||||
config.macAddr = macaddr
|
config.macAddr = macaddr
|
||||||
tv := &Tavern{
|
tv := &Tavern{
|
||||||
wsh: wsh,
|
wsh: wsh,
|
||||||
apiFuncs: &apiFuncsContainer{
|
|
||||||
normfuncs: make(map[string]apiFuncType),
|
|
||||||
funcs: make(map[string][]apiFuncType),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tv.prepare(context); err != nil {
|
if err = tv.prepare(context); err != nil {
|
||||||
@ -143,25 +114,24 @@ func (tv *Tavern) prepare(ctx context.Context) error {
|
|||||||
tv.redison = gocommon.NewRedisonHandler(redisClient.Context(), redisClient)
|
tv.redison = gocommon.NewRedisonHandler(redisClient.Context(), redisClient)
|
||||||
|
|
||||||
groups := make(map[string]group)
|
groups := make(map[string]group)
|
||||||
for typename, cfg := range config.Group {
|
if cfg, ok := config.Group["chat"]; ok {
|
||||||
gtype, ok := groupTypeContainer()[typename]
|
chat := new(groupChat)
|
||||||
if !ok {
|
if err := chat.Initialize(tv, cfg); err != nil {
|
||||||
return fmt.Errorf("%s group type is not valid", typename)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !gtype.Implements(reflect.TypeOf((*group)(nil)).Elem()) {
|
|
||||||
return fmt.Errorf("%s is not implement proper interface", typename)
|
|
||||||
}
|
|
||||||
ptrvalue := reflect.New(gtype.Elem())
|
|
||||||
instance := ptrvalue.Interface().(group)
|
|
||||||
if err := instance.Initialize(tv, cfg); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groups[typename] = instance
|
tv.apiReceivers.RegistReceiver(gocommon.MakeHttpApiReceiver(chat, "chat"))
|
||||||
|
groups["chat"] = chat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg, ok := config.Group["party"]; ok {
|
||||||
|
party := new(groupParty)
|
||||||
|
if err := party.Initialize(tv, cfg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tv.apiReceivers.RegistReceiver(gocommon.MakeHttpApiReceiver(party, "party"))
|
||||||
|
groups["party"] = party
|
||||||
|
}
|
||||||
tv.groups = groups
|
tv.groups = groups
|
||||||
tv.apiFuncs.normalize()
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -259,11 +229,12 @@ func (tv *Tavern) api(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
operation := r.URL.Query().Get("operation")
|
funcname := r.URL.Query().Get("call")
|
||||||
if len(operation) == 0 {
|
if len(funcname) == 0 {
|
||||||
|
logger.Println("query param 'call' is missing")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tv.apiFuncs.call(operation, w, r)
|
tv.apiReceivers.Call(funcname, w, r)
|
||||||
}
|
}
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.20
|
|||||||
require (
|
require (
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
go.mongodb.org/mongo-driver v1.11.7
|
go.mongodb.org/mongo-driver v1.11.7
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904053533-821dc5c639d8
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905074334-7951814f125d
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
16
go.sum
16
go.sum
@ -160,3 +160,19 @@ repositories.action2quare.com/ayo/gocommon v0.0.0-20230904005440-d396a35713ad h1
|
|||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904005440-d396a35713ad/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904005440-d396a35713ad/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904053533-821dc5c639d8 h1:clQB7s726Rt/q2BgGjZMVjek7Z0YDBUrD4HjFKUFSIw=
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904053533-821dc5c639d8 h1:clQB7s726Rt/q2BgGjZMVjek7Z0YDBUrD4HjFKUFSIw=
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904053533-821dc5c639d8/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230904053533-821dc5c639d8/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905024342-84f56dfc505c h1:Db+5nxlTu9W7qM0DApVqpG+y2MimlOz02FgTza291Jw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905024342-84f56dfc505c/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905025653-511784774009 h1:GtedcdVrlMY9CFbd6BoayjgFRwR/pbNPngZfAZ7Ublg=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905025653-511784774009/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905030636-def9494dd387 h1:lx9zDFycfr1703qszt9YLz8lae79gpu4tGe+kX41bG4=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905030636-def9494dd387/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905032825-8877bf88c0b7 h1:PkQS5X4t610gxGQD1AYklb2zH2bOUM9HLZowNnPPqlY=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905032825-8877bf88c0b7/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905045203-0762d9311b90 h1:AiG+6UG9vxiDsaTI8c6mPd53qIhon9T3C93jvQ4paAY=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905045203-0762d9311b90/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905054212-7489fa657a86 h1:WtjuPV28reK4RZgWHYH98ggUL6u/yxpaZzGgCvYY7so=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905054212-7489fa657a86/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905060206-3a3839a46187 h1:x+/G4jg2YwOdTmT4rHEw/RVaaxAc38CN8woWP9L/eZY=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905060206-3a3839a46187/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905074334-7951814f125d h1:zvTbz/14pdfjpSpczpSOcRCBZKY8agFILxL/QrIJngQ=
|
||||||
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20230905074334-7951814f125d/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=
|
||||||
|
|||||||
Reference in New Issue
Block a user