Skip to content

Commit 4de269b

Browse files
committed
Implement client commands for JS with Browser
1 parent 6c37494 commit 4de269b

File tree

8 files changed

+143
-53
lines changed

8 files changed

+143
-53
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.18
55
require (
66
github.com/Bananenpro/cli v0.2.2
77
github.com/code-game-project/go-utils v0.2.9
8+
github.com/spf13/pflag v1.0.5
89
)
910

1011
require (

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63n
66
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
77
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
88
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
9-
github.com/code-game-project/go-utils v0.2.8 h1:f6ZvORWmlf8uZnCSAhLJ23MdA5dGvcAPkijTLfbv+B4=
10-
github.com/code-game-project/go-utils v0.2.8/go.mod h1:kQ6kH9XDzdM2pnJUI1lw61Gp8XOams/E2dKABa1mBI8=
119
github.com/code-game-project/go-utils v0.2.9 h1:ezaxxLBAQRwFnIXso+zKPL7AJnuAMIcMwrhLruoyOa8=
1210
github.com/code-game-project/go-utils v0.2.9/go.mod h1:kQ6kH9XDzdM2pnJUI1lw61Gp8XOams/E2dKABa1mBI8=
1311
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
@@ -30,6 +28,8 @@ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQ
3028
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
3129
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3230
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
31+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
32+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
3333
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3434
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3535
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=

new_client.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func CreateNewClient(projectName string) error {
6969

7070
node := runtime == "node"
7171

72-
if !node {
72+
if !node && typescript {
7373
panic("not implemented")
7474
}
7575

@@ -92,27 +92,32 @@ func CreateNewClient(projectName string) error {
9292
return err
9393
}
9494

95-
if node {
96-
cli.BeginLoading("Installing javascript-client...")
97-
_, err = exec.Execute(true, "npm", "install", "@code-game-project/client"+"@"+data.LibraryVersion)
98-
if err != nil {
99-
return err
100-
}
101-
cli.FinishLoading()
95+
cli.BeginLoading("Installing javascript-client...")
96+
_, err = exec.Execute(true, "npm", "install", "@code-game-project/client"+"@"+data.LibraryVersion)
97+
if err != nil {
98+
return err
99+
}
100+
cli.FinishLoading()
102101

103-
cli.BeginLoading("Installing dependencies...")
104-
_, err = exec.Execute(true, "npm", "install", "commander")
102+
cli.BeginLoading("Installing dependencies...")
103+
_, err = exec.Execute(true, "npm", "install", "commander")
104+
if err != nil {
105+
return err
106+
}
107+
if typescript {
108+
_, err = exec.Execute(true, "npm", "install", "--save-dev", "typescript", "@types/node")
105109
if err != nil {
106110
return err
107111
}
108-
if typescript {
109-
_, err = exec.Execute(true, "npm", "install", "--save-dev", "typescript", "@types/node")
112+
} else {
113+
if !node {
114+
_, err = exec.Execute(true, "npm", "install", "--save-dev", "serve")
110115
if err != nil {
111116
return err
112117
}
113118
}
114-
cli.FinishLoading()
115119
}
120+
cli.FinishLoading()
116121

117122
return nil
118123
}
@@ -195,7 +200,15 @@ func execClientTemplate(projectName string, info server.GameInfo, eventNames, co
195200
}
196201
} else {
197202
if !update {
198-
err := ExecTemplate(clientJSIndexTemplate, "app.js", data)
203+
indexName := "index.js"
204+
if !node {
205+
indexName = "app.js"
206+
err := ExecTemplate(clientIndexHTMLTemplate, "index.html", data)
207+
if err != nil {
208+
return err
209+
}
210+
}
211+
err := ExecTemplate(clientJSIndexTemplate, indexName, data)
199212
if err != nil {
200213
return err
201214
}
@@ -204,12 +217,6 @@ func execClientTemplate(projectName string, info server.GameInfo, eventNames, co
204217
if err != nil {
205218
return err
206219
}
207-
if !node {
208-
err := ExecTemplate(clientIndexHTMLTemplate, "index.html", data)
209-
if err != nil {
210-
return err
211-
}
212-
}
213220
}
214221

215222
if !update && node {

run.go

Lines changed: 97 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import (
55
"os"
66
"os/exec"
77
"strings"
8+
"time"
89

910
"github.com/code-game-project/go-utils/cgfile"
1011
cgExec "github.com/code-game-project/go-utils/exec"
1112
"github.com/code-game-project/go-utils/external"
1213
"github.com/code-game-project/go-utils/modules"
14+
"github.com/spf13/pflag"
1315
)
1416

1517
func Run() error {
@@ -27,10 +29,6 @@ func Run() error {
2729
runtime := config.LangConfig["runtime"]
2830
node := runtime == "node"
2931

30-
if !node {
31-
panic("not implemented")
32-
}
33-
3432
url := external.TrimURL(config.URL)
3533

3634
switch config.Type {
@@ -51,31 +49,107 @@ func runClient(url string, args []string, typescript, node bool) error {
5149
}
5250
}
5351

54-
path := "app.js"
55-
if typescript {
56-
path = "dist/index.js"
57-
}
52+
if node {
53+
path := "index.js"
54+
if typescript {
55+
path = "dist/index.js"
56+
}
5857

59-
cmdArgs := []string{path}
60-
cmdArgs = append(cmdArgs, args...)
58+
cmdArgs := []string{path}
59+
cmdArgs = append(cmdArgs, args...)
6160

62-
env := []string{"CG_GAME_URL=" + url}
63-
env = append(env, os.Environ()...)
61+
env := []string{"CG_GAME_URL=" + url}
62+
env = append(env, os.Environ()...)
6463

65-
if _, err := exec.LookPath("node"); err != nil {
66-
return fmt.Errorf("'node' ist not installed!")
67-
}
64+
if _, err := exec.LookPath("node"); err != nil {
65+
return fmt.Errorf("'node' ist not installed!")
66+
}
6867

69-
cmd := exec.Command("node", cmdArgs...)
70-
cmd.Stdin = os.Stdin
71-
cmd.Stdout = os.Stdout
72-
cmd.Stderr = os.Stderr
73-
cmd.Env = env
68+
cmd := exec.Command("node", cmdArgs...)
69+
cmd.Stdin = os.Stdin
70+
cmd.Stdout = os.Stdout
71+
cmd.Stderr = os.Stderr
72+
cmd.Env = env
7473

75-
err := cmd.Run()
76-
if err != nil {
77-
return fmt.Errorf("Failed to run 'CG_GAME_URL=%s node %s'", url, strings.Join(cmdArgs, " "))
74+
err := cmd.Run()
75+
if err != nil {
76+
return fmt.Errorf("Failed to run 'CG_GAME_URL=%s node %s'.", url, strings.Join(cmdArgs, " "))
77+
}
78+
} else {
79+
if _, err := exec.LookPath("npx"); err != nil {
80+
return fmt.Errorf("'npx' ist not installed!")
81+
}
82+
83+
cmd := exec.Command("npx", "serve", "-n", "--no-port-switching", "-l", "5000", ".")
84+
cmd.Stdin = os.Stdin
85+
cmd.Stdout = os.Stdout
86+
cmd.Stderr = os.Stderr
87+
88+
err := cmd.Start()
89+
if err != nil {
90+
return fmt.Errorf("Failed to start 'npx serve': %s", err)
91+
}
92+
93+
pflag.Usage = func() {
94+
fmt.Fprintf(os.Stdout, "Usage: %s [options] [command]\n\n", os.Args[0])
95+
fmt.Fprintf(os.Stdout, "Options:\n")
96+
pflag.PrintDefaults()
97+
fmt.Fprintf(os.Stdout, "\nCommands:\n")
98+
fmt.Fprintf(os.Stdout, " create [options] <username> Create and join a new game.\n")
99+
fmt.Fprintf(os.Stdout, " join [options] <game_id> <username> [join_secret] Join an existing game.\n")
100+
fmt.Fprintf(os.Stdout, " reconnect [options] <username> Reconnect to a game using a saved session.\n")
101+
fmt.Fprintf(os.Stdout, " spectate [options] [game_id] Spectate a new or existing game.\n")
102+
}
103+
104+
var queryParams string
105+
var public bool
106+
pflag.BoolVar(&public, "public", false, "Make the created game protected.")
107+
var protected bool
108+
pflag.BoolVar(&public, "protected", false, "Make the created game protected.")
109+
pflag.CommandLine.Parse(args)
110+
111+
var op string
112+
if pflag.NArg() > 0 {
113+
op = pflag.Arg(0)
114+
}
115+
116+
switch op {
117+
case "create", "reconnect":
118+
if pflag.NArg() > 1 {
119+
queryParams += "&username=" + pflag.Arg(1)
120+
}
121+
case "join":
122+
if pflag.NArg() > 1 {
123+
queryParams += "&game_id=" + pflag.Arg(1)
124+
}
125+
if pflag.NArg() > 2 {
126+
queryParams += "&username=" + pflag.Arg(2)
127+
}
128+
if pflag.NArg() > 3 {
129+
queryParams += "&join_secret=" + pflag.Arg(3)
130+
}
131+
case "spectate":
132+
if pflag.NArg() > 1 {
133+
queryParams += "&game_id=" + pflag.Arg(1)
134+
}
135+
}
136+
137+
if public {
138+
queryParams += "&public=true"
139+
}
140+
if protected {
141+
queryParams += "&protected=true"
142+
}
143+
144+
time.Sleep(2 * time.Second)
145+
146+
cgExec.OpenBrowser(fmt.Sprintf("http://localhost:5000?game_url=%s&op=%s%s", url, op, queryParams))
147+
err = cmd.Wait()
148+
if err != nil {
149+
return fmt.Errorf("Failed to run 'npx serve -n --no-port-switching -l 5000 .': %s", err)
150+
}
78151
}
152+
79153
return nil
80154
}
81155

templates/new/client/js/app.js.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
import { Game, Verbosity } from './{{.GameName}}/game.js';
22

3+
{{ if .Node }}
34
const { game } = await Game.fromArgv({}, Verbosity.DEBUG);
5+
{{ else }}
6+
const { game } = await Game.fromQuery({}, Verbosity.DEBUG);
7+
{{ end }}

templates/new/client/js/game.js.tmpl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ import { createSocket, GameSocket, Verbosity } from '@code-game-project/client';
99
import { Argument, Command, Option } from 'commander';
1010

1111
import { argv, env } from 'process';
12-
export { Verbosity };
1312

1413
function getURL() {
1514
if (!env.CG_GAME_URL) throw 'Environment variable `CG_GAME_URL` must be set.';
1615
else return env.CG_GAME_URL;
1716
}
1817
{{ else }}
19-
// import { createSocket, GameSocket, Verbosity } from '../node_modules/@code-game-project/client/dist/browser.js';
18+
import { createSocket, GameSocket, Verbosity } from '../node_modules/@code-game-project/client/dist/browser.js';
2019

2120
function getURL() {
22-
const CG_GAME_URL = new URLSearchParams(window.location.search).get('host');
23-
if (!CG_GAME_URL) throw 'Query parameter "host" must be set.';
21+
const CG_GAME_URL = new URLSearchParams(window.location.search).get('game_url');
22+
if (!CG_GAME_URL) throw 'Query parameter "game_url" must be set.';
2423
else return CG_GAME_URL;
2524
}
2625
{{ end }}
26+
export { Verbosity };
2727
const VERBOSITY = ['silent', 'error', 'warning', 'info', 'debug'];
2828
{{ if .Node }}
2929
const PUBLIC_OPTION = new Option('--public', 'List the game as public.');

templates/new/client/ts/game.ts.tmpl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type { Events, Commands{{range .Commands}}, {{.PascalName}}Cmd{{end}}{{ra
1212
import { Argument, Command, Option } from 'commander';
1313

1414
import { argv, env } from 'process';
15-
export { Verbosity };
1615

1716
function getURL(): string {
1817
if (!env.CG_GAME_URL) throw 'Environment variable `CG_GAME_URL` must be set.';
@@ -24,11 +23,12 @@ import type { EventListenerCallback, Session } from '@code-game-project/client/d
2423
import type { Events, Commands{{range .Commands}}, {{.PascalName}}Cmd{{end}}{{range .Events}}, {{.PascalName}}Event{{end}} } from './event_definitions';
2524

2625
function getURL(): string {
27-
const CG_GAME_URL = new URLSearchParams(window.location.search).get('host');
28-
if (!CG_GAME_URL) throw 'Query parameter "host" must be set.';
26+
const CG_GAME_URL = new URLSearchParams(window.location.search).get('game_url');
27+
if (!CG_GAME_URL) throw 'Query parameter "game_url" must be set.';
2928
else return CG_GAME_URL;
3029
}
3130
{{ end }}
31+
export { Verbosity };
3232
const VERBOSITY = ['silent', 'error', 'warning', 'info', 'debug'] as Verbosity[];
3333
{{ if .Node }}
3434
const PUBLIC_OPTION = new Option('--public', 'List the game as public.');

templates/new/client/ts/index.ts.tmpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { GameConfig } from './{{.GameName}}/event_definitions.js';
22
import { Game, Verbosity } from './{{.GameName}}/game.js';
33

4-
const { game } = await Game.fromArgv<GameConfig>({}, Verbosity.DEBUG);
4+
{{ if .Node }}
5+
const { game } = await Game.fromArgv({}, Verbosity.DEBUG);
6+
{{ else }}
7+
const { game } = await Game.fromQuery({}, Verbosity.DEBUG);
8+
{{ end }}

0 commit comments

Comments
 (0)