From a503fe7f304fd84ca96f82ec039e902d9cb149d3 Mon Sep 17 00:00:00 2001 From: mountain Date: Mon, 8 Jan 2024 20:22:54 +0900 Subject: [PATCH] =?UTF-8?q?voice=20chat=EC=9D=84=20gocommon=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=98=AE=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/group_voice.go | 227 -------------------------------------------- 1 file changed, 227 deletions(-) delete mode 100644 core/group_voice.go diff --git a/core/group_voice.go b/core/group_voice.go deleted file mode 100644 index 903adb3..0000000 --- a/core/group_voice.go +++ /dev/null @@ -1,227 +0,0 @@ -package core - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "sync/atomic" - "time" - "unsafe" - - "github.com/gorilla/websocket" - "repositories.action2quare.com/ayo/gocommon" - "repositories.action2quare.com/ayo/gocommon/logger" - "repositories.action2quare.com/ayo/gocommon/wshandler" -) - -type eosauth struct { - AccessToken string `json:"access_token"` - ExpiresAt time.Time `json:"expires_at"` - ExpiresIn int64 `json:"expires_in"` - DeploymentId string `json:"deployment_id"` - ProductId string `json:"product_id"` - SandboxId string `json:"sandbox_id"` - TokenType string `json:"token_type"` -} - -type groupVoice struct { - rh *gocommon.RedisonHandler - eosptr unsafe.Pointer -} - -func (gv *groupVoice) eosTokenRefresh(ctx context.Context) { - defer func() { - r := recover() - if r != nil { - logger.Error(r) - } - }() - - endpoint := "https://api.epicgames.dev/auth/v1/oauth/token" - auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", config.EosClientId, config.EosClientSecret))) - body := bytes.NewBufferString("grant_type=client_credentials&deployment_id=" + config.EosDeploymentId) - for { - req, _ := http.NewRequest("POST", endpoint, body) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("Accept", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Basic %s", auth)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - logger.Println("eosTokenRefresh failed. eos token reqeust err :", err) - time.Sleep(time.Minute) - continue - } - - var neweos eosauth - err = json.NewDecoder(resp.Body).Decode(&neweos) - resp.Body.Close() - - if err != nil { - logger.Println("eosTokenRefresh failed. decode err :", err) - return - } - - logger.Printf("eos access_token retreived : %s...", neweos.AccessToken[:20]) - atomic.StorePointer(&gv.eosptr, unsafe.Pointer(&neweos)) - select { - case <-ctx.Done(): - return - - case <-time.After(time.Duration(neweos.ExpiresIn-60) * time.Second): - - } - } -} - -func (gv *groupVoice) eosAuth() *eosauth { - ptr := atomic.LoadPointer(&gv.eosptr) - return (*eosauth)(ptr) -} - -func (gv *groupVoice) Initialize(tv *Tavern, ctx context.Context) error { - gv.rh = tv.redison - gv.eosptr = unsafe.Pointer(&eosauth{}) - - if len(config.EosClientId) == 0 { - logger.Println("eos voice chat is disabled. 'eos_client_id' is empty") - } - if len(config.EosClientSecret) == 0 { - logger.Println("eos voice chat is disabled. 'eos_client_secret' is empty") - } - if len(config.EosDeploymentId) == 0 { - logger.Println("eos voice chat is disabled. 'eos_deployment_id' is empty") - } - - if len(config.EosClientId) > 0 && len(config.EosClientSecret) > 0 && len(config.EosDeploymentId) > 0 { - go gv.eosTokenRefresh(ctx) - } - - return nil -} - -func (gv *groupVoice) ClientConnected(conn *websocket.Conn, callby *wshandler.Sender) { - -} - -func (gv *groupVoice) ClientDisconnected(msg string, callby *wshandler.Sender) { - // vals, err := gv.rh.JSONGetString(callby.Accid.Hex(), "$.voice") - // if err != nil { - // return - // } - - // if len(vals) == 0 { - // return - // } - - // switch vals[0] { - // case "eos": - // // TODO : Removing a Participant - // // https://dev.epicgames.com/docs/web-api-ref/voice-web-api#removing-a-participant - // } -} - -type eosRoomParticipantRequests struct { - Puid string `json:"puid"` - ClientIP string `json:"clientIP"` - HardMuted bool `json:"hardMuted"` -} - -type eosRoomParticipants struct { - Participants []eosRoomParticipantRequests `json:"participants"` -} - -func (gv *groupVoice) JoinVoiceChat(w http.ResponseWriter, r *http.Request) { - var data struct { - Gid string - Mid string - Service string - Alias string - } - if err := gocommon.MakeDecoder(r).Decode(&data); err != nil { - logger.Println("JoinVoiceChat failed. DecodeGob returns err :", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - switch data.Service { - case "eos": - // https://dev.epicgames.com/docs/web-api-ref/voice-web-api - accessToken := gv.eosAuth().AccessToken - if len(accessToken) == 0 { - logger.Println("eos voice chat is not ready. access_token is empty") - w.WriteHeader(http.StatusInternalServerError) - return - } - - voiceendpoint := fmt.Sprintf("https://api.epicgames.dev/rtc/v1/%s/room/%s", config.EosDeploymentId, data.Gid) - participants := eosRoomParticipants{ - Participants: []eosRoomParticipantRequests{ - {Puid: data.Mid}, - }, - } - - body, _ := json.Marshal(participants) - req, _ := http.NewRequest("POST", voiceendpoint, bytes.NewBuffer(body)) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - logger.Println("join voice room failed. api.epicgames.dev return err :", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - var result map[string]any - json.NewDecoder(resp.Body).Decode(&result) - resp.Body.Close() - - result["client_id"] = config.EosClientId - result["client_secret"] = config.EosClientSecret - - par := result["participants"].([]any)[0] - participant := par.(map[string]any) - - channelCredentials := map[string]any{ - "override_userid": data.Mid, - "client_base_url": result["clientBaseUrl"], - "participant_token": participant["token"], - } - marshaled, _ := json.Marshal(channelCredentials) - result["channel_credentials"] = base64.StdEncoding.EncodeToString(marshaled) - - gocommon.MakeEncoder(w, r).Encode(result) - } -} - -func (gv *groupVoice) LeaveVoiceChat(w http.ResponseWriter, r *http.Request) { - var data struct { - Gid string - Mid string - Service string - } - if err := gocommon.MakeDecoder(r).Decode(&data); err != nil { - logger.Println("JoinVoiceChat failed. DecodeGob returns err :", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - switch data.Service { - case "eos": - voiceendpoint := fmt.Sprintf("https://api.epicgames.dev/rtc/v1/%s/room/%s/participants/%s", config.EosDeploymentId, data.Gid, data.Mid) - accessToken := gv.eosAuth().AccessToken - - req, _ := http.NewRequest("DELETE", voiceendpoint, nil) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - logger.Println("LeaveVoiceChat failed. err :", err) - } else if resp.StatusCode != http.StatusOK { - logger.Println("LeaveVoiceChat failed. status code :", resp.StatusCode) - } - } -}