Skip to content

Commit 34ebc5b

Browse files
committed
wip
1 parent f406cce commit 34ebc5b

File tree

9 files changed

+200
-39
lines changed

9 files changed

+200
-39
lines changed

internal/api/http.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func (handler *V1Handler) SetupRoutes(rootPath string, register func(string, str
3232
register("GET", path.Join(v1, "lobby", "ws"), handler.websocketUpgrade)
3333

3434
register("POST", path.Join(v1, "lobby", "{lobby_id}", "player"), handler.postPlayer)
35+
register("POST", path.Join(v1, "discord_authenticate"), handler.discordAuthenticate)
3536
}
3637

3738
// remoteAddressToSimpleIP removes unnecessary clutter from the input,

internal/api/v1.go

Lines changed: 108 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package api
66

77
import (
8+
"bytes"
9+
"encoding/json"
810
"errors"
911
"fmt"
1012
"log"
@@ -191,6 +193,57 @@ func (handler *V1Handler) postLobby(writer http.ResponseWriter, request *http.Re
191193
state.AddLobby(lobby)
192194
}
193195

196+
type discordAuthenticatePayload struct {
197+
Code string `json:"code"`
198+
}
199+
200+
type discordTokenRequest struct {
201+
ClientId string `json:"client_id"`
202+
ClientSecret string `json:"client_secret"`
203+
GrantType string `json:"grant_type"`
204+
Code string `json:"code"`
205+
}
206+
type discordTokenResponse struct {
207+
AccessCode string `json:"access_code"`
208+
}
209+
210+
func (handler *V1Handler) discordAuthenticate(writer http.ResponseWriter, request *http.Request) {
211+
decoder := json.NewDecoder(request.Body)
212+
var payload discordAuthenticatePayload
213+
if err := decoder.Decode(&payload); err != nil {
214+
http.Error(writer, "error decoding payload", http.StatusBadRequest)
215+
return
216+
}
217+
218+
discordPayload := bytes.NewBuffer(nil)
219+
if err := json.NewEncoder(discordPayload).Encode(discordTokenRequest{
220+
ClientId: "1320396325925163070",
221+
ClientSecret: handler.cfg.DiscordApiKey,
222+
GrantType: "authorization_code",
223+
Code: payload.Code,
224+
}); err != nil {
225+
http.Error(writer, "error retrieving token from discord", http.StatusInternalServerError)
226+
return
227+
}
228+
discordRequest, err := http.NewRequest(http.MethodPost, "https://discord.com/api/oauth2/token", discordPayload)
229+
if err != nil {
230+
http.Error(writer, "internal server error", http.StatusInternalServerError)
231+
return
232+
}
233+
234+
response, err := http.DefaultClient.Do(discordRequest)
235+
if err != nil {
236+
http.Error(writer, "error retrieving token from discord", http.StatusInternalServerError)
237+
return
238+
}
239+
240+
var discordTokenResponse discordTokenResponse
241+
if err := json.NewDecoder(response.Body).Decode(&discordTokenResponse); err != nil {
242+
http.Error(writer, "error retrieving token from discord", http.StatusInternalServerError)
243+
return
244+
}
245+
}
246+
194247
func (handler *V1Handler) postPlayer(writer http.ResponseWriter, request *http.Request) {
195248
lobby := state.GetLobby(request.PathValue("lobby_id"))
196249
if lobby == nil {
@@ -249,20 +302,57 @@ func GetDiscordInstanceId(request *http.Request) string {
249302
return discordInstanceId
250303
}
251304

305+
func GetDiscordFrameId(request *http.Request) string {
306+
value := request.URL.Query().Get("frame_id")
307+
if value == "" {
308+
cookie, _ := request.Cookie("discord-frame-id")
309+
if cookie != nil {
310+
value = cookie.Value
311+
}
312+
}
313+
return value
314+
}
315+
316+
func GetDiscordPlatform(request *http.Request) string {
317+
value := request.URL.Query().Get("platform")
318+
if value == "" {
319+
cookie, _ := request.Cookie("discord-platform")
320+
if cookie != nil {
321+
value = cookie.Value
322+
}
323+
}
324+
return value
325+
}
326+
252327
const discordDomain = "1320396325925163070.discordsays.com"
253328

329+
func createDiscordCookie(name, value string) *http.Cookie {
330+
return &http.Cookie{
331+
Name: name,
332+
Value: value,
333+
Domain: discordDomain,
334+
Path: "/",
335+
SameSite: http.SameSiteNoneMode,
336+
Partitioned: true,
337+
Secure: true,
338+
}
339+
}
340+
254341
func SetDiscordCookies(w http.ResponseWriter, request *http.Request) {
255-
discordInstanceId := GetDiscordInstanceId(request)
342+
discordInstanceId := request.URL.Query().Get("instance_id")
256343
if discordInstanceId != "" {
257-
http.SetCookie(w, &http.Cookie{
258-
Name: "discord-instance-id",
259-
Value: discordInstanceId,
260-
Domain: discordDomain,
261-
Path: "/",
262-
SameSite: http.SameSiteNoneMode,
263-
Partitioned: true,
264-
Secure: true,
265-
})
344+
http.SetCookie(w, createDiscordCookie(
345+
"discord-instance-id",
346+
discordInstanceId,
347+
))
348+
http.SetCookie(w, createDiscordCookie(
349+
"discord-platform",
350+
GetDiscordPlatform(request),
351+
))
352+
http.SetCookie(w, createDiscordCookie(
353+
"discord-frame-id",
354+
GetDiscordFrameId(request),
355+
))
266356
}
267357
}
268358

@@ -276,24 +366,14 @@ func SetGameplayCookies(
276366
) {
277367
discordInstanceId := GetDiscordInstanceId(request)
278368
if discordInstanceId != "" {
279-
http.SetCookie(w, &http.Cookie{
280-
Name: "usersession",
281-
Value: player.GetUserSession().String(),
282-
Domain: discordDomain,
283-
Path: "/",
284-
SameSite: http.SameSiteNoneMode,
285-
Partitioned: true,
286-
Secure: true,
287-
})
288-
http.SetCookie(w, &http.Cookie{
289-
Name: "lobby-id",
290-
Value: lobby.LobbyID,
291-
Domain: discordDomain,
292-
Path: "/",
293-
SameSite: http.SameSiteNoneMode,
294-
Partitioned: true,
295-
Secure: true,
296-
})
369+
http.SetCookie(w, createDiscordCookie(
370+
"usersession",
371+
player.GetUserSession().String(),
372+
))
373+
http.SetCookie(w, createDiscordCookie(
374+
"lobby-id",
375+
lobby.LobbyID,
376+
))
297377
} else {
298378
// For the discord case, we need both, as the discord specific cookies
299379
// aren't available during the readirect from ssrCreate to ssrEnter.

internal/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ type Config struct {
7272
Port uint16 `env:"PORT"`
7373
CORS CORS `envPrefix:"CORS_"`
7474
LobbyCleanup LobbyCleanup `envPrefix:"LOBBY_CLEANUP_"`
75+
76+
DiscordApiKey string `env:"DISCORD_API_KEY"`
7577
}
7678

7779
var Default = Config{

internal/frontend/http.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ type BasePageConfig struct {
6161

6262
var fallbackChecksum = uuid.Must(uuid.NewV4()).String()
6363

64-
func (baseConfig *BasePageConfig) Hash(key string, bytes []byte) error {
64+
func (baseConfig *BasePageConfig) Hash(key string, bytes ...[]byte) error {
6565
_, alreadyExists := baseConfig.checksums[key]
6666
if alreadyExists {
6767
return fmt.Errorf("duplicate hash key '%s'", key)
6868
}
69-
if _, err := baseConfig.hash.Write(bytes); err != nil {
70-
return fmt.Errorf("error hashing '%s': %w", key, err)
69+
for _, arr := range bytes {
70+
if _, err := baseConfig.hash.Write(arr); err != nil {
71+
return fmt.Errorf("error hashing '%s': %w", key, err)
72+
}
7173
}
7274
baseConfig.checksums[key] = hex.EncodeToString(baseConfig.hash.Sum(nil))
7375
baseConfig.hash.Reset()

internal/frontend/index.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ import (
2424
//go:embed lobby.js
2525
var lobbyJsRaw string
2626

27+
//go:embed lobby-discord.js
28+
var lobbyDiscordJsRaw string
29+
30+
func init() {
31+
lobbyJsRaw = `
32+
{{if .DiscordActivity}}
33+
` + lobbyDiscordJsRaw + `
34+
{{end}}
35+
` + lobbyJsRaw
36+
lobbyDiscordJsRaw = ""
37+
}
38+
2739
//go:embed index.js
2840
var indexJsRaw string
2941

@@ -95,7 +107,7 @@ func NewHandler(cfg *config.Config) (*SSRHandler, error) {
95107
if err := basePageConfig.Hash("index.js", []byte(indexJsRaw)); err != nil {
96108
return nil, fmt.Errorf("error hashing: %w", err)
97109
}
98-
if err := basePageConfig.Hash("lobby.js", []byte(lobbyJsRaw)); err != nil {
110+
if err := basePageConfig.Hash("lobby.js", []byte(lobbyJsRaw), []byte(lobbyDiscordJsRaw)); err != nil {
99111
return nil, fmt.Errorf("error hashing: %w", err)
100112
}
101113

@@ -136,7 +148,6 @@ func (handler *SSRHandler) indexPageHandler(writer http.ResponseWriter, request
136148
api.SetDiscordCookies(writer, request)
137149
discordInstanceId := api.GetDiscordInstanceId(request)
138150
if discordInstanceId != "" {
139-
createPageData.DiscordActivity = true
140151
lobby := state.GetLobby(discordInstanceId)
141152
if lobby != nil {
142153
handler.ssrEnterLobbyNoChecks(lobby, writer, request,
@@ -145,6 +156,8 @@ func (handler *SSRHandler) indexPageHandler(writer http.ResponseWriter, request
145156
})
146157
return
147158
}
159+
160+
createPageData.DiscordActivity = true
148161
}
149162

150163
err := pageTemplates.ExecuteTemplate(writer, "index", createPageData)

internal/frontend/lobby-discord.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { DiscordSDK } from '{{.RootPath}}/resources/discord-sdk.mjs';
2+
const clientId = "1320396325925163070"
3+
const discordSdk = new DiscordSDK(clientId, null, {
4+
frameId: getCookie("discord-frame-id"),
5+
instanceId: getCookie("discord-instance-id"),
6+
platform: getCookie("discord-platform"),
7+
});
8+
// postMessage(JSON.parse(window.localStorage.getItem("sdk-payload")));
9+
10+
async function setupDiscordSdk() {
11+
await discordSdk.ready()
12+
13+
console.log("Discord SDK ready")
14+
return discordSdk
15+
.authorize({
16+
client_id: clientId,
17+
response_type: "code",
18+
state: "",
19+
prompt: "none",
20+
scope: [
21+
"identify",
22+
],
23+
})
24+
.then((response) => {
25+
console.log("Authenticating client");
26+
return fetch("`{{.RootPath}}/v1/discord_authenticate`", {
27+
method: "POST",
28+
headers: {
29+
'Content-Type': 'application/json',
30+
},
31+
body: JSON.stringify({
32+
code: response.code,
33+
}),
34+
})
35+
})
36+
.then((response) => response.json())
37+
.then((response) => {
38+
return discordSdk
39+
.authenticate({
40+
access_token: response.access_code(),
41+
})
42+
})
43+
}
44+
45+
setupDiscordSdk()
46+
.then((response) => {
47+
let name = response.user.username;
48+
if (response.user.nickname) {
49+
name = response.user.nickname;
50+
}
51+
console.log(name);
52+
changeName(name);
53+
}).
54+
catch((error) => {
55+
console.log(error);
56+
});
57+

internal/frontend/lobby.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type lobbyPageData struct {
2424
type lobbyJsData struct {
2525
*BasePageConfig
2626
*api.GameConstants
27+
DiscordActivity bool
2728

2829
Translation translations.Translation
2930
Locale string
@@ -35,18 +36,21 @@ type robotPageData struct {
3536
}
3637

3738
func (handler *SSRHandler) lobbyJs(writer http.ResponseWriter, request *http.Request) {
39+
discordInstanceId := api.GetDiscordInstanceId(request)
3840
translation, locale := determineTranslation(request)
3941
pageData := &lobbyJsData{
40-
BasePageConfig: handler.basePageConfig,
41-
GameConstants: api.GameConstantsData,
42-
Translation: translation,
43-
Locale: locale,
42+
BasePageConfig: handler.basePageConfig,
43+
GameConstants: api.GameConstantsData,
44+
Translation: translation,
45+
DiscordActivity: discordInstanceId != "",
46+
Locale: locale,
4447
}
4548

4649
writer.Header().Set("Content-Type", "text/javascript")
4750
// Duration of 1 year, since we use cachebusting anyway.
4851
writer.Header().Set("Cache-Control", "public, max-age=31536000")
4952
writer.WriteHeader(http.StatusOK)
53+
5054
if err := handler.lobbyJsRawTemplate.ExecuteTemplate(writer, "lobby-js", pageData); err != nil {
5155
log.Printf("error templating JS: %s\n", err)
5256
}
@@ -86,6 +90,7 @@ func (handler *SSRHandler) ssrEnterLobbyNoChecks(
8690
) {
8791
translation, locale := determineTranslation(request)
8892
requestAddress := api.GetIPAddressFromRequest(request)
93+
discordInstanceId := api.GetDiscordInstanceId(request)
8994
api.SetDiscordCookies(writer, request)
9095
writer.Header().Set("Cache-Control", "no-cache")
9196

@@ -120,7 +125,7 @@ func (handler *SSRHandler) ssrEnterLobbyNoChecks(
120125
BasePageConfig: handler.basePageConfig,
121126
LobbyData: api.CreateLobbyData(handler.cfg, lobby),
122127
Translation: translation,
123-
DiscordActivity: api.GetDiscordInstanceId(request) != "",
128+
DiscordActivity: discordInstanceId != "",
124129
Locale: locale,
125130
}
126131
})

internal/frontend/resources/discord-sdk.mjs

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

internal/frontend/templates/lobby.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@
383383
</div>
384384

385385
<script type="text/javascript" src='{{.RootPath}}/resources/{{.WithCacheBust "draw.js"}}'></script>
386-
<script type="text/javascript" src='{{.RootPath}}/{{.WithCacheBust "lobby.js"}}'></script>
386+
<script type="module" src='{{.RootPath}}/{{.WithCacheBust "lobby.js"}}'></script>
387387
</body>
388388

389389
</html>

0 commit comments

Comments
 (0)