mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
DNET: Rebalance / player feedback (#2533)
This commit is contained in:
committed by
GitHub
parent
15e1ab9af7
commit
3d41c348bc
@@ -17,7 +17,7 @@ unleashStormSeed(): DarknetResult;
|
||||
|
||||
[DarknetResult](./bitburner.darknetresult.md)
|
||||
|
||||
A promise that resolves to a [DarknetResult](./bitburner.darknetresult.md) object.
|
||||
A [DarknetResult](./bitburner.darknetresult.md) object.
|
||||
|
||||
## Remarks
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## NS.getServerUsedRam() method
|
||||
|
||||
Get the used RAM on a server.
|
||||
Get the used RAM on a server. This includes ram used by running scripts as well as blocked ram on darknet servers.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -1037,7 +1037,7 @@ Get server security level.
|
||||
|
||||
</td><td>
|
||||
|
||||
Get the used RAM on a server.
|
||||
Get the used RAM on a server. This includes ram used by running scripts as well as blocked ram on darknet servers.
|
||||
|
||||
|
||||
</td></tr>
|
||||
|
||||
@@ -112,5 +112,5 @@ const server = ns.args[0];
|
||||
const files = ["hack.js", "weaken.js", "grow.js"];
|
||||
ns.scp(files, server, "home");
|
||||
```
|
||||
For password-protected servers (such as darknet servers), a session must be established with the destination server before using this function.
|
||||
For password-protected servers (such as darknet servers), a session must be established with the destination server before using this function. (The source server does not require a session.)
|
||||
|
||||
|
||||
@@ -181,17 +181,19 @@ export const addRandomConnections = (server: DarknetServer) => {
|
||||
const x = server.depth;
|
||||
const y = server.leftOffset;
|
||||
const horizontalNeighbors = getNeighborsOnRow(x, y);
|
||||
const lateralConnectionChance = HORIZONTAL_CONNECTION_CHANCE * (1.1 - server.depth * 0.01);
|
||||
horizontalNeighbors.forEach((neighbor) => {
|
||||
if (Math.random() < HORIZONTAL_CONNECTION_CHANCE) {
|
||||
if (Math.random() < lateralConnectionChance) {
|
||||
connectServers(server, neighbor);
|
||||
}
|
||||
});
|
||||
|
||||
const serversAbove = getServersOnRowAbove(x);
|
||||
const serversBelow = getServersOnRowBelow(x);
|
||||
const verticalConnectionChance = VERTICAL_CONNECTION_CHANCE * (1.1 - server.depth * 0.01);
|
||||
[...serversAbove, ...serversBelow].forEach((neighbor) => {
|
||||
const distance = Math.abs(neighbor.depth ?? x - x) + 1;
|
||||
if (Math.random() < VERTICAL_CONNECTION_CHANCE / distance) {
|
||||
if (Math.random() < verticalConnectionChance / distance) {
|
||||
connectServers(server, neighbor);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ export const mutateDarknet = (): void => {
|
||||
restartRandomServer();
|
||||
}
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
if (Math.random() < 0.3) {
|
||||
moveRandomDarknetServers(3);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,22 +62,24 @@ export const handleFailedAuth = (server: DarknetServer, threads: number) => {
|
||||
* @param person - the player's character
|
||||
* @param attemptedPassword - the password being attempted
|
||||
* @param threads - the number of threads used for the password attempt (which speeds up the process)
|
||||
* @param linear - if true, the time scaling is linear with the number of threads instead of having diminishing returns
|
||||
*/
|
||||
export const calculateAuthenticationTime = (
|
||||
darknetServerData: DarknetServerData,
|
||||
person: IPerson = Player,
|
||||
threads = 1,
|
||||
attemptedPassword = "",
|
||||
linear = false,
|
||||
) => {
|
||||
const chaRequired = darknetServerData.requiredCharismaSkill;
|
||||
const difficulty = darknetServerData.difficulty;
|
||||
|
||||
const baseDiff = (difficulty + 1) * 100;
|
||||
const diffFactor = 5;
|
||||
const baseTime = 500;
|
||||
const baseTime = 850;
|
||||
|
||||
const threadsFactor = 1 / (1 + 0.2 * (threads - 1));
|
||||
const skillFactor = (diffFactor * chaRequired + baseDiff) / (person.skills.charisma + 100);
|
||||
const threadsFactor = 1 / (linear ? threads : 1 + 0.2 * (threads - 1));
|
||||
const skillFactor = (diffFactor * chaRequired + baseDiff) / (person.skills.charisma + 150);
|
||||
const backdoorFactor = getBackdoorAuthTimeDebuff();
|
||||
const applyUnderleveledFactor = person.skills.charisma <= chaRequired && darknetServerData.depth > 1;
|
||||
const underleveledFactor = applyUnderleveledFactor ? 1.5 + (chaRequired + 50) / (person.skills.charisma + 50) : 1;
|
||||
@@ -128,10 +130,9 @@ export const getMultiplierFromCharisma = (scalar = 1) => {
|
||||
);
|
||||
};
|
||||
|
||||
// TODO: balance xp gain
|
||||
export const calculatePasswordAttemptChaGain = (server: DarknetServerData, threads: number = 1, success = false) => {
|
||||
const baseXpGain = 3;
|
||||
const difficultyBase = 1.12;
|
||||
const difficultyBase = 0.8;
|
||||
const xpGain = baseXpGain + difficultyBase ** server.difficulty;
|
||||
const alreadyHackedMult = server.hasAdminRights ? 0.2 : 1;
|
||||
const successMult = success && !server.hasAdminRights ? 10 : 1;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { generateDarknetServerName, isPasswordResponse, type PasswordResponse }
|
||||
import { LocationName } from "@enums";
|
||||
import { getServerState, LogEntry } from "./DarknetState";
|
||||
import { ModelIds } from "../Enums";
|
||||
import { getDarknetServer } from "../utils/darknetServerUtils";
|
||||
import { getDarknetServer, getDarknetServerOrThrow } from "../utils/darknetServerUtils";
|
||||
import { getAllMovableDarknetServers } from "../utils/darknetNetworkUtils";
|
||||
import { getExactCorrectChars, getTwoCharsInPassword } from "../utils/darknetAuthUtils";
|
||||
import type { DarknetServer } from "../../Server/DarknetServer";
|
||||
@@ -200,8 +200,8 @@ const getLogNoise = (server: DarknetServer, logDate: Date): LogEntry => {
|
||||
return log(`--${randomServer.password}--`);
|
||||
}
|
||||
|
||||
if (server.modelId === ModelIds.packetSniffer && Math.random() < 0.5 / (server.difficulty + 1)) {
|
||||
return log("Authentication successful: " + server.password);
|
||||
if (server.modelId === ModelIds.packetSniffer && Math.random() < 0.7 - server.difficulty * 0.01) {
|
||||
return addPacketSnifferNoise(server);
|
||||
}
|
||||
|
||||
return log(`${logDate.toLocaleTimeString()}: ${server.hostname} - heartbeat check (alive)`);
|
||||
@@ -212,6 +212,18 @@ const log = (message: string, pid = -1) => ({
|
||||
pid,
|
||||
});
|
||||
|
||||
const addPacketSnifferNoise = (server: DarknetServer) => {
|
||||
const connectedServers = server.serversOnNetwork;
|
||||
// If the server becomes disconnected while the UI is open and has no neighbors but still
|
||||
// has logs being populated, fall back to showing the current password
|
||||
if (Math.random() < 0.3 || connectedServers.length === 0) {
|
||||
return log(`Logging in with passcode: ${server.password} ...`);
|
||||
}
|
||||
const randomServerName = connectedServers[Math.floor(Math.random() * connectedServers.length)];
|
||||
const randomServer = getDarknetServerOrThrow(randomServerName);
|
||||
return log(`Connecting to ${randomServer.hostname}:${randomServer.password} ...`);
|
||||
};
|
||||
|
||||
export const getMostRecentAuthLog = (hostname: string) => {
|
||||
for (const log of getServerState(hostname).serverLogs) {
|
||||
if (!isPasswordResponse(log.message)) {
|
||||
|
||||
@@ -4,11 +4,13 @@ import { AIR_GAP_DEPTH, MS_PER_MUTATION_PER_ROW, NET_WIDTH } from "../Enums";
|
||||
import { GetAllServers } from "../../Server/AllServers";
|
||||
import { getNetDepth } from "../effects/labyrinth";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Player } from "@player";
|
||||
|
||||
export const getDarknetCyclesPerMutation = () => {
|
||||
const depth = getNetDepth();
|
||||
const cycleRate = MS_PER_MUTATION_PER_ROW / CONSTANTS.MilliPerCycle;
|
||||
return cycleRate / depth;
|
||||
const rateMultiplier = Player.bitNodeN !== 15 ? 2 : 1;
|
||||
return (rateMultiplier * cycleRate) / depth;
|
||||
};
|
||||
|
||||
export const getAllOpenPositions = (minDepth: number, maxDepth: number): [number, number][] => {
|
||||
|
||||
@@ -425,7 +425,8 @@ export function NetscriptDarknet(): InternalAPI<DarknetAPI> {
|
||||
}
|
||||
|
||||
const server = serverCheck.server;
|
||||
const networkDelay = calculateAuthenticationTime(server, Player, ctx.workerScript.scriptRef.threads) * 4;
|
||||
const networkDelay =
|
||||
calculateAuthenticationTime(server, Player, ctx.workerScript.scriptRef.threads, "", true) * 4;
|
||||
const xp = formatNumber(calculatePasswordAttemptChaGain(server, ctx.workerScript.scriptRef.threads), 1);
|
||||
|
||||
logger(ctx)(`Captured some outgoing transmissions from ${server.hostname}. (Gained ${xp} cha xp)`);
|
||||
|
||||
6
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
6
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@@ -4619,7 +4619,7 @@ export interface Darknet {
|
||||
* @remarks
|
||||
* RAM cost: 0.1 GB
|
||||
*
|
||||
* @returns A promise that resolves to a {@link DarknetResult} object.
|
||||
* @returns A {@link DarknetResult} object.
|
||||
*/
|
||||
unleashStormSeed(): DarknetResult;
|
||||
|
||||
@@ -7953,7 +7953,7 @@ export interface NS {
|
||||
* ns.scp(files, server, "home");
|
||||
* ```
|
||||
*
|
||||
* For password-protected servers (such as darknet servers), a session must be established with the destination server before using this function.
|
||||
* For password-protected servers (such as darknet servers), a session must be established with the destination server before using this function. (The source server does not require a session.)
|
||||
*
|
||||
* @param files - Filename or an array of filenames of script/literature files to copy. Note that if a file is located in a subdirectory, the filename must include the leading `/`.
|
||||
* @param destination - Hostname/IP of the destination server, which is the server to which the file will be copied.
|
||||
@@ -8185,7 +8185,7 @@ export interface NS {
|
||||
*/
|
||||
getServerMaxRam(host?: string): number;
|
||||
/**
|
||||
* Get the used RAM on a server.
|
||||
* Get the used RAM on a server. This includes ram used by running scripts as well as blocked ram on darknet servers.
|
||||
* @remarks
|
||||
* RAM cost: 0.05 GB
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "../Utilities";
|
||||
import type { ScriptFilePath } from "../../../src/Paths/ScriptFilePath";
|
||||
import { DarknetState, getServerState, triggerNextUpdate } from "../../../src/DarkNet/models/DarknetState";
|
||||
import { getDarknetServerOrThrow } from "../../../src/DarkNet/utils/darknetServerUtils";
|
||||
import { getDarknetServer, getDarknetServerOrThrow } from "../../../src/DarkNet/utils/darknetServerUtils";
|
||||
import { ModelIds, ResponseCodeEnum } from "../../../src/DarkNet/Enums";
|
||||
import { getAllMovableDarknetServers } from "../../../src/DarkNet/utils/darknetNetworkUtils";
|
||||
import { expectRunningOnDarknetServer } from "../../../src/DarkNet/effects/offlineServerHandling";
|
||||
@@ -878,9 +878,19 @@ describe("Non-darkweb darknet server", () => {
|
||||
test("authenticate from darkweb", async () => {
|
||||
const ns = getNsOnDarkWeb();
|
||||
const target = getFirstDarknetServerAdjacentToDarkWeb();
|
||||
const result = await ns.dnet.authenticate(target, getDarknetServerOrThrow(target).password);
|
||||
expect(result.success).toStrictEqual(true);
|
||||
const server = getDarknetServerOrThrow(target);
|
||||
const result = await ns.dnet.authenticate(target, server.password);
|
||||
// Logging details for debugging flaky test
|
||||
if (!result.success) {
|
||||
console.log("Server details grabbed before auth:");
|
||||
console.log(server);
|
||||
console.log("result:");
|
||||
console.log(result);
|
||||
console.log("currentServerDetails:");
|
||||
console.log(getDarknetServer(target));
|
||||
}
|
||||
expect(result.code).toStrictEqual(ResponseCodeEnum.Success);
|
||||
expect(result.success).toStrictEqual(true);
|
||||
});
|
||||
test("authenticate itself", async () => {
|
||||
const ns = getNsOnNonDarkwebDarknetServer();
|
||||
|
||||
Reference in New Issue
Block a user