Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NETSCRIPT: Add functionality and support to fully allow Players to use IP addresses in place of hostnames #1990

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from

Conversation

NagaOuroboros
Copy link
Contributor

@NagaOuroboros NagaOuroboros commented Mar 2, 2025

Motivation

While looking through the source code, I noticed that the game widely has the ability to accept IPs where it accepts hostnames. This intrigued me since IPs are randomly assigned at reset/install, making them dynamic as opposed to the static hostnames.

I began considering the idea of using primarily IPs instead of Hostnames as a challenge/aesthetic option, but quickly hit a few obstacles to doing so:

  1. The connect terminal/Singularity command fails to properly use IP addresses
  2. There is no IP equivalent to the hostname terminal command
  3. The only way to get an IP address from a hostname in a script is to use the very expensive ns.getServer("hostname").ip
  4. Core methods, like ns.scan(), return only hostnames, even though the terminal equivalent displays both hostname and IP
  5. Many API methods that take a hostname can also properly handle taking an IP in its place, but then assume later in the logic that the player passed a hostname without verifying and error/fail at these assumption points, preventing the use of IPs.
  6. The documentation and source code variable naming conventions do not properly differentiate between functions that can take either an IP or hostname, and those that can only take one or the other.

Scope

This PR's goal is to remedy these obstacles so that IPs can be consistently accessed and used across the game at the Player's option. In pursuit of this, I took the following approach:

  • In most cases, a simple documentation change and edit to variable names to indicate an IP address is a viable input was all that was needed.

  • In cases where a new method made the most sense, I implemented them with functional parity to their hostname counterparts where applicable.

  • Where it made no sense to pass an IP address instead of a hostname, I instead shored up the string checking to ensure an IP cannot be successfully passed.

  • In all cases, I ensured proper and consistent use between 'host', 'hostname', and 'ip' in both documentation and player-facing code.

Splitting this task into multiple PRs would not make sense, in my opinion, as the individual changes do not stand on their own and are more properly rolled into a single feature. This PR should be feature positive and make no regressions or major breaking changes.

New Terminal Command

  • ipaddr - Prints the current server's IP to the terminal

New API Methods

  • ns.getIP() - Returns the IP address of the script's current server
  • ns.scanByIP(host) - Functionally identical to ns.scan, but returns IP addresses
  • ns.getPurchasedServersByIP() - Functionally identical to ns.getPurchasedServers, but returns IP addresses
  • ns.dnsLookup(host) - Given a hostname, returns its IP address; or given an IP address, returns its hostname

Major Changes

  • connect - Both the terminal command and ns.singularity.connect(host) now allow IP addresses as arguments
  • ns.purchaseServer(hostname, ram) - Will not accept an IP-formatted string as a hostname
  • ns.renamePurchasedServer(hostname, newName) - Will not accept IP-formatted strings in either argument

Considerations

  • An argument could be made that dealing with the dynamic nature of the game's random IPs could merit a cheaper RAM cost than the equivalent hostname methods as a trade-off, however this PR defaults to parity in RAM cost.

  • The new ns.dnsLookup method is given a RAM cost of 0. Given that you must already have an IP or Hostname to use this method, the bidirectional conversion should be costless, as there's no functional difference in gameplay.

  • An argument could be made that ns.dnsLookup should be split into ns.dnsLookup and ns.dnsReverseLookup, which is more true-to-life. However, given the simplicity of the actual operation being performed, I found making one method instead of two was the more ergonomic choice.

  • The name for the new terminal command ipaddr is not necessarily final. Suggestions for an alternative, more 'CLI-flavored' name are welcome, and I'll happily change the name to conform whatever is more desired.

Demo Script for new NS functionality

https://gist.github.com/NagaOuroboros/6c27c61f2f478f8cb22f71c1ba894d05

@Alpheus
Copy link
Contributor

Alpheus commented Mar 2, 2025

This is a great addition, kuddos for the attention to documentation

@NagaOuroboros
Copy link
Contributor Author

Rebased onto version 2.8.0 final release.

@NagaOuroboros
Copy link
Contributor Author

NagaOuroboros commented Mar 8, 2025

Summary of cumulative changes

Removed from PR

ns.scanByIP - see new ns.scan signature
ns.getPurchasedServersByIP - see new ns.getPurchasedServers signature

New Terminal Command

  • ipaddr - Prints the current server's IP to the terminal

New API Methods

  • ns.getIP() - Returns the IP address of the script's current server
  • ns.dnsLookup(host) - Given a hostname, returns its IP address; or given an IP address, returns its hostname

Changed API Signatures

  • interface HostReturnOptions - A new @public type to control how a server identifier (hostname or IP address) is returned.
  • ns.scan(host?, returnOpts?) - New returnOpts parameter is a HostReturnOptions object. host can be null, allowing returnOpts to be used with host's default behavior.
  • ns.getPurchasedServers(returnOpts?) - New returnOpts parameter is a HostReturnOptions object.
  • ns.singularity.getCurrentServer(returnOpts?) - New returnOpts parameter is a HostReturnOptions object.

New NetscriptHelper Functions

interface CompleteHostReturnOptions - an interface with non-optional, type-validated members of the HostReturnOptions type.
helpers.hostReturnOptions(returnOpts) - validates returnOpts as a HostReturnOptions object, returning the default values for empty fields as a CompleteHostReturnOptions type.
helpers.returnServerID(server, returnOpts) - changes which identifier (hostname or IP) is returned, based on the returnOpts object, which must be of the CompleteHostReturnOptions type.

Other Changes

  • All API methods that take host as a parameter will now accept either an IP or hostname
  • connect - Both the terminal command and ns.singularity.connect(host) now allow IP addresses as arguments
  • ns.purchaseServer(hostname, ram) - Will not accept an IP-formatted string as a hostname
  • ns.renamePurchasedServer(hostname, newName) - Will not accept IP-formatted strings in either argument

Considerations

  • The name for the new terminal command ipaddr is not necessarily final. Suggestions for an alternative, more 'CLI-flavored' name are welcome, and I'll happily change the name to conform to whatever is more desired.

  • The new ns.dnsLookup method is given a RAM cost of 0. Given that you must already have an IP or Hostname to use this method, the bidirectional conversion should be costless, as there's no functional difference in gameplay.

  • An argument could be made that ns.dnsLookup should be split into ns.dnsLookup and ns.dnsReverseLookup, which is more true-to-life. However, given the simplicity of the actual operation being performed, I found making one method instead of two was the more ergonomic choice.

New Demo Script

https://gist.github.com/NagaOuroboros/552ce05724831e5368592f89ba8e6d1a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants