Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
unixpickle
GitHub Repository: unixpickle/kahoot-hack
Path: blob/master/kahoot-auto/main.go
10110 views
1
package main
2
3
//written by Peter Stenger (@reteps)
4
import (
5
"fmt"
6
"os"
7
"os/signal"
8
"strconv"
9
"syscall"
10
11
"github.com/howeyc/gopass"
12
"github.com/unixpickle/kahoot-hack/kahoot"
13
)
14
15
// ParseQuizInformation parses quiz information
16
// from a kahoot. It returns the question, answer,
17
// default answer number, and default answer color.
18
func ParseQuizInformation(data *kahoot.QuizInfo) [][]string {
19
var results [][]string
20
colormap := map[int]string{0: "red", 1: "blue", 2: "yellow", 3: "blue"}
21
for _, value := range data.Questions {
22
var questiondata []string
23
for i, choice := range value.Choices {
24
if choice.Correct == true {
25
questiondata = append(questiondata, value.Question, choice.Answer, strconv.Itoa(i), colormap[i])
26
break
27
}
28
}
29
results = append(results, questiondata)
30
}
31
return results
32
}
33
34
func Prompt(question string) string {
35
fmt.Print(question)
36
var response string
37
fmt.Scanf("%s", &response)
38
return response
39
}
40
41
func main() {
42
argnum := len(os.Args)
43
if argnum != 5 && argnum != 4 {
44
fmt.Fprintln(os.Stderr, "Usage: auto <quizid> <game pin> <nickname> (email)")
45
os.Exit(1)
46
}
47
48
gamePin := os.Args[2]
49
nickname := os.Args[3]
50
quizid := os.Args[1]
51
var email string
52
if argnum == 4 {
53
email = Prompt("email > ")
54
} else {
55
email = os.Args[4]
56
}
57
fmt.Print("password > ")
58
password, err := gopass.GetPasswdMasked()
59
if err != nil {
60
panic(err)
61
}
62
token, err := kahoot.AccessToken(email, string(password))
63
if err != nil {
64
panic(err)
65
}
66
data, err := kahoot.QuizInformation(token, quizid)
67
if err != nil {
68
panic(err)
69
}
70
answers := ParseQuizInformation(data)
71
conn, err := kahoot.NewConn(gamePin)
72
if err != nil {
73
fmt.Fprintln(os.Stderr, "failed to connect:", err)
74
os.Exit(1)
75
}
76
if err := conn.Login(nickname); err != nil {
77
fmt.Fprintln(os.Stderr, "failed to login:", err)
78
os.Exit(1)
79
}
80
81
closed := make(chan bool, 1)
82
closed <- false
83
go func() {
84
sigChan := make(chan os.Signal, 1)
85
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
86
<-sigChan
87
<-closed
88
closed <- true
89
conn.GracefulClose()
90
}()
91
92
quiz := kahoot.NewQuiz(conn)
93
fmt.Println("waiting to start...")
94
questionnum := 0
95
for {
96
97
action, err := quiz.Receive()
98
if err != nil {
99
if !<-closed {
100
fmt.Fprintln(os.Stderr, "Could not receive question:", err)
101
}
102
os.Exit(1)
103
}
104
if action.Type == kahoot.QuestionIntro {
105
fmt.Printf("Question %d starting...\n", questionnum+1)
106
} else if action.Type == kahoot.QuestionAnswers {
107
answer, _ := strconv.Atoi(answers[questionnum][2])
108
if err := quiz.Send(answer); err != nil {
109
fmt.Fprintln(os.Stderr, "Could not answer:", err)
110
os.Exit(1)
111
}
112
fmt.Printf("Answered %s (%s)\n", answers[questionnum][1], answers[questionnum][3])
113
questionnum += 1
114
}
115
}
116
}
117
118