mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
DNET: More fixes and feedback (#2489)
* Add some re-rendering improvements to avoid the canvas and visual servers getting desynched * removed underlevelled nerf to low-level servers; improved charisma level docs * Remove offscreen dynamic culling * PR feedback; add cache file names to tooltip * Ensure stasis link servers get loaded properly; ensure darkweb has neighbors to prevent unit tests from failing; remove extra optional chaining accessors
This commit is contained in:
committed by
GitHub
parent
68700ff01f
commit
26db9f2955
@@ -8,6 +8,8 @@ Sends a network request to try to authenticate on a darkweb server. The target s
|
||||
|
||||
If successful, grants the script a session, allowing it to exec() scripts on that server, or scp() files to it. (scp() \*from\* the server is always allowed.)
|
||||
|
||||
Note that the charisma level on a server is not a requirement for authentication, but authentication takes longer if the player's charisma is below the server's charisma level.
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
|
||||
@@ -8,7 +8,7 @@ Uses an exploit to extract log data from a server by sending a malformed heartbe
|
||||
|
||||
Servers will periodically produce logs themselves, as well, which sometimes are useful, but most times are not.
|
||||
|
||||
The speed of capture scales with the number of threads used. See formulas.dnet.getHeartbleedTime for more information.
|
||||
The speed of capture scales with the number of threads used. See formulas.dnet.getHeartbleedTime for more information. Note that you cannot scrape logs from servers whose required charisma is higher than your charisma level.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ Sends a network request to try to authenticate on a darkweb server. The target s
|
||||
|
||||
If successful, grants the script a session, allowing it to exec() scripts on that server, or scp() files to it. (scp() \*from\* the server is always allowed.)
|
||||
|
||||
Note that the charisma level on a server is not a requirement for authentication, but authentication takes longer if the player's charisma is below the server's charisma level.
|
||||
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
@@ -145,7 +147,7 @@ Uses an exploit to extract log data from a server by sending a malformed heartbe
|
||||
|
||||
Servers will periodically produce logs themselves, as well, which sometimes are useful, but most times are not.
|
||||
|
||||
The speed of capture scales with the number of threads used. See formulas.dnet.getHeartbleedTime for more information.
|
||||
The speed of capture scales with the number of threads used. See formulas.dnet.getHeartbleedTime for more information. Note that you cannot scrape logs from servers whose required charisma is higher than your charisma level.
|
||||
|
||||
|
||||
</td></tr>
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
} from "../Enums";
|
||||
import { DarknetServerOptions, DnetServerBuilder } from "../models/DarknetServerOptions";
|
||||
import {
|
||||
getAllDarknetServers,
|
||||
getAllMovableDarknetServers,
|
||||
getNeighborsOnRow,
|
||||
getServersOnRowAbove,
|
||||
@@ -94,7 +95,7 @@ export const populateDarknet = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
clearDarknet(true);
|
||||
clearDarknet();
|
||||
addLabyrinth();
|
||||
addRandomDarknetServers(getNetDepth() * NET_WIDTH * SERVER_DENSITY - 10);
|
||||
addRandomDarknetServers(5 - DarknetState.Network[0].length);
|
||||
@@ -108,13 +109,13 @@ export const populateDarknet = () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const clearDarknet = (force = false) => {
|
||||
export const clearDarknet = () => {
|
||||
movePlayerIfNeeded();
|
||||
for (let i = 0; i < MAX_NET_DEPTH; i++) {
|
||||
for (let j = 0; j < NET_WIDTH; j++) {
|
||||
const server = DarknetState.Network[i]?.[j];
|
||||
if (!server) continue;
|
||||
deleteDarknetServer(server, force);
|
||||
deleteDarknetServer(server, true);
|
||||
DarknetState.Network[i][j] = null;
|
||||
}
|
||||
}
|
||||
@@ -156,9 +157,9 @@ export const loadDarknet = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const darkNetServers = getAllMovableDarknetServers();
|
||||
const darkNetServers = getAllDarknetServers();
|
||||
for (const server of darkNetServers) {
|
||||
if (isLabyrinthServer(server.hostname)) {
|
||||
if (isLabyrinthServer(server.hostname) || server.hostname === SpecialServers.DarkWeb) {
|
||||
continue;
|
||||
}
|
||||
disconnectServer(server, true);
|
||||
|
||||
@@ -203,6 +203,7 @@ export const addLowLevelServersIfNeeded = (): void => {
|
||||
const serversConnectedToDarkweb = getAllDarknetServers().filter((s) => s.depth === 0);
|
||||
if (serversConnectedToDarkweb.length <= 3) {
|
||||
addRandomDarknetServers(2, 0, true);
|
||||
addLowLevelServersIfNeeded();
|
||||
}
|
||||
if (lowLevelServers.length / (4 * NET_WIDTH) < LOW_LEVEL_SERVER_DENSITY) {
|
||||
addRandomDarknetServers(2, Math.floor(Math.random() * 4));
|
||||
|
||||
@@ -79,10 +79,9 @@ export const calculateAuthenticationTime = (
|
||||
|
||||
const threadsFactor = 1 / (1 + 0.2 * (threads - 1));
|
||||
const skillFactor = (diffFactor * chaRequired + baseDiff) / (person.skills.charisma + 100);
|
||||
const noobFactor = Math.min(0.5 + difficulty / 4, 1);
|
||||
const backdoorFactor = getBackdoorAuthTimeDebuff();
|
||||
const underleveledFactor =
|
||||
person.skills.charisma >= chaRequired ? 1 : 1.5 + (chaRequired + 50) / (person.skills.charisma + 50);
|
||||
const applyUnderleveledFactor = person.skills.charisma <= chaRequired && darknetServerData.depth > 1;
|
||||
const underleveledFactor = applyUnderleveledFactor ? 1.5 + (chaRequired + 50) / (person.skills.charisma + 50) : 1;
|
||||
const hasBootsFactor = Player.hasAugmentation(AugmentationName.TheBoots) ? 0.8 : 1;
|
||||
const hasSf15_2Factor = Player.activeSourceFileLvl(15) > 2 ? 0.8 : 1;
|
||||
const bonusTimeFactor = hasDarknetBonusTime() ? 0.75 : 1;
|
||||
@@ -90,7 +89,6 @@ export const calculateAuthenticationTime = (
|
||||
const time =
|
||||
baseTime *
|
||||
skillFactor *
|
||||
noobFactor *
|
||||
backdoorFactor *
|
||||
underleveledFactor *
|
||||
hasBootsFactor *
|
||||
|
||||
@@ -58,36 +58,33 @@ export function NetworkDisplayWrapper(): React.ReactElement {
|
||||
[draggableBackground],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const clearSubscription = DarknetEvents.subscribe(() => {
|
||||
if (canvas.current) {
|
||||
const lab = getLabyrinthDetails().lab;
|
||||
const startingDepth = lab && getServerLogs(lab, 1, true).length ? lab.depth : 0;
|
||||
const deepestServer = DarknetState.Network.flat().reduce((deepest, server) => {
|
||||
if (server?.hasAdminRights && server.depth > deepest) {
|
||||
return server.depth;
|
||||
}
|
||||
return deepest;
|
||||
}, startingDepth);
|
||||
const visibilityMargin = DarknetState.showFullNetwork ? 99 : 3;
|
||||
setNetDisplayDepth(deepestServer + visibilityMargin);
|
||||
const updateDisplay = useCallback(() => {
|
||||
if (!canvas.current) {
|
||||
return;
|
||||
}
|
||||
const visibilityMargin = DarknetState.showFullNetwork ? 99 : 3;
|
||||
const lab = getLabyrinthDetails().lab;
|
||||
const startingDepth = lab && getServerLogs(lab, 1, true).length ? lab.depth : 0;
|
||||
const deepestServerDepth = DarknetState.Network.flat().reduce(
|
||||
(deepest, server) => (server?.hasAdminRights && server.depth > deepest ? server.depth : deepest),
|
||||
startingDepth,
|
||||
);
|
||||
setNetDisplayDepth(deepestServerDepth + visibilityMargin);
|
||||
|
||||
rerender();
|
||||
drawOnCanvas(canvas.current);
|
||||
}
|
||||
});
|
||||
canvas.current && drawOnCanvas(canvas.current);
|
||||
rerender();
|
||||
drawOnCanvas(canvas.current);
|
||||
}, [rerender]);
|
||||
|
||||
useEffect(() => {
|
||||
const clearSubscription = DarknetEvents.subscribe(() => updateDisplay());
|
||||
draggableBackground.current?.addEventListener("wheel", (e) => e.preventDefault());
|
||||
scrollTo(DarknetState.netViewTopScroll, DarknetState.netViewLeftScroll);
|
||||
updateDisplay();
|
||||
|
||||
return () => {
|
||||
clearSubscription();
|
||||
};
|
||||
}, [rerender, scrollTo]);
|
||||
|
||||
useEffect(() => {
|
||||
DarknetEvents.emit();
|
||||
}, []);
|
||||
}, [updateDisplay, rerender, scrollTo]);
|
||||
|
||||
const allowAuth = (server: DarknetServer | null) =>
|
||||
!!server &&
|
||||
@@ -189,24 +186,6 @@ export function NetworkDisplayWrapper(): React.ReactElement {
|
||||
throttledZoom(wheelEvent as unknown as WheelEvent);
|
||||
};
|
||||
|
||||
const isWithinScreen = (server: DarknetServer) => {
|
||||
const { left, top } = getPixelPosition(server, true);
|
||||
const background = draggableBackground.current;
|
||||
const buffer = 600;
|
||||
const visibleAreaLeftEdge = (background?.scrollLeft ?? 0) / zoomOptions[zoomIndex];
|
||||
const visibleAreaTopEdge = (background?.scrollTop ?? 0) / zoomOptions[zoomIndex];
|
||||
const visibleAreaRightEdge =
|
||||
visibleAreaLeftEdge + ((background?.clientWidth ?? 0) / zoomOptions[zoomIndex] ** 2 || window.innerWidth);
|
||||
const visibleAreaBottomEdge =
|
||||
visibleAreaTopEdge + ((background?.clientHeight ?? 0) / zoomOptions[zoomIndex] ** 2 || window.innerHeight);
|
||||
return (
|
||||
left >= visibleAreaLeftEdge - buffer &&
|
||||
left <= visibleAreaRightEdge + buffer &&
|
||||
top >= visibleAreaTopEdge - buffer &&
|
||||
top <= visibleAreaBottomEdge + buffer
|
||||
);
|
||||
};
|
||||
|
||||
const search = (selection: string, options: string[], searchTerm: string) => {
|
||||
if (searchTerm.length === 1) {
|
||||
return;
|
||||
@@ -317,12 +296,11 @@ export function NetworkDisplayWrapper(): React.ReactElement {
|
||||
style={{ position: "absolute", zIndex: -1 }}
|
||||
></canvas>
|
||||
{darkWebRoot && <ServerStatusBox server={darkWebRoot} enableAuth={true} classes={classes} />}
|
||||
{DarknetState.Network.slice(0, netDisplayDepth).map((row, i) =>
|
||||
{DarknetState.Network.slice(0, netDisplayDepth).map((row) =>
|
||||
row.map(
|
||||
(server, j) =>
|
||||
server &&
|
||||
isWithinScreen(server) && (
|
||||
<ServerStatusBox server={server} key={`${i},${j}`} enableAuth={allowAuth(server)} classes={classes} />
|
||||
(server) =>
|
||||
server && (
|
||||
<ServerStatusBox server={server} key={server.ip} enableAuth={allowAuth(server)} classes={classes} />
|
||||
),
|
||||
),
|
||||
)}
|
||||
|
||||
@@ -48,6 +48,9 @@ export function ServerSummary({
|
||||
runningScriptNames.length > 3 ? ` +${runningScriptNames.length - 3}` : ""
|
||||
}`
|
||||
: "No running scripts on server";
|
||||
const dataCacheTooltip = `Reward caches on server: ${server.caches.slice(0, 3).join(", ")}${
|
||||
server.caches.length > 3 ? ` +${server.caches.length - 3}` : ""
|
||||
}`;
|
||||
const hasStormSeed = server.programs.includes(CompletedProgramName.stormSeed);
|
||||
const hasBackdoor = server.backdoorInstalled && !server.hasStasisLink;
|
||||
const ramBlockedDetails = formatToMaxDigits(server.blockedRam, 2) + "GB";
|
||||
@@ -65,7 +68,7 @@ export function ServerSummary({
|
||||
const components = [];
|
||||
if (cacheCount) {
|
||||
components.push(
|
||||
<Tooltip key="cache" title={<>Reward cache count: {cacheCount}</>}>
|
||||
<Tooltip key="cache" title={<>{dataCacheTooltip}</>}>
|
||||
<Typography>
|
||||
<SvgIcon component={Inventory2} className={`${classes.gold} ${classes.serverStatusIcon}`} />
|
||||
{cacheCount}
|
||||
|
||||
@@ -32,8 +32,9 @@ export const drawOnCanvas = (canvas: HTMLCanvasElement) => {
|
||||
for (const connectedServerName of server.serversOnNetwork) {
|
||||
const connectedServer = getDarknetServerOrThrow(connectedServerName);
|
||||
if (
|
||||
!connectedServer.hasAdminRights &&
|
||||
!connectedServer.serversOnNetwork.find((s) => getDarknetServerOrThrow(s).hasAdminRights)
|
||||
!connectedServer ||
|
||||
(!connectedServer.hasAdminRights &&
|
||||
!connectedServer.serversOnNetwork.find((s) => getDarknetServerOrThrow(s).hasAdminRights))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ export function DarknetDev(): React.ReactElement {
|
||||
<Tooltip title={<Typography>Create a new darkweb network.</Typography>}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
clearDarknet(true);
|
||||
clearDarknet();
|
||||
populateDarknet();
|
||||
SnackbarEvents.emit("New dark network generated", ToastVariant.SUCCESS, 2000);
|
||||
}}
|
||||
|
||||
4
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
4
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@@ -4450,6 +4450,9 @@ export interface Darknet {
|
||||
*
|
||||
* If successful, grants the script a session, allowing it to exec() scripts on that server, or scp() files to it. (scp() *from* the server is always allowed.)
|
||||
*
|
||||
* Note that the charisma level on a server is not a requirement for authentication, but authentication takes longer
|
||||
* if the player's charisma is below the server's charisma level.
|
||||
*
|
||||
* @remarks
|
||||
* RAM cost: 0.6 GB
|
||||
*
|
||||
@@ -4489,6 +4492,7 @@ export interface Darknet {
|
||||
* Servers will periodically produce logs themselves, as well, which sometimes are useful, but most times are not.
|
||||
*
|
||||
* The speed of capture scales with the number of threads used. See formulas.dnet.getHeartbleedTime for more information.
|
||||
* Note that you cannot scrape logs from servers whose required charisma is higher than your charisma level.
|
||||
*
|
||||
* @remarks
|
||||
* RAM cost: 0.6 GB
|
||||
|
||||
@@ -71,7 +71,7 @@ function getNsOnServerNearLabyrinth() {
|
||||
(hostname) => hostname !== SpecialServers.Home && hostname !== SpecialServers.DarkWeb,
|
||||
);
|
||||
if (!server) {
|
||||
clearDarknet(true);
|
||||
clearDarknet();
|
||||
populateDarknet();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user