2022-12-30 02:28:53 +01:00
|
|
|
import { Player } from "@player";
|
2021-10-14 09:22:02 +02:00
|
|
|
import { CodingContract } from "../CodingContracts";
|
2022-12-30 02:28:53 +01:00
|
|
|
import { CodingContract as ICodingContract } from "@nsdefs";
|
2022-08-08 19:43:41 +02:00
|
|
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
2022-11-28 15:15:09 +01:00
|
|
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
2022-10-09 08:56:11 +02:00
|
|
|
import { codingContractTypesMetadata } from "../data/codingcontracttypes";
|
|
|
|
import { generateDummyContract } from "../CodingContractGenerator";
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-08-09 21:41:47 +02:00
|
|
|
export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
2022-10-12 14:49:27 +02:00
|
|
|
const getCodingContract = function (ctx: NetscriptContext, hostname: string, filename: string): CodingContract {
|
2022-08-08 19:43:41 +02:00
|
|
|
const server = helpers.getServer(ctx, hostname);
|
2021-11-20 21:01:04 +01:00
|
|
|
const contract = server.getContract(filename);
|
2021-10-14 09:22:02 +02:00
|
|
|
if (contract == null) {
|
2024-02-26 14:05:10 +01:00
|
|
|
throw helpers.errorMessage(ctx, `Cannot find contract '${filename}' on server '${hostname}'`);
|
2021-10-14 09:22:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return contract;
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
2022-11-28 15:15:09 +01:00
|
|
|
attempt: (ctx) => (answer, _filename, _hostname?) => {
|
2022-10-12 14:49:27 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
|
|
|
const contract = getCodingContract(ctx, hostname, filename);
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-10-12 14:49:27 +02:00
|
|
|
if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer))
|
|
|
|
throw new Error("The answer provided was not a number, string, or array");
|
2022-08-02 17:30:28 +02:00
|
|
|
|
2022-10-12 14:49:27 +02:00
|
|
|
// Convert answer to string.
|
2022-11-28 15:15:09 +01:00
|
|
|
// Todo: better typing for contracts, don't do this weird string conversion of the player answer
|
2022-10-12 14:49:27 +02:00
|
|
|
const answerStr = typeof answer === "string" ? answer : JSON.stringify(answer);
|
|
|
|
const creward = contract.reward;
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-10-12 14:49:27 +02:00
|
|
|
const serv = helpers.getServer(ctx, hostname);
|
|
|
|
if (contract.isSolution(answerStr)) {
|
2022-12-30 02:28:53 +01:00
|
|
|
const reward = Player.gainCodingContractReward(creward, contract.getDifficulty());
|
2022-10-12 14:49:27 +02:00
|
|
|
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
|
|
|
serv.removeContract(filename);
|
2022-11-28 15:15:09 +01:00
|
|
|
return reward;
|
2022-10-12 14:49:27 +02:00
|
|
|
} else {
|
|
|
|
++contract.tries;
|
|
|
|
if (contract.tries >= contract.getMaxNumTries()) {
|
|
|
|
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
2021-11-20 21:01:04 +01:00
|
|
|
serv.removeContract(filename);
|
2021-10-14 09:22:02 +02:00
|
|
|
} else {
|
2022-10-12 14:49:27 +02:00
|
|
|
helpers.log(
|
|
|
|
ctx,
|
|
|
|
() =>
|
|
|
|
`Coding Contract attempt '${filename}' failed. ${
|
|
|
|
contract.getMaxNumTries() - contract.tries
|
|
|
|
} attempts remaining.`,
|
|
|
|
);
|
2021-10-14 09:22:02 +02:00
|
|
|
}
|
|
|
|
|
2022-11-28 15:15:09 +01:00
|
|
|
return "";
|
2022-10-12 14:49:27 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
getContractType: (ctx) => (_filename, _hostname?) => {
|
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
|
|
|
const contract = getCodingContract(ctx, hostname, filename);
|
|
|
|
return contract.getType();
|
|
|
|
},
|
|
|
|
getData: (ctx) => (_filename, _hostname?) => {
|
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
|
|
|
const contract = getCodingContract(ctx, hostname, filename);
|
2024-02-10 10:10:19 +01:00
|
|
|
return structuredClone(contract.getData());
|
2022-10-12 14:49:27 +02:00
|
|
|
},
|
|
|
|
getDescription: (ctx) => (_filename, _hostname?) => {
|
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
|
|
|
const contract = getCodingContract(ctx, hostname, filename);
|
|
|
|
return contract.getDescription();
|
|
|
|
},
|
|
|
|
getNumTriesRemaining: (ctx) => (_filename, _hostname?) => {
|
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
|
|
|
const contract = getCodingContract(ctx, hostname, filename);
|
|
|
|
return contract.getMaxNumTries() - contract.tries;
|
|
|
|
},
|
|
|
|
createDummyContract: (ctx) => (_type) => {
|
|
|
|
const type = helpers.string(ctx, "type", _type);
|
2024-03-02 05:12:04 +01:00
|
|
|
return generateDummyContract(type);
|
2022-10-12 14:49:27 +02:00
|
|
|
},
|
|
|
|
getContractTypes: () => () => codingContractTypesMetadata.map((c) => c.name),
|
2021-10-14 09:22:02 +02:00
|
|
|
};
|
|
|
|
}
|