CONTRACTS: Generate test contracts on executing host by default. Add support for optional parameter to specify the server. (#2417)

This commit is contained in:
Paul Setzer
2025-12-16 19:23:59 -05:00
committed by GitHub
parent e7768824ba
commit 968c0c2a8c
7 changed files with 47 additions and 14 deletions

View File

@@ -9,7 +9,7 @@ Generate a dummy contract.
**Signature:**
```typescript
createDummyContract(type: CodingContractName): string | null;
createDummyContract(type: CodingContractName, host?: string): string | null;
```
## Parameters
@@ -45,6 +45,22 @@ type
Type of contract to generate
</td></tr>
<tr><td>
host
</td><td>
string
</td><td>
_(Optional)_ Hostname/IP of the server containing the contract. Optional. Defaults to the server the calling script is running on.
</td></tr>
</tbody></table>
@@ -58,7 +74,7 @@ Filename of the contract.
RAM cost: 2 GB
Generate a dummy contract on the home computer with no reward. Used to test various algorithms.
Generate a dummy contract on the current server with no reward. Used to test various algorithms.
This function will return null and not generate a contract if the randomized contract name is the same as another contract's name.

View File

@@ -38,7 +38,7 @@ Attempts a coding contract, returning a reward string on success or empty string
</td></tr>
<tr><td>
[createDummyContract(type)](./bitburner.codingcontract.createdummycontract.md)
[createDummyContract(type, host)](./bitburner.codingcontract.createdummycontract.md)
</td><td>

View File

@@ -113,16 +113,15 @@ export function generateRandomContractOnHome(): void {
serv.addContract(contract);
}
export const generateDummyContract = (problemType: CodingContractName): string | null => {
export const generateDummyContract = (problemType: CodingContractName, server: BaseServer): string | null => {
if (!CodingContractTypes[problemType]) throw new Error(`Invalid problem type: '${problemType}'`);
const serv = Player.getHomeComputer();
const contractFn = getRandomFilename(serv);
const contractFn = getRandomFilename(server);
if (contractFn == null) {
return null;
}
const contract = new CodingContract(contractFn, problemType, null);
serv.addContract(contract);
server.addContract(contract);
return contractFn;
};

View File

@@ -127,9 +127,11 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
const contract = getCodingContract(ctx, host, filename);
return contract.getMaxNumTries() - contract.tries;
},
createDummyContract: (ctx) => (_type) => {
createDummyContract: (ctx) => (_type, _host?) => {
const type = getEnumHelper("CodingContractName").nsGetMember(ctx, _type);
return generateDummyContract(type);
const host = _host ? helpers.string(ctx, "host", _host) : ctx.workerScript.hostname;
const server = helpers.getServer(ctx, host);
return generateDummyContract(type, server);
},
getContractTypes: () => () => Object.values(CodingContractName),
};

View File

@@ -4057,14 +4057,15 @@ export interface CodingContract {
* @remarks
* RAM cost: 2 GB
*
* Generate a dummy contract on the home computer with no reward. Used to test various algorithms.
* Generate a dummy contract on the current server with no reward. Used to test various algorithms.
*
* This function will return null and not generate a contract if the randomized contract name is the same as another contract's name.
*
* @param type - Type of contract to generate
* @param host - Hostname/IP of the server containing the contract. Optional. Defaults to the server the calling script is running on.
* @returns Filename of the contract.
*/
createDummyContract(type: CodingContractName): string | null;
createDummyContract(type: CodingContractName, host?: string): string | null;
/**
* List all contract types.

View File

@@ -499,11 +499,26 @@ export const breakingChanges300: VersionBreakingChange = {
showWarning: false,
},
{
brokenAPIs: [{ name: "createDummyContract" }],
brokenAPIs: [
{
name: "createDummyContract",
migration: {
searchValue: "createDummyContract",
migrator: (line: string) => {
for (const match of line.matchAll(/createDummyContract\([^,]*?\)/g)) {
line = line.replace(match[0], match[0].slice(0, match[0].length - 1) + `, "home")`);
}
return line;
},
},
},
],
info:
"ns.codingcontract.createDummyContract might generate a contract with the same name of another contract.\n" +
"This bug was fixed. Now this function will return null and not generate a contract if the randomized contract " +
"name is the same as another contract's name.",
"name is the same as another contract's name.\n\n" +
"ns.codingcontract.createDummyContract generated a dummy contract on home. Now you can specify the host that \n" +
'gets the generated contract with a new optional parameter. Your code was migrated to specify "home" as the host.',
showWarning: false,
},
],

View File

@@ -35,7 +35,7 @@ describe("Generator", () => {
assertNumberOfContracts(1, [Player.getHomeComputer()]);
});
test("generateDummyContract", () => {
generateDummyContract(CodingContractName.FindLargestPrimeFactor);
generateDummyContract(CodingContractName.FindLargestPrimeFactor, Player.getHomeComputer());
assertNumberOfContracts(1, GetAllServers());
});
// generateContract is flexible. All properties in IGenerateContractParams are optional. This test checks the usage in