forked from T-Hugs/advent-of-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubmit.ts
154 lines (139 loc) · 5.97 KB
/
submit.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { LocalStorage } from "node-localstorage";
import { formatTime, getAppRoot, wait } from "./util/util";
import path from "path";
import { log, SolutionObject, solutionLogKey } from "./util/log";
import fetch from "cross-fetch";
import chalk from "chalk";
import _ from "lodash";
import { getSessionToken } from "./getToken";
import { UA_STRING } from "./config";
const appRoot = getAppRoot();
const localStorage = new LocalStorage(path.join(appRoot, ".scratch"));
/* Potential responses from an answer submission */
/*That's not the right answer. If you're stuck, make sure you're using the full input data; there are also some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 12345.) [Return to Day 6]*/
/*That's not the right answer; your answer is too high. If you're stuck, make sure you're using the full input data; there are also some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 78986.) [Return to Day 2]*/
/*That's not the right answer; your answer is too low. If you're stuck, make sure you're using the full input data; there are also some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 78986.) [Return to Day 2]*/
/*You gave an answer too recently; you have to wait after submitting an answer before trying again. You have 55s left to wait. <a href="/2016/day/6">[Return to Day 6]</a>*/
function getMsUntilActiveCooldownExpiration(solutionLog: SolutionObject[]) {
const expirations = solutionLog.map(solution => {
const previousSubmissions = solution.submissions;
if (previousSubmissions && previousSubmissions.length > 0) {
const mostRecentSubmission = _.maxBy(previousSubmissions, s => new Date(s.date).getTime())!;
if (mostRecentSubmission.result === "timeout" && mostRecentSubmission.cooldownFinished != undefined) {
return new Date(mostRecentSubmission.cooldownFinished).getTime() - new Date().getTime();
}
}
return 0;
});
return Math.max(...expirations, 0);
}
async function submit() {
const solutionLogStr = localStorage.getItem(solutionLogKey);
if (solutionLogStr == undefined) {
log("Could not find solution log!");
process.exit(1);
}
let solutionLog: SolutionObject[];
try {
solutionLog = JSON.parse(solutionLogStr);
} catch {
log("Could not parse solution log!");
process.exit(1);
}
let mostRecent: SolutionObject | undefined = undefined;
let i = 0;
for (const solution of solutionLog) {
const dateComputed = new Date(solution.dateComputed);
if (!mostRecent) {
mostRecent = solution;
} else if (new Date(mostRecent.dateComputed).getTime() < dateComputed.getTime()) {
mostRecent = solution;
}
i++;
}
if (!mostRecent) {
log("Could not find any solutions in the log!");
process.exit(1);
}
const msTillCooldown = getMsUntilActiveCooldownExpiration(solutionLog);
if (msTillCooldown > 0) {
log(
`Waiting ${formatTime(msTillCooldown)} until cooldown expiration before automatically submitting. Ctrl+C to abort.`
);
}
await wait(msTillCooldown);
let part: string;
let answer: string;
if (mostRecent.part2 && mostRecent.part2 !== "Not implemented") {
part = "2";
answer = mostRecent.part2;
} else if (mostRecent.part1 && mostRecent.part1 !== "Not implemented") {
part = "1";
answer = mostRecent.part1;
} else {
log("No solution to submit!");
process.exit(1);
}
const postData = `level=${part}&answer=${answer}`;
const sessionToken = await getSessionToken();
const uri = `https://adventofcode.com/${mostRecent.problem.year}/day/${mostRecent.problem.day}/answer`;
log(
`Submitting: Year: ${mostRecent.problem.year}, Day: ${mostRecent.problem.day}, Part: ${part}, Answer: ${answer}`
);
const result = await fetch(uri, {
headers: {
cookie: `session=${sessionToken}`,
accept: `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9`,
"content-type": "application/x-www-form-urlencoded",
"user-agent": UA_STRING
},
method: "post",
body: postData,
});
if (!mostRecent.submissions) {
mostRecent.submissions = [];
}
if (result.status === 200) {
const responseText = await result.text();
if (responseText.includes("That's not the right answer")) {
if (responseText.includes("your answer is too high.")) {
mostRecent.submissions.push({ date: new Date().toJSON(), result: "high" });
log("Wrong! (too high)");
} else if (responseText.includes("your answer is too low.")) {
mostRecent.submissions.push({ date: new Date().toJSON(), result: "low" });
log("Wrong! (too low)");
} else {
mostRecent.submissions.push({ date: new Date().toJSON(), result: "incorrect" });
log("Wrong answer!");
}
} else if (responseText.includes("You gave an answer too recently")) {
const waitTime = /You have (.*?) left to wait/.exec(responseText)![1];
let cooldownFinished: string | undefined = undefined;
const waitTimeMatch = /^(\d+)s$/.exec(waitTime);
if (waitTimeMatch) {
cooldownFinished = new Date(new Date().getTime() + Number(waitTimeMatch[1]) * 1000).toJSON();
}
mostRecent.submissions.push({
date: new Date().toJSON(),
result: "timeout",
cooldownFinished: cooldownFinished,
});
log(
`Cooldown in progress (${waitTime} remaining). Re-submitting now will auto wait for cooldown to expire.`
);
} else if (responseText.includes("That's the right answer!")) {
mostRecent.submissions.push({date: new Date().toJSON(), result: "correct"});
log(
chalk.greenBright("Correct! One ") + chalk.yellowBright("GOLD") + chalk.greenBright(" star for you!")
);
} else {
mostRecent.submissions.push({date: new Date().toJSON(), result: "unknown"});
log("Unrecognized response! See below.\n");
log(responseText);
}
localStorage.setItem(solutionLogKey, JSON.stringify(solutionLog, null, 4));
}
}
submit().then(() => {
process.exit(0);
});