2023-06-26 04:53:35 +02:00
|
|
|
import type { FactionName } from "@enums";
|
2021-09-09 05:47:34 +02:00
|
|
|
import { codingContractTypesMetadata, DescriptionFunc, GeneratorFunc, SolverFunc } from "./data/codingcontracttypes";
|
2019-04-11 10:37:40 +02:00
|
|
|
|
2023-04-07 06:33:51 +02:00
|
|
|
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "./utils/JSONReviver";
|
2021-10-01 19:08:37 +02:00
|
|
|
import { CodingContractEvent } from "./ui/React/CodingContractModal";
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
import { ContractFilePath, resolveContractFilePath } from "./Paths/ContractFilePath";
|
2021-05-04 01:46:04 +02:00
|
|
|
|
2018-09-14 23:03:31 +02:00
|
|
|
/* Represents different types of problems that a Coding Contract can have */
|
2021-10-15 00:45:50 +02:00
|
|
|
class CodingContractType {
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Function that generates a description of the problem */
|
2021-09-05 01:09:30 +02:00
|
|
|
desc: DescriptionFunc;
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Number that generally represents the problem's difficulty. Bigger numbers = harder */
|
2021-09-05 01:09:30 +02:00
|
|
|
difficulty: number;
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** A function that randomly generates a valid 'data' for the problem */
|
2021-09-05 01:09:30 +02:00
|
|
|
generate: GeneratorFunc;
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Name of the type of problem */
|
2021-09-05 01:09:30 +02:00
|
|
|
name: string;
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** The maximum number of tries the player gets on this kind of problem before it self-destructs */
|
2021-09-05 01:09:30 +02:00
|
|
|
numTries: number;
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Stores a function that checks if the provided answer is correct */
|
2021-09-05 01:09:30 +02:00
|
|
|
solver: SolverFunc;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
name: string,
|
|
|
|
desc: DescriptionFunc,
|
|
|
|
gen: GeneratorFunc,
|
|
|
|
solver: SolverFunc,
|
|
|
|
diff: number,
|
|
|
|
numTries: number,
|
|
|
|
) {
|
|
|
|
this.name = name;
|
|
|
|
this.desc = desc;
|
|
|
|
this.generate = gen;
|
|
|
|
this.solver = solver;
|
|
|
|
this.difficulty = diff;
|
|
|
|
this.numTries = numTries;
|
|
|
|
}
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Contract Types */
|
2022-10-03 18:12:16 +02:00
|
|
|
export const CodingContractTypes: Record<string, CodingContractType> = {};
|
2018-09-14 23:03:31 +02:00
|
|
|
|
|
|
|
for (const md of codingContractTypesMetadata) {
|
2021-09-05 01:09:30 +02:00
|
|
|
CodingContractTypes[md.name] = new CodingContractType(
|
|
|
|
md.name,
|
|
|
|
md.desc,
|
|
|
|
md.gen,
|
|
|
|
md.solver,
|
|
|
|
md.difficulty,
|
|
|
|
md.numTries,
|
|
|
|
);
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
|
2023-06-12 06:34:20 +02:00
|
|
|
// Numeric enum
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Enum representing the different types of rewards a Coding Contract can give */
|
2018-09-14 23:03:31 +02:00
|
|
|
export enum CodingContractRewardType {
|
2021-09-05 01:09:30 +02:00
|
|
|
FactionReputation,
|
|
|
|
FactionReputationAll,
|
|
|
|
CompanyReputation,
|
|
|
|
Money, // This must always be the last reward type
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
|
2023-06-12 06:34:20 +02:00
|
|
|
// Numeric enum
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Enum representing the result when trying to solve the Contract */
|
2018-09-14 23:03:31 +02:00
|
|
|
export enum CodingContractResult {
|
2021-09-05 01:09:30 +02:00
|
|
|
Success,
|
|
|
|
Failure,
|
|
|
|
Cancelled,
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** A class that represents the type of reward a contract gives */
|
2023-06-26 04:53:35 +02:00
|
|
|
export type ICodingContractReward =
|
|
|
|
| {
|
|
|
|
type: CodingContractRewardType.Money;
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
type: CodingContractRewardType.FactionReputationAll;
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
type: CodingContractRewardType.CompanyReputation;
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
type: CodingContractRewardType.FactionReputation;
|
|
|
|
name: FactionName;
|
|
|
|
};
|
2018-09-14 23:03:31 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A Coding Contract is a file that poses a programming-related problem to the Player.
|
|
|
|
* The player receives a reward if the problem is solved correctly
|
|
|
|
*/
|
|
|
|
export class CodingContract {
|
2021-09-05 01:09:30 +02:00
|
|
|
/* Relevant data for the contract's problem */
|
2022-07-18 08:28:21 +02:00
|
|
|
data: unknown;
|
2018-09-14 23:03:31 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
/* Contract's filename */
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
fn: ContractFilePath;
|
2018-09-14 23:03:31 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
/* Describes the reward given if this Contract is solved. The reward is actually
|
2018-09-14 23:03:31 +02:00
|
|
|
processed outside of this file */
|
2021-09-05 01:09:30 +02:00
|
|
|
reward: ICodingContractReward | null;
|
|
|
|
|
|
|
|
/* Number of times the Contract has been attempted */
|
|
|
|
tries = 0;
|
|
|
|
|
|
|
|
/* String representing the contract's type. Must match type in ContractTypes */
|
|
|
|
type: string;
|
|
|
|
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
constructor(fn = "default.cct", type = "Find Largest Prime Factor", reward: ICodingContractReward | null = null) {
|
|
|
|
const path = resolveContractFilePath(fn);
|
|
|
|
if (!path) throw new Error(`Bad file path while creating a coding contract: ${fn}`);
|
|
|
|
if (!CodingContractTypes[type]) {
|
2021-09-09 05:47:34 +02:00
|
|
|
throw new Error(`Error: invalid contract type: ${type} please contact developer`);
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
2021-05-01 09:17:31 +02:00
|
|
|
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
this.fn = path;
|
2021-09-05 01:09:30 +02:00
|
|
|
this.type = type;
|
|
|
|
this.data = CodingContractTypes[type].generate();
|
|
|
|
this.reward = reward;
|
|
|
|
}
|
|
|
|
|
2022-07-18 08:28:21 +02:00
|
|
|
getData(): unknown {
|
2021-09-05 01:09:30 +02:00
|
|
|
return this.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
getDescription(): string {
|
|
|
|
return CodingContractTypes[this.type].desc(this.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
getDifficulty(): number {
|
|
|
|
return CodingContractTypes[this.type].difficulty;
|
|
|
|
}
|
|
|
|
|
|
|
|
getMaxNumTries(): number {
|
|
|
|
return CodingContractTypes[this.type].numTries;
|
|
|
|
}
|
|
|
|
|
|
|
|
getType(): string {
|
|
|
|
return CodingContractTypes[this.type].name;
|
|
|
|
}
|
|
|
|
|
|
|
|
isSolution(solution: string): boolean {
|
|
|
|
return CodingContractTypes[this.type].solver(this.data, solution);
|
|
|
|
}
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Creates a popup to prompt the player to solve the problem */
|
2021-09-05 01:09:30 +02:00
|
|
|
async prompt(): Promise<CodingContractResult> {
|
|
|
|
return new Promise<CodingContractResult>((resolve) => {
|
2023-06-27 04:29:44 +02:00
|
|
|
CodingContractEvent.emit({
|
2021-10-01 19:08:37 +02:00
|
|
|
c: this,
|
|
|
|
onClose: () => {
|
|
|
|
resolve(CodingContractResult.Cancelled);
|
2021-09-05 01:09:30 +02:00
|
|
|
},
|
2021-10-01 19:08:37 +02:00
|
|
|
onAttempt: (val: string) => {
|
|
|
|
if (this.isSolution(val)) {
|
|
|
|
resolve(CodingContractResult.Success);
|
|
|
|
} else {
|
|
|
|
resolve(CodingContractResult.Failure);
|
|
|
|
}
|
|
|
|
},
|
2023-06-27 04:29:44 +02:00
|
|
|
});
|
2021-09-05 01:09:30 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Serialize the current file to a JSON save state. */
|
2022-07-15 01:00:10 +02:00
|
|
|
toJSON(): IReviverValue {
|
2021-09-05 01:09:30 +02:00
|
|
|
return Generic_toJSON("CodingContract", this);
|
|
|
|
}
|
|
|
|
|
2022-10-09 07:25:31 +02:00
|
|
|
/** Initializes a CodingContract from a JSON save state. */
|
2022-07-15 01:00:10 +02:00
|
|
|
static fromJSON(value: IReviverValue): CodingContract {
|
2021-09-05 01:09:30 +02:00
|
|
|
return Generic_fromJSON(CodingContract, value.data);
|
|
|
|
}
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
|
2023-04-07 06:33:51 +02:00
|
|
|
constructorsForReviver.CodingContract = CodingContract;
|