Aimbot
Aimbot
// Updates an existing gist or creates a new one depending on what the user chooses
to do.
async function updateOrCreateGistWithFile(filePath) {
let shouldUpdate = await askIfGistShouldBeUpdated()
if (shouldUpdate) {
let gist = await pickGist()
await updateGistWithFile(gist, filePath)
} else {
await createGistWithFile(filePath)
}
}
// Asks the user if they really want to remove the stored credentials.
async function confirmRemoveCredentials() {
let alert = new Alert()
alert.title = "Remove Credentials"
alert.message = "Are you sure you want to remove the credentials from your
keychain? If you remove the credentials, you'll need to enter your client ID and
client secret the next time you run the script."
alert.addDestructiveAction("Yes, remove credentials")
alert.addCancelAction("Cancel")
let idx = await alert.presentAlert()
if (idx == 0) {
removeCredentials()
}
}
// Presents the document picker and returns the file path to the picked file.
async function pickFile() {
let paths = await DocumentPicker.open(["public.plain-text"])
if (paths.length > 0) {
return paths[0]
} else {
throw new Error("Cancelled picking file")
}
}
// Presents a list of all Scriptable scripts and returns the path to the picked
script.
async function pickScript() {
let fm = FileManager.iCloud()
let dir = fm.documentsDirectory()
let filenames = fm.listContents(dir)
let jsFilePaths = filenames.filter(filename => {
let uti = fm.getUTI(filename)
return uti == "com.netscape.javascript-source"
}).map(filename => {
return fm.joinPath(dir, filename)
}).sort()
let selectedFilePath = null
let table = new UITable()
table.showSeparators = true
for (filepath of jsFilePaths) {
let filename = fm.fileName(filepath)
let row = new UITableRow()
row.height = 50
row.addText(filename)
table.addRow(row)
row.onSelect = (idx) => {
selectedFilePath = jsFilePaths[idx]
}
row.dismissOnSelect = true
}
await table.present()
if (selectedFilePath != null) {
return selectedFilePath
} else {
throw new Error("Cancelled picking script")
}
}
// Exchanges an OAuth code to an access token using the GitHub API and stores the
access token in the keychain.
async function exchangeCode(code) {
let clientId = Keychain.get(CLIENT_ID_KEY)
let clientSecret = Keychain.get(CLIENT_SECRET_KEY)
let baseURL = "https://github.com/login/oauth/access_token"
let url = baseURL
+ "?client_id=" + encodeURIComponent(clientId)
+ "&client_secret=" + encodeURIComponent(clientSecret)
+ "&code=" + encodeURIComponent(code)
let req = new Request(url)
req.method = "POST"
req.headers = {
"Accept": "application/json"
}
let res = await req.loadJSON()
let accessToken = res.access_token
Keychain.set(ACCESS_TOKEN_KEY, accessToken)
}
// Presents an alert where the user can enter a value in a text field.
// Returns the entered value.
async function promptForValue(title, message, placeholder, value) {
let alert = new Alert()
alert.title = title
alert.message = message
alert.addTextField(placeholder, value)
alert.addAction("OK")
alert.addCancelAction("Cancel")
let idx = await alert.present()
if (idx != -1) {
return alert.textFieldValue(0)
} else {
throw new Error("Cancelled entering value")
}
}