mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 23:08:36 +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)
|
[DarknetResult](./bitburner.darknetresult.md)
|
||||||
|
|
||||||
A promise that resolves to a [DarknetResult](./bitburner.darknetresult.md) object.
|
A [DarknetResult](./bitburner.darknetresult.md) object.
|
||||||
|
|
||||||
## Remarks
|
## Remarks
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## NS.getServerUsedRam() method
|
## 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:**
|
**Signature:**
|
||||||
|
|
||||||
|
|||||||
@@ -1037,7 +1037,7 @@ Get server security level.
|
|||||||
|
|
||||||
</td><td>
|
</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>
|
</td></tr>
|
||||||
|
|||||||
@@ -112,5 +112,5 @@ const server = ns.args[0];
|
|||||||
const files = ["hack.js", "weaken.js", "grow.js"];
|
const files = ["hack.js", "weaken.js", "grow.js"];
|
||||||
ns.scp(files, server, "home");
|
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 x = server.depth;
|
||||||
const y = server.leftOffset;
|
const y = server.leftOffset;
|
||||||
const horizontalNeighbors = getNeighborsOnRow(x, y);
|
const horizontalNeighbors = getNeighborsOnRow(x, y);
|
||||||
|
const lateralConnectionChance = HORIZONTAL_CONNECTION_CHANCE * (1.1 - server.depth * 0.01);
|
||||||
horizontalNeighbors.forEach((neighbor) => {
|
horizontalNeighbors.forEach((neighbor) => {
|
||||||
if (Math.random() < HORIZONTAL_CONNECTION_CHANCE) {
|
if (Math.random() < lateralConnectionChance) {
|
||||||
connectServers(server, neighbor);
|
connectServers(server, neighbor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const serversAbove = getServersOnRowAbove(x);
|
const serversAbove = getServersOnRowAbove(x);
|
||||||
const serversBelow = getServersOnRowBelow(x);
|
const serversBelow = getServersOnRowBelow(x);
|
||||||
|
const verticalConnectionChance = VERTICAL_CONNECTION_CHANCE * (1.1 - server.depth * 0.01);
|
||||||
[...serversAbove, ...serversBelow].forEach((neighbor) => {
|
[...serversAbove, ...serversBelow].forEach((neighbor) => {
|
||||||
const distance = Math.abs(neighbor.depth ?? x - x) + 1;
|
const distance = Math.abs(neighbor.depth ?? x - x) + 1;
|
||||||
if (Math.random() < VERTICAL_CONNECTION_CHANCE / distance) {
|
if (Math.random() < verticalConnectionChance / distance) {
|
||||||
connectServers(server, neighbor);
|
connectServers(server, neighbor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export const mutateDarknet = (): void => {
|
|||||||
restartRandomServer();
|
restartRandomServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Math.random() < 0.5) {
|
if (Math.random() < 0.3) {
|
||||||
moveRandomDarknetServers(3);
|
moveRandomDarknetServers(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,22 +62,24 @@ export const handleFailedAuth = (server: DarknetServer, threads: number) => {
|
|||||||
* @param person - the player's character
|
* @param person - the player's character
|
||||||
* @param attemptedPassword - the password being attempted
|
* @param attemptedPassword - the password being attempted
|
||||||
* @param threads - the number of threads used for the password attempt (which speeds up the process)
|
* @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 = (
|
export const calculateAuthenticationTime = (
|
||||||
darknetServerData: DarknetServerData,
|
darknetServerData: DarknetServerData,
|
||||||
person: IPerson = Player,
|
person: IPerson = Player,
|
||||||
threads = 1,
|
threads = 1,
|
||||||
attemptedPassword = "",
|
attemptedPassword = "",
|
||||||
|
linear = false,
|
||||||
) => {
|
) => {
|
||||||
const chaRequired = darknetServerData.requiredCharismaSkill;
|
const chaRequired = darknetServerData.requiredCharismaSkill;
|
||||||
const difficulty = darknetServerData.difficulty;
|
const difficulty = darknetServerData.difficulty;
|
||||||
|
|
||||||
const baseDiff = (difficulty + 1) * 100;
|
const baseDiff = (difficulty + 1) * 100;
|
||||||
const diffFactor = 5;
|
const diffFactor = 5;
|
||||||
const baseTime = 500;
|
const baseTime = 850;
|
||||||
|
|
||||||
const threadsFactor = 1 / (1 + 0.2 * (threads - 1));
|
const threadsFactor = 1 / (linear ? threads : 1 + 0.2 * (threads - 1));
|
||||||
const skillFactor = (diffFactor * chaRequired + baseDiff) / (person.skills.charisma + 100);
|
const skillFactor = (diffFactor * chaRequired + baseDiff) / (person.skills.charisma + 150);
|
||||||
const backdoorFactor = getBackdoorAuthTimeDebuff();
|
const backdoorFactor = getBackdoorAuthTimeDebuff();
|
||||||
const applyUnderleveledFactor = person.skills.charisma <= chaRequired && darknetServerData.depth > 1;
|
const applyUnderleveledFactor = person.skills.charisma <= chaRequired && darknetServerData.depth > 1;
|
||||||
const underleveledFactor = applyUnderleveledFactor ? 1.5 + (chaRequired + 50) / (person.skills.charisma + 50) : 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) => {
|
export const calculatePasswordAttemptChaGain = (server: DarknetServerData, threads: number = 1, success = false) => {
|
||||||
const baseXpGain = 3;
|
const baseXpGain = 3;
|
||||||
const difficultyBase = 1.12;
|
const difficultyBase = 0.8;
|
||||||
const xpGain = baseXpGain + difficultyBase ** server.difficulty;
|
const xpGain = baseXpGain + difficultyBase ** server.difficulty;
|
||||||
const alreadyHackedMult = server.hasAdminRights ? 0.2 : 1;
|
const alreadyHackedMult = server.hasAdminRights ? 0.2 : 1;
|
||||||
const successMult = success && !server.hasAdminRights ? 10 : 1;
|
const successMult = success && !server.hasAdminRights ? 10 : 1;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { generateDarknetServerName, isPasswordResponse, type PasswordResponse }
|
|||||||
import { LocationName } from "@enums";
|
import { LocationName } from "@enums";
|
||||||
import { getServerState, LogEntry } from "./DarknetState";
|
import { getServerState, LogEntry } from "./DarknetState";
|
||||||
import { ModelIds } from "../Enums";
|
import { ModelIds } from "../Enums";
|
||||||
import { getDarknetServer } from "../utils/darknetServerUtils";
|
import { getDarknetServer, getDarknetServerOrThrow } from "../utils/darknetServerUtils";
|
||||||
import { getAllMovableDarknetServers } from "../utils/darknetNetworkUtils";
|
import { getAllMovableDarknetServers } from "../utils/darknetNetworkUtils";
|
||||||
import { getExactCorrectChars, getTwoCharsInPassword } from "../utils/darknetAuthUtils";
|
import { getExactCorrectChars, getTwoCharsInPassword } from "../utils/darknetAuthUtils";
|
||||||
import type { DarknetServer } from "../../Server/DarknetServer";
|
import type { DarknetServer } from "../../Server/DarknetServer";
|
||||||
@@ -200,8 +200,8 @@ const getLogNoise = (server: DarknetServer, logDate: Date): LogEntry => {
|
|||||||
return log(`--${randomServer.password}--`);
|
return log(`--${randomServer.password}--`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.modelId === ModelIds.packetSniffer && Math.random() < 0.5 / (server.difficulty + 1)) {
|
if (server.modelId === ModelIds.packetSniffer && Math.random() < 0.7 - server.difficulty * 0.01) {
|
||||||
return log("Authentication successful: " + server.password);
|
return addPacketSnifferNoise(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
return log(`${logDate.toLocaleTimeString()}: ${server.hostname} - heartbeat check (alive)`);
|
return log(`${logDate.toLocaleTimeString()}: ${server.hostname} - heartbeat check (alive)`);
|
||||||
@@ -212,6 +212,18 @@ const log = (message: string, pid = -1) => ({
|
|||||||
pid,
|
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) => {
|
export const getMostRecentAuthLog = (hostname: string) => {
|
||||||
for (const log of getServerState(hostname).serverLogs) {
|
for (const log of getServerState(hostname).serverLogs) {
|
||||||
if (!isPasswordResponse(log.message)) {
|
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 { GetAllServers } from "../../Server/AllServers";
|
||||||
import { getNetDepth } from "../effects/labyrinth";
|
import { getNetDepth } from "../effects/labyrinth";
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
|
import { Player } from "@player";
|
||||||
|
|
||||||
export const getDarknetCyclesPerMutation = () => {
|
export const getDarknetCyclesPerMutation = () => {
|
||||||
const depth = getNetDepth();
|
const depth = getNetDepth();
|
||||||
const cycleRate = MS_PER_MUTATION_PER_ROW / CONSTANTS.MilliPerCycle;
|
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][] => {
|
export const getAllOpenPositions = (minDepth: number, maxDepth: number): [number, number][] => {
|
||||||
|
|||||||
@@ -425,7 +425,8 @@ export function NetscriptDarknet(): InternalAPI<DarknetAPI> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const server = serverCheck.server;
|
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);
|
const xp = formatNumber(calculatePasswordAttemptChaGain(server, ctx.workerScript.scriptRef.threads), 1);
|
||||||
|
|
||||||
logger(ctx)(`Captured some outgoing transmissions from ${server.hostname}. (Gained ${xp} cha xp)`);
|
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
|
* @remarks
|
||||||
* RAM cost: 0.1 GB
|
* RAM cost: 0.1 GB
|
||||||
*
|
*
|
||||||
* @returns A promise that resolves to a {@link DarknetResult} object.
|
* @returns A {@link DarknetResult} object.
|
||||||
*/
|
*/
|
||||||
unleashStormSeed(): DarknetResult;
|
unleashStormSeed(): DarknetResult;
|
||||||
|
|
||||||
@@ -7953,7 +7953,7 @@ export interface NS {
|
|||||||
* ns.scp(files, server, "home");
|
* 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 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.
|
* @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;
|
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
|
* @remarks
|
||||||
* RAM cost: 0.05 GB
|
* RAM cost: 0.05 GB
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from "../Utilities";
|
} from "../Utilities";
|
||||||
import type { ScriptFilePath } from "../../../src/Paths/ScriptFilePath";
|
import type { ScriptFilePath } from "../../../src/Paths/ScriptFilePath";
|
||||||
import { DarknetState, getServerState, triggerNextUpdate } from "../../../src/DarkNet/models/DarknetState";
|
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 { ModelIds, ResponseCodeEnum } from "../../../src/DarkNet/Enums";
|
||||||
import { getAllMovableDarknetServers } from "../../../src/DarkNet/utils/darknetNetworkUtils";
|
import { getAllMovableDarknetServers } from "../../../src/DarkNet/utils/darknetNetworkUtils";
|
||||||
import { expectRunningOnDarknetServer } from "../../../src/DarkNet/effects/offlineServerHandling";
|
import { expectRunningOnDarknetServer } from "../../../src/DarkNet/effects/offlineServerHandling";
|
||||||
@@ -878,9 +878,19 @@ describe("Non-darkweb darknet server", () => {
|
|||||||
test("authenticate from darkweb", async () => {
|
test("authenticate from darkweb", async () => {
|
||||||
const ns = getNsOnDarkWeb();
|
const ns = getNsOnDarkWeb();
|
||||||
const target = getFirstDarknetServerAdjacentToDarkWeb();
|
const target = getFirstDarknetServerAdjacentToDarkWeb();
|
||||||
const result = await ns.dnet.authenticate(target, getDarknetServerOrThrow(target).password);
|
const server = getDarknetServerOrThrow(target);
|
||||||
expect(result.success).toStrictEqual(true);
|
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.code).toStrictEqual(ResponseCodeEnum.Success);
|
||||||
|
expect(result.success).toStrictEqual(true);
|
||||||
});
|
});
|
||||||
test("authenticate itself", async () => {
|
test("authenticate itself", async () => {
|
||||||
const ns = getNsOnNonDarkwebDarknetServer();
|
const ns = getNsOnNonDarkwebDarknetServer();
|
||||||
|
|||||||
Reference in New Issue
Block a user