Merge branch 'dev' of github.com:danielyxie/bitburner into dev

This commit is contained in:
Olivier Gagnon 2022-07-21 02:42:52 -04:00
commit 6498a720bb
7 changed files with 284 additions and 15 deletions

@ -370,3 +370,35 @@ The list contains the name of (i.e. the value returned by
| | | aaaaaaaaaaaaa -> 1a91031 | | | | aaaaaaaaaaaaa -> 1a91031 |
| | | aaaaaaaaaaaaaa -> 1a91041 | | | | aaaaaaaaaaaaaa -> 1a91041 |
+-----------------------------------------+------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------+
| Encryption I: Caesar Cipher | | Caesar cipher is one of the simplest encryption technique. It is a type of |
| | | substitution cipher in which each letter in the plaintext is replaced by a letter some |
| | | fixed number of positions down the alphabet. For example, with a left shift of 3, D |
| | | would be replaced by A, E would become B, and A would become X (because of rotation). |
| | | You are given an array with two elements.The first element is the plaintext, the |
| | | second element is the left shift value. Return the ciphertext as uppercase string. |
| | | Spaces remains the same. |
+-----------------------------------------+------------------------------------------------------------------------------------------+
| Encryption II: Vigenère Cipher | | Vigenère cipher is a type of polyalphabetic substitution. It uses the Vigenère square |
| | | to encrypt and decrypt plaintext with a keyword. |
| | | Vignenère square: |
| | | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
| | | +---------------------------------------------------- |
| | | A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
| | | B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A |
| | | C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B |
| | | D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C |
| | | E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D |
| | | ... |
| | | Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X |
| | | Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y |
| | | For encryption each letter of the plaintext is paired with the corresponding letter of |
| | | a repeating keyword. For example, the plaintext DASHBOARD is encrypted with the |
| | | keyword LINUX: |
| | | Plaintext: DASHBOARD |
| | | Keyword: LINUXLINU |
| | | So, the first letter D is paired with the first letter of the key L. Therefore, row D |
| | | and column L of the Vigenère square are used to get the first cipher letter O. This |
| | | must be repeated for the whole ciphertext. |
| | | You are given an array with two elements. The first element is the plaintext, the |
| | | second element is the keyword. Return the ciphertext as uppercase string. |
+-----------------------------------------+------------------------------------------------------------------------------------------+

12
package-lock.json generated

@ -19131,9 +19131,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "4.8.0", "version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"commander": "^2.20.0", "commander": "^2.20.0",
@ -37110,9 +37110,9 @@
} }
}, },
"terser": { "terser": {
"version": "4.8.0", "version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
"dev": true, "dev": true,
"requires": { "requires": {
"commander": "^2.20.0", "commander": "^2.20.0",

@ -39,6 +39,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
return { return {
shock: 100 - sl.shock, shock: 100 - sl.shock,
sync: sl.sync, sync: sl.sync,
memory: sl.memory,
hacking: sl.hacking, hacking: sl.hacking,
strength: sl.strength, strength: sl.strength,
defense: sl.defense, defense: sl.defense,
@ -349,9 +350,13 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
continue; continue;
} }
const other = player.sleeves[i]; const other = player.sleeves[i];
if (other.currentTask === SleeveTaskType.Bladeburner && other.bbAction === action) { if (
other.currentTask === SleeveTaskType.Bladeburner &&
other.bbAction === action &&
other.bbContract === contract
) {
throw ctx.helper.makeRuntimeErrorMsg( throw ctx.helper.makeRuntimeErrorMsg(
`Sleeve ${sleeveNumber} cannot take of contracts because Sleeve ${i} is already performing that action.`, `Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
); );
} }
} }

@ -44,7 +44,7 @@ interface ITaskDetails {
function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] { function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
// Array of all companies that other sleeves are working at // Array of all companies that other sleeves are working at
const forbiddenCompanies = []; const forbiddenCompanies: string[] = [];
for (const otherSleeve of player.sleeves) { for (const otherSleeve of player.sleeves) {
if (sleeve === otherSleeve) { if (sleeve === otherSleeve) {
continue; continue;
@ -54,13 +54,8 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
} }
} }
const allJobs: string[] = Object.keys(player.jobs); const allJobs: string[] = Object.keys(player.jobs);
for (let i = 0; i < allJobs.length; ++i) {
if (!forbiddenCompanies.includes(allJobs[i])) {
allJobs[i];
}
}
return allJobs; return allJobs.filter((company) => !forbiddenCompanies.includes(company));
} }
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] { function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {

@ -15,6 +15,7 @@ import { updateHashManagerCapacity } from "./Hacknet/HacknetHelpers";
import { prestigeWorkerScripts } from "./NetscriptWorker"; import { prestigeWorkerScripts } from "./NetscriptWorker";
import { Player } from "./Player"; import { Player } from "./Player";
import { Router } from "./ui/GameRoot"; import { Router } from "./ui/GameRoot";
import { recentScripts } from "./Netscript/RecentScripts";
import { resetPidCounter } from "./Netscript/Pid"; import { resetPidCounter } from "./Netscript/Pid";
import { LiteratureNames } from "./Literature/data/LiteratureNames"; import { LiteratureNames } from "./Literature/data/LiteratureNames";
@ -309,5 +310,7 @@ export function prestigeSourceFile(flume: boolean): void {
// Gain int exp // Gain int exp
if (Player.sourceFileLvl(5) !== 0 && !flume) Player.gainIntelligenceExp(300); if (Player.sourceFileLvl(5) !== 0 && !flume) Player.gainIntelligenceExp(300);
// Clear recent scripts
recentScripts.splice(0, recentScripts.length);
resetPidCounter(); resetPidCounter();
} }

@ -1023,6 +1023,8 @@ export interface SleeveSkills {
shock: number; shock: number;
/** Current sync of the sleeve [0-100] */ /** Current sync of the sleeve [0-100] */
sync: number; sync: number;
/** Current memory of the sleeve [1-100] */
memory: number;
/** Current hacking skill of the sleeve */ /** Current hacking skill of the sleeve */
hacking: number; hacking: number;
/** Current strength of the sleeve */ /** Current strength of the sleeve */

@ -1653,4 +1653,236 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
return comprLZDecode(ans) === plain && ans.length <= comprLZEncode(plain).length; return comprLZDecode(ans) === plain && ans.length <= comprLZEncode(plain).length;
}, },
}, },
{
desc: (data: [string, number]): string => {
return [
"Caesar cipher is one of the simplest encryption technique.",
"It is a type of substitution cipher in which each letter in the plaintext ",
"is replaced by a letter some fixed number of positions down the alphabet.",
"For example, with a left shift of 3, D would be replaced by A, ",
"E would become B, and A would become X (because of rotation).\n\n",
"You are given an array with two elements:\n",
`&nbsp;&nbsp;["${data[0]}", ${data[1]}]\n`,
"The first element is the plaintext, the second element is the left shift value.\n\n",
"Return the ciphertext as uppercase string. Spaces remains the same.",
].join(" ");
},
difficulty: 1,
gen: (): [string, number] => {
// return [plaintext, shift value]
const words = [
"ARRAY",
"CACHE",
"CLOUD",
"DEBUG",
"EMAIL",
"ENTER",
"FLASH",
"FRAME",
"INBOX",
"LINUX",
"LOGIC",
"LOGIN",
"MACRO",
"MEDIA",
"MODEM",
"MOUSE",
"PASTE",
"POPUP",
"PRINT",
"QUEUE",
"SHELL",
"SHIFT",
"TABLE",
"TRASH",
"VIRUS",
];
return [
words
.sort(() => Math.random() - 0.5)
.slice(0, 5)
.join(" "),
Math.floor(Math.random() * 25 + 1),
];
},
name: "Encryption I: Caesar Cipher",
numTries: 10,
solver: (data: [string, number], ans: string): boolean => {
// data = [plaintext, shift value]
// build char array, shifting via map and join to final results
const cipher = [...data[0]]
.map((a) => (a === " " ? a : String.fromCharCode(((a.charCodeAt(0) - 65 - data[1] + 26) % 26) + 65)))
.join("");
return cipher === ans;
},
},
{
desc: (data: [string, string]): string => {
return [
"Vigenère cipher is a type of polyalphabetic substitution. It uses ",
"the Vigenère square to encrypt and decrypt plaintext with a keyword.\n\n",
"&nbsp;&nbsp;Vignenère square:\n",
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \n",
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------------------------------------------------\n",
"&nbsp;&nbsp;&nbsp;&nbsp; A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \n",
"&nbsp;&nbsp;&nbsp;&nbsp; B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A \n",
"&nbsp;&nbsp;&nbsp;&nbsp; C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B\n",
"&nbsp;&nbsp;&nbsp;&nbsp; D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C\n",
"&nbsp;&nbsp;&nbsp;&nbsp; E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D\n",
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...\n",
"&nbsp;&nbsp;&nbsp;&nbsp; Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X\n",
"&nbsp;&nbsp;&nbsp;&nbsp; Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y\n\n",
"For encryption each letter of the plaintext is paired with the corresponding letter of a repeating keyword.",
"For example, the plaintext DASHBOARD is encrypted with the keyword LINUX:\n",
"&nbsp;&nbsp; Plaintext: DASHBOARD\n",
"&nbsp;&nbsp; Keyword:&nbsp;&nbsp;&nbsp;LINUXLINU\n",
"So, the first letter D is paired with the first letter of the key L. Therefore, row D and column L of the ",
"Vigenère square are used to get the first cipher letter O. This must be repeated for the whole ciphertext.\n\n",
"You are given an array with two elements:\n",
`&nbsp;&nbsp;["${data[0]}", "${data[1]}"]\n`,
"The first element is the plaintext, the second element is the keyword.\n\n",
"Return the ciphertext as uppercase string.",
].join(" ");
},
difficulty: 2,
gen: (): [string, string] => {
// return [plaintext, keyword]
const words = [
"ARRAY",
"CACHE",
"CLOUD",
"DEBUG",
"EMAIL",
"ENTER",
"FLASH",
"FRAME",
"INBOX",
"LINUX",
"LOGIC",
"LOGIN",
"MACRO",
"MEDIA",
"MODEM",
"MOUSE",
"PASTE",
"POPUP",
"PRINT",
"QUEUE",
"SHELL",
"SHIFT",
"TABLE",
"TRASH",
"VIRUS",
];
const keys = [
"ALGORITHM",
"BANDWIDTH",
"BLOGGER",
"BOOKMARK",
"BROADBAND",
"BROWSER",
"CAPTCHA",
"CLIPBOARD",
"COMPUTING",
"COMMAND",
"COMPILE",
"COMPRESS",
"COMPUTER",
"CONFIGURE",
"DASHBOARD",
"DATABASE",
"DESKTOP",
"DIGITAL",
"DOCUMENT",
"DOWNLOAD",
"DYNAMIC",
"EMOTICON",
"ENCRYPT",
"EXABYTE",
"FIREWALL",
"FIRMWARE",
"FLAMING",
"FLOWCHART",
"FREEWARE",
"GIGABYTE",
"GRAPHICS",
"HARDWARE",
"HYPERLINK",
"HYPERTEXT",
"INTEGER",
"INTERFACE",
"INTERNET",
"ITERATION",
"JOYSTICK",
"JUNKMAIL",
"KEYBOARD",
"KEYWORD",
"LURKING",
"MACINTOSH",
"MAINFRAME",
"MALWARE",
"MONITOR",
"NETWORK",
"NOTEBOOK",
"COMPUTER",
"OFFLINE",
"OPERATING",
"PASSWORD",
"PHISHING",
"PLATFORM",
"PODCAST",
"PRINTER",
"PRIVACY",
"PROCESS",
"PROGRAM",
"PROTOCOL",
"REALTIME",
"RESTORE",
"RUNTIME",
"SCANNER",
"SECURITY",
"SHAREWARE",
"SNAPSHOT",
"SOFTWARE",
"SPAMMER",
"SPYWARE",
"STORAGE",
"TERMINAL",
"TEMPLATE",
"TERABYTE",
"TOOLBAR",
"TYPEFACE",
"USERNAME",
"UTILITY",
"VERSION",
"VIRTUAL",
"WEBMASTER",
"WEBSITE",
"WINDOWS",
"WIRELESS",
"PROCESSOR",
];
return [
words
.sort(() => Math.random() - 0.5)
.slice(0, 5)
.join(""),
keys.sort(() => Math.random() - 0.5)[0],
];
},
name: "Encryption II: Vigenère Cipher",
numTries: 10,
solver: (data: [string, string], ans: string): boolean => {
// data = [plaintext, keyword]
// build char array, shifting via map and corresponding keyword letter and join to final results
const cipher = [...data[0]]
.map((a, i) => {
return a === " "
? a
: String.fromCharCode(((a.charCodeAt(0) - 2 * 65 + data[1].charCodeAt(i % data[1].length)) % 26) + 65);
})
.join("");
return cipher === ans;
},
},
]; ];