2022-08-09 21:41:47 +02:00
|
|
|
import { Player as player } from "../Player";
|
2021-10-14 09:22:02 +02:00
|
|
|
import { CodingContract } from "../CodingContracts";
|
2022-03-30 02:29:05 +02:00
|
|
|
import { CodingAttemptOptions, CodingContract as ICodingContract } from "../ScriptEditor/NetscriptDefinitions";
|
2022-08-08 19:43:41 +02:00
|
|
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
|
|
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-08-09 21:41:47 +02:00
|
|
|
export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
2022-05-08 01:08:07 +02:00
|
|
|
const getCodingContract = function (
|
|
|
|
ctx: NetscriptContext,
|
|
|
|
func: string,
|
|
|
|
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) {
|
2022-08-08 19:43:41 +02:00
|
|
|
throw helpers.makeRuntimeErrorMsg(ctx, `Cannot find contract '${filename}' on server '${hostname}'`);
|
2021-10-14 09:22:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return contract;
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
2022-05-08 01:08:07 +02:00
|
|
|
attempt:
|
|
|
|
(ctx: NetscriptContext) =>
|
|
|
|
(
|
2022-07-20 17:50:26 +02:00
|
|
|
answer: unknown,
|
2022-05-08 01:08:07 +02:00
|
|
|
_filename: unknown,
|
2022-08-09 21:41:47 +02:00
|
|
|
_hostname: unknown = ctx.workerScript.hostname,
|
2022-05-08 01:08:07 +02:00
|
|
|
{ returnReward }: CodingAttemptOptions = { returnReward: false },
|
|
|
|
): boolean | string => {
|
2022-08-08 19:43:41 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
2022-05-08 01:08:07 +02:00
|
|
|
const contract = getCodingContract(ctx, "attempt", hostname, filename);
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-08-02 17:30:28 +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:11:49 +02:00
|
|
|
// Convert answer to string.
|
2022-08-28 04:32:48 +02:00
|
|
|
const answerStr = typeof answer === "string" ? answer : JSON.stringify(answer);
|
2022-05-08 01:08:07 +02:00
|
|
|
const creward = contract.reward;
|
|
|
|
if (creward === null) throw new Error("Somehow solved a contract that didn't have a reward");
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-08-08 19:43:41 +02:00
|
|
|
const serv = helpers.getServer(ctx, hostname);
|
2022-07-20 17:50:26 +02:00
|
|
|
if (contract.isSolution(answerStr)) {
|
2022-05-08 01:08:07 +02:00
|
|
|
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
2022-08-08 21:51:50 +02:00
|
|
|
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
2021-11-20 21:01:04 +01:00
|
|
|
serv.removeContract(filename);
|
2022-05-08 01:08:07 +02:00
|
|
|
return returnReward ? reward : true;
|
2021-10-14 09:22:02 +02:00
|
|
|
} else {
|
2022-05-08 01:08:07 +02:00
|
|
|
++contract.tries;
|
|
|
|
if (contract.tries >= contract.getMaxNumTries()) {
|
2022-08-08 21:51:50 +02:00
|
|
|
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
2022-05-08 01:08:07 +02:00
|
|
|
serv.removeContract(filename);
|
|
|
|
} else {
|
2022-08-08 21:51:50 +02:00
|
|
|
helpers.log(
|
|
|
|
ctx,
|
2022-05-08 01:08:07 +02:00
|
|
|
() =>
|
|
|
|
`Coding Contract attempt '${filename}' failed. ${
|
|
|
|
contract.getMaxNumTries() - contract.tries
|
|
|
|
} attempts remaining.`,
|
|
|
|
);
|
2021-10-14 09:22:02 +02:00
|
|
|
}
|
2022-05-08 01:08:07 +02:00
|
|
|
|
|
|
|
return returnReward ? "" : false;
|
2021-10-14 09:22:02 +02:00
|
|
|
}
|
2022-05-08 01:08:07 +02:00
|
|
|
},
|
|
|
|
getContractType:
|
|
|
|
(ctx: NetscriptContext) =>
|
2022-08-09 21:41:47 +02:00
|
|
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
2022-08-08 19:43:41 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
2022-05-08 01:08:07 +02:00
|
|
|
const contract = getCodingContract(ctx, "getContractType", hostname, filename);
|
|
|
|
return contract.getType();
|
|
|
|
},
|
|
|
|
getData:
|
|
|
|
(ctx: NetscriptContext) =>
|
2022-08-09 21:41:47 +02:00
|
|
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): unknown => {
|
2022-08-08 19:43:41 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
2022-05-08 01:08:07 +02:00
|
|
|
const contract = getCodingContract(ctx, "getData", hostname, filename);
|
|
|
|
const data = contract.getData();
|
2022-07-18 08:28:21 +02:00
|
|
|
if (Array.isArray(data)) {
|
2022-05-08 01:08:07 +02:00
|
|
|
// For two dimensional arrays, we have to copy the internal arrays using
|
|
|
|
// slice() as well. As of right now, no contract has arrays that have
|
|
|
|
// more than two dimensions
|
|
|
|
const copy = data.slice();
|
|
|
|
for (let i = 0; i < copy.length; ++i) {
|
|
|
|
if (data[i].constructor === Array) {
|
|
|
|
copy[i] = data[i].slice();
|
|
|
|
}
|
|
|
|
}
|
2021-10-14 09:22:02 +02:00
|
|
|
|
2022-05-08 01:08:07 +02:00
|
|
|
return copy;
|
|
|
|
} else {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getDescription:
|
|
|
|
(ctx: NetscriptContext) =>
|
2022-08-09 21:41:47 +02:00
|
|
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
2022-08-08 19:43:41 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
2022-05-08 01:08:07 +02:00
|
|
|
const contract = getCodingContract(ctx, "getDescription", hostname, filename);
|
|
|
|
return contract.getDescription();
|
|
|
|
},
|
|
|
|
getNumTriesRemaining:
|
|
|
|
(ctx: NetscriptContext) =>
|
2022-08-09 21:41:47 +02:00
|
|
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): number => {
|
2022-08-08 19:43:41 +02:00
|
|
|
const filename = helpers.string(ctx, "filename", _filename);
|
|
|
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
2022-05-08 01:08:07 +02:00
|
|
|
const contract = getCodingContract(ctx, "getNumTriesRemaining", hostname, filename);
|
|
|
|
return contract.getMaxNumTries() - contract.tries;
|
|
|
|
},
|
2021-10-14 09:22:02 +02:00
|
|
|
};
|
|
|
|
}
|