Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
unixpickle
GitHub Repository: unixpickle/kahoot-hack
Path: blob/master/kahoot-play/main.go
10110 views
1
package main
2
3
import (
4
"fmt"
5
"os"
6
"os/signal"
7
"strconv"
8
"syscall"
9
10
"github.com/unixpickle/kahoot-hack/kahoot"
11
)
12
13
func main() {
14
if len(os.Args) != 3 {
15
fmt.Fprintln(os.Stderr, "Usage: play <game pin> <nickname>")
16
os.Exit(1)
17
}
18
19
gamePin := os.Args[1]
20
nickname := os.Args[2]
21
22
conn, err := kahoot.NewConn(gamePin)
23
if err != nil {
24
fmt.Fprintln(os.Stderr, "failed to connect:", err)
25
os.Exit(1)
26
}
27
if err := conn.Login(nickname); err != nil {
28
fmt.Fprintln(os.Stderr, "failed to login:", err)
29
os.Exit(1)
30
}
31
32
closed := make(chan bool, 1)
33
closed <- false
34
go func() {
35
sigChan := make(chan os.Signal, 1)
36
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
37
<-sigChan
38
<-closed
39
closed <- true
40
conn.GracefulClose()
41
}()
42
43
quiz := kahoot.NewQuiz(conn)
44
for {
45
action, err := quiz.Receive()
46
if err != nil {
47
if !<-closed {
48
fmt.Fprintln(os.Stderr, "Could not receive question:", err)
49
}
50
os.Exit(1)
51
}
52
if action.Type == kahoot.QuestionIntro {
53
fmt.Println("Awaiting answers...")
54
} else if action.Type == kahoot.QuestionAnswers {
55
fmt.Print("Answer (0 through " + strconv.Itoa(action.NumAnswers-1) + "): ")
56
answer := readNumberInput()
57
if err := quiz.Send(answer); err != nil {
58
fmt.Fprintln(os.Stderr, "Could not answer:", err)
59
os.Exit(1)
60
}
61
}
62
}
63
}
64
65
func readNumberInput() int {
66
for {
67
var buffer string
68
for {
69
buf := make([]byte, 1)
70
if _, err := os.Stdin.Read(buf); err != nil {
71
panic("could not read input")
72
}
73
if buf[0] == '\r' {
74
continue
75
} else if buf[0] == '\n' {
76
break
77
}
78
buffer += string(rune(buf[0]))
79
}
80
res, err := strconv.Atoi(buffer)
81
if err != nil {
82
fmt.Println("please enter a number")
83
continue
84
} else {
85
return res
86
}
87
}
88
}
89
90