bitburner-src/src/Terminal/determineAllPossibilitiesForTabCompletion.ts

315 lines
8.3 KiB
TypeScript
Raw Normal View History

2019-04-20 07:27:33 +02:00
import {
evaluateDirectoryPath,
getAllParentDirectories,
} from "./DirectoryHelpers";
import { getSubdirectories } from "./DirectoryServerHelpers";
2019-04-20 07:27:33 +02:00
import {
Aliases,
2021-04-30 05:52:56 +02:00
GlobalAliases,
} from "../Alias";
import { DarkWebItems } from "../DarkWeb/DarkWebItems";
import { Message } from "../Message/Message";
import { IPlayer } from "../PersonObjects/IPlayer"
import { AllServers } from "../Server/AllServers";
// An array of all Terminal commands
const commands = [
"alias",
"analyze",
v0.51.6 (#905) * Make command `cd` without arguments an alias for `cd /` (#853) In most shells `cd` without arguments takes you to the home directory of the current user. I keep trying to do this due to muscle memory from working in terminals, so I figured I'd make it do something useful. There is no home directory in the game, but going to / is the closest thing we have, since that is the starting point for the user in the game. * Add new `backdoor` terminal command (#852) * Add the backdoor command to the terminal This command will perform a manual hack without rewarding money. It will be used for the story, mainly for faction hacking tests * Add tab completion for backdoor command * Add help text for backdoor command * Change condition syntax to be more consistent with others * Extract reused code block so it is always called after actions * Update documentation for new backdoor command Modified references to manual hack as it isn't for factions anymore * Remove extra parenthesis * Rename manuallyHacked to backdoorInstalled * Fix typo * Change faction test messages to use backdoor instad of hack * Rename more instances of manuallyHacked * fixed typo in helptext of darkweb buy (#858) * Fix typos and unify descriptions of augmentations (#859) Made an attempt to... - give all "+rep% company/faction" the same text - make all augmentations with a single effect use a single line to describe the effect - make all effects end with a period * Made Cashroot starter kit display its tooltip with the money formatted properly and in gold * fix typo in docs (#860) * Initial code for Casino Card Deck implementation * Casino Blackjack Implementation * Update some tools (eslint, typescript) * Blackjack code cleanup * Update README_contribution * Update ScriptHelpers.js (#861) expand error message * More augmentation typo fixes (#862) * Add Netscript function getCurrentScript (#856) Add netscript function that returns the current script. * Added milestones menu to guide new players. (#865) Milestone menu * fix typos in milestones (#866) Co-authored-by: sschmidTU <s.schmid@phonicscore.com> * Corrupt location title when backdoor is installed (#864) * Add corruptableText component * Corrupt location title if backdoor is installed * Formatting * Add helper to check value of backdoorInstalled Helper could be oneline but it would make it less readable * Fix some formatting * Add settings option to disable text effects * Import useState * getRunningScript (#867) * Replaced getCurrentScript with getRunningScript * Bunch of smaller fixes (#904) Fix #884 Fix #879 Fix #878 Fix #876 Fix #874 Fix #873 Fix #887 Fix #891 Fix #895 * rework the early servers to be more noob friendly (#903) * v0.51.6 Co-authored-by: Andreas Eriksson <2691182+AndreasTPC@users.noreply.github.com> Co-authored-by: Jack <jackdewinter1@gmail.com> Co-authored-by: Teun Pronk <5228255+Crownie88@users.noreply.github.com> Co-authored-by: Pimvgd <Pimvgd@gmail.com> Co-authored-by: Daniel Xie <daniel.xie@flockfreight.com> Co-authored-by: Simon <33069673+sschmidTU@users.noreply.github.com> Co-authored-by: sschmidTU <s.schmid@phonicscore.com>
2021-04-29 02:07:26 +02:00
"backdoor",
"cat",
"cd",
"check",
"clear",
"cls",
"connect",
"download",
"expr",
"free",
"hack",
"help",
"home",
"hostname",
"ifconfig",
"kill",
"killall",
"ls",
"lscpu",
"mem",
"mv",
"nano",
"ps",
"rm",
"run",
"scan",
"scan-analyze",
"scp",
"sudov",
"tail",
"theme",
2021-04-30 05:52:56 +02:00
"top",
];
2021-04-30 05:52:56 +02:00
export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: string, index: number, currPath=""): string[] {
let allPos: string[] = [];
allPos = allPos.concat(Object.keys(GlobalAliases));
const currServ = p.getCurrentServer();
const homeComputer = p.getHomeComputer();
2019-04-20 07:27:33 +02:00
2021-04-30 05:52:56 +02:00
let parentDirPath = "";
2019-04-20 07:27:33 +02:00
let evaledParentDirPath: string | null = null;
// Helper functions
2021-05-01 09:17:31 +02:00
function addAllCodingContracts(): void {
for (const cct of currServ.contracts) {
allPos.push(cct.fn);
}
}
2021-05-01 09:17:31 +02:00
function addAllLitFiles(): void {
for (const file of currServ.messages) {
if (!(file instanceof Message)) {
allPos.push(file);
}
}
}
2021-05-01 09:17:31 +02:00
function addAllMessages(): void {
for (const file of currServ.messages) {
if (file instanceof Message) {
allPos.push(file.filename);
}
}
}
2021-05-01 09:17:31 +02:00
function addAllPrograms(): void {
2019-04-13 01:52:59 +02:00
for (const program of homeComputer.programs) {
allPos.push(program);
}
}
2021-05-01 09:17:31 +02:00
function addAllScripts(): void {
for (const script of currServ.scripts) {
2019-04-20 07:27:33 +02:00
const res = processFilepath(script.filename);
if (res) {
allPos.push(res);
}
}
}
2021-05-01 09:17:31 +02:00
function addAllTextFiles(): void {
for (const txt of currServ.textFiles) {
2019-04-20 07:27:33 +02:00
const res = processFilepath(txt.fn);
if (res) {
allPos.push(res);
}
}
}
2021-05-01 09:17:31 +02:00
function addAllDirectories(): void {
2019-04-20 07:27:33 +02:00
// Directories are based on the currently evaluated path
const subdirs = getSubdirectories(currServ, evaledParentDirPath == null ? "/" : evaledParentDirPath);
for (let i = 0; i < subdirs.length; ++i) {
const assembledDirPath = (evaledParentDirPath == null ? subdirs[i] : evaledParentDirPath + subdirs[i]);
const res = processFilepath(assembledDirPath);
if (res != null) {
subdirs[i] = res;
}
}
allPos = allPos.concat(subdirs);
}
// Convert from the real absolute path back to the original path used in the input
function convertParentPath(filepath: string): string {
if (parentDirPath == null || evaledParentDirPath == null) {
console.warn(`convertParentPath() called when paths are null`);
return filepath;
}
if (!filepath.startsWith(evaledParentDirPath)) {
console.warn(`convertParentPath() called for invalid path. (filepath=${filepath}) (evaledParentDirPath=${evaledParentDirPath})`);
return filepath;
}
2019-04-20 07:27:33 +02:00
return parentDirPath + filepath.slice(evaledParentDirPath.length);
}
// Given an a full, absolute filepath, converts it to the proper value
// for autocompletion purposes
function processFilepath(filepath: string): string | null {
if (evaledParentDirPath) {
if (filepath.startsWith(evaledParentDirPath)) {
return convertParentPath(filepath);
}
} else if (parentDirPath !== "") {
// If the parent directory is the root directory, but we're not searching
// it from the root directory, we have to add the original path
let t_parentDirPath = parentDirPath;
if (!t_parentDirPath.endsWith("/")) { t_parentDirPath += "/"; }
return parentDirPath + filepath;
} else {
return filepath;
}
return null;
}
2021-05-01 09:17:31 +02:00
function isCommand(cmd: string): boolean {
let t_cmd = cmd;
if (!t_cmd.endsWith(" ")) {
t_cmd += " ";
}
return input.startsWith(t_cmd);
}
/**
* If the command starts with './' and the index == -1, then the user
* has input ./partialexecutablename so autocomplete the script or program.
* Put './' in front of each script/executable
*/
if (isCommand("./") && index == -1) {
//All programs and scripts
2021-05-01 09:17:31 +02:00
for (let i = 0; i < currServ.scripts.length; ++i) {
allPos.push("./" + currServ.scripts[i].filename);
}
//Programs are on home computer
2021-05-01 09:17:31 +02:00
for(let i = 0; i < homeComputer.programs.length; ++i) {
allPos.push("./" + homeComputer.programs[i]);
}
return allPos;
}
// Autocomplete the command
2019-04-20 07:27:33 +02:00
if (index === -1) {
return commands.concat(Object.keys(Aliases)).concat(Object.keys(GlobalAliases));
}
2019-04-20 07:27:33 +02:00
// Since we're autocompleting an argument and not a command, the argument might
// be a file/directory path. We have to account for that when autocompleting
const commandArray = input.split(" ");
if (commandArray.length === 0) {
console.warn(`Tab autocompletion logic reached invalid branch`);
return allPos;
}
const arg = commandArray[commandArray.length - 1];
parentDirPath = getAllParentDirectories(arg);
evaledParentDirPath = evaluateDirectoryPath(parentDirPath, currPath);
if (evaledParentDirPath === "/") {
evaledParentDirPath = null;
} else if (evaledParentDirPath == null) {
return allPos; // Invalid path
} else {
evaledParentDirPath += "/";
}
if (isCommand("buy")) {
2021-04-30 05:52:56 +02:00
const options = [];
for (const i in DarkWebItems) {
const item = DarkWebItems[i]
options.push(item.program);
}
return options.concat(Object.keys(GlobalAliases));
}
if (isCommand("scp") && index === 1) {
for (const iphostname in AllServers) {
allPos.push(AllServers[iphostname].ip);
allPos.push(AllServers[iphostname].hostname);
}
return allPos;
}
if (isCommand("scp") && index === 0) {
addAllScripts();
addAllLitFiles();
addAllTextFiles();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("connect")) {
// All network connections
2021-05-01 09:17:31 +02:00
for (let i = 0; i < currServ.serversOnNetwork.length; ++i) {
2021-04-30 05:52:56 +02:00
const serv = AllServers[currServ.serversOnNetwork[i]];
if (serv == null) { continue; }
allPos.push(serv.ip);
allPos.push(serv.hostname);
}
return allPos;
}
if (isCommand("kill") || isCommand("tail") || isCommand("mem") || isCommand("check")) {
addAllScripts();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("nano")) {
addAllScripts();
addAllTextFiles();
allPos.push(".fconf");
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("rm")) {
addAllScripts();
addAllPrograms();
addAllLitFiles();
addAllTextFiles();
addAllCodingContracts();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("run")) {
addAllScripts();
addAllPrograms();
addAllCodingContracts();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("cat")) {
addAllMessages();
addAllLitFiles();
addAllTextFiles();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("download") || isCommand("mv")) {
addAllScripts();
addAllTextFiles();
2019-04-20 07:27:33 +02:00
addAllDirectories();
return allPos;
}
if (isCommand("cd")) {
addAllDirectories();
return allPos;
}
2019-04-20 07:27:33 +02:00
if (isCommand("ls") && index === 0) {
addAllDirectories();
}
return allPos;
}