mirror of
				https://github.com/SikongJueluo/cc-utils.git
				synced 2025-11-04 19:27:50 +08:00 
			
		
		
		
	finish basic autocraft for create store
This commit is contained in:
		
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
node_modules
 | 
			
		||||
*.lua
 | 
			
		||||
.DS_Store
 | 
			
		||||
event/
 | 
			
		||||
build/
 | 
			
		||||
							
								
								
									
										9
									
								
								.justfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.justfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
 | 
			
		||||
 | 
			
		||||
build: build-autocraft sync
 | 
			
		||||
 | 
			
		||||
build-autocraft:
 | 
			
		||||
    pnpm build-autocraft
 | 
			
		||||
 | 
			
		||||
sync:
 | 
			
		||||
    cp -r "./build/*" "C:\\Users\\sikongjueluo\\AppData\\Roaming\\CraftOS-PC\\computer\\0\\user\\"
 | 
			
		||||
							
								
								
									
										38
									
								
								eslint.config.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								eslint.config.mjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// @ts-check
 | 
			
		||||
 | 
			
		||||
import eslint from "@eslint/js";
 | 
			
		||||
import { defineConfig } from "eslint/config";
 | 
			
		||||
import tseslint from "typescript-eslint";
 | 
			
		||||
 | 
			
		||||
export default defineConfig(
 | 
			
		||||
  eslint.configs.recommended,
 | 
			
		||||
  ...tseslint.configs.recommendedTypeChecked,
 | 
			
		||||
  ...tseslint.configs.stylisticTypeChecked,
 | 
			
		||||
  {
 | 
			
		||||
    languageOptions: {
 | 
			
		||||
      parserOptions: {
 | 
			
		||||
        project: ["./tsconfig.json", "./tsconfig.autocraft.json"],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    rules: {
 | 
			
		||||
      "@typescript-eslint/strict-boolean-expressions": "error",
 | 
			
		||||
      "@typescript-eslint/prefer-nullish-coalescing": "error",
 | 
			
		||||
      "@typescript-eslint/no-unused-vars": [
 | 
			
		||||
        "error",
 | 
			
		||||
        {
 | 
			
		||||
          args: "all",
 | 
			
		||||
          argsIgnorePattern: "^_",
 | 
			
		||||
          caughtErrors: "all",
 | 
			
		||||
          caughtErrorsIgnorePattern: "^_",
 | 
			
		||||
          destructuredArrayIgnorePattern: "^_",
 | 
			
		||||
          varsIgnorePattern: "^_",
 | 
			
		||||
          ignoreRestSiblings: true,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    files: ["**/*.js", "**/*.mjs"],
 | 
			
		||||
    ...tseslint.configs.disableTypeChecked,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "cc-utils",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "Template project for ComputerCraft programs written in TypeScript.",
 | 
			
		||||
  "main": "main.ts",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "tstl",
 | 
			
		||||
    "build-autocraft": "tstl -p ./tsconfig.autocraft.json",
 | 
			
		||||
    "sync": "cp -r \"./build/*\"  \"C:\\Users\\sikongjueluo\\AppData\\Roaming\\CraftOS-PC\\computer\\0\\user\""
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@eslint/js": "^9.36.0",
 | 
			
		||||
    "@sikongjueluo/advanced-peripherals-types": "file:types/advanced-peripherals",
 | 
			
		||||
    "@jackmacwindows/cc-types": "file:types/cc",
 | 
			
		||||
    "@jackmacwindows/craftos-types": "file:types/craftos",
 | 
			
		||||
    "@jackmacwindows/lua-types": "^2.13.2",
 | 
			
		||||
    "@jackmacwindows/typescript-to-lua": "^1.28.1",
 | 
			
		||||
    "@typescript-to-lua/language-extensions": "^1.19.0",
 | 
			
		||||
    "eslint": "^9.36.0",
 | 
			
		||||
    "typescript": "^5.7.2",
 | 
			
		||||
    "typescript-eslint": "^8.45.0"
 | 
			
		||||
  },
 | 
			
		||||
  "author": "sikongjueluo",
 | 
			
		||||
  "license": "MIT"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1147
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1147
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										120
									
								
								src/autocraft/main.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/autocraft/main.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
import { CraftManager } from "@/lib/CraftManager";
 | 
			
		||||
import * as peripheralManager from "../lib/PeripheralManager";
 | 
			
		||||
import { CCLog } from "@/lib/ccLog";
 | 
			
		||||
 | 
			
		||||
const log = new CCLog("autocraft.log");
 | 
			
		||||
 | 
			
		||||
const peripheralsRelativeSides = {
 | 
			
		||||
  packagesContainer: "minecraft:chest_10",
 | 
			
		||||
  itemsContainer: "minecraft:chest_9",
 | 
			
		||||
  packageExtractor: "create:packager_1",
 | 
			
		||||
  blockReader: "front",
 | 
			
		||||
  wiredModem: "back",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function main() {
 | 
			
		||||
  const packagesContainer = peripheralManager.findByNameRequired(
 | 
			
		||||
    "inventory",
 | 
			
		||||
    peripheralsRelativeSides.packagesContainer,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const itemsContainer = peripheralManager.findByNameRequired(
 | 
			
		||||
    "inventory",
 | 
			
		||||
    peripheralsRelativeSides.itemsContainer,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const packageExtractor = peripheralManager.findByNameRequired(
 | 
			
		||||
    "inventory",
 | 
			
		||||
    peripheralsRelativeSides.packageExtractor,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const blockReader = peripheralManager.findByNameRequired(
 | 
			
		||||
    "blockReader",
 | 
			
		||||
    peripheralsRelativeSides.blockReader,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const wiredModem = peripheralManager.findByNameRequired(
 | 
			
		||||
    "wiredModem",
 | 
			
		||||
    peripheralsRelativeSides.wiredModem,
 | 
			
		||||
  );
 | 
			
		||||
  const turtleLocalName = wiredModem.getNameLocal();
 | 
			
		||||
 | 
			
		||||
  const craftManager = new CraftManager(turtleLocalName);
 | 
			
		||||
 | 
			
		||||
  let hasPackage = redstone.getInput("front");
 | 
			
		||||
  while (true) {
 | 
			
		||||
    if (!hasPackage) os.pullEvent("redstone");
 | 
			
		||||
    hasPackage = redstone.getInput("front");
 | 
			
		||||
    if (!hasPackage) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    log.info(`Package detected`);
 | 
			
		||||
 | 
			
		||||
    const itemsInfo = packagesContainer.list();
 | 
			
		||||
    for (const key in itemsInfo) {
 | 
			
		||||
      const slot = parseInt(key);
 | 
			
		||||
      const item = itemsInfo[slot];
 | 
			
		||||
      log.info(`${item.count}x ${item.name} in slot ${key}`);
 | 
			
		||||
 | 
			
		||||
      // Get package NBT
 | 
			
		||||
      packagesContainer.pushItems(turtleLocalName, slot);
 | 
			
		||||
      const packageInfo = blockReader.getBlockData().Items[1];
 | 
			
		||||
      // log.info(textutils.serialise(packageInfo));
 | 
			
		||||
 | 
			
		||||
      // Get recipe
 | 
			
		||||
      const packageRecipes = CraftManager.getPackageRecipe(packageInfo);
 | 
			
		||||
 | 
			
		||||
      // No recipe, just extract package
 | 
			
		||||
      if (packageRecipes == undefined) {
 | 
			
		||||
        packageExtractor.pullItems(turtleLocalName, 1);
 | 
			
		||||
        log.info(`No recipe, just pass`);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Extract package
 | 
			
		||||
      // log.info(`Get recipe ${textutils.serialise(recipe)}`);
 | 
			
		||||
      packageExtractor.pullItems(turtleLocalName, 1);
 | 
			
		||||
 | 
			
		||||
      // Pull and craft multi recipe
 | 
			
		||||
      for (const recipe of packageRecipes) {
 | 
			
		||||
        let craftOutputItem: BlockItemDetailData | undefined = undefined;
 | 
			
		||||
        let restCraftCnt = recipe.Count;
 | 
			
		||||
 | 
			
		||||
        do {
 | 
			
		||||
          // Clear workbench
 | 
			
		||||
          craftManager.pushAll(itemsContainer);
 | 
			
		||||
 | 
			
		||||
          log.info(`Pull items according to a recipe`);
 | 
			
		||||
          const craftCnt = craftManager.pullItems(
 | 
			
		||||
            recipe,
 | 
			
		||||
            itemsContainer,
 | 
			
		||||
            restCraftCnt,
 | 
			
		||||
          );
 | 
			
		||||
          if (craftCnt == 0) break;
 | 
			
		||||
          craftManager.craft();
 | 
			
		||||
          log.info(`Craft ${craftCnt} times`);
 | 
			
		||||
          restCraftCnt -= craftCnt;
 | 
			
		||||
 | 
			
		||||
          // Get output item
 | 
			
		||||
          craftOutputItem ??= blockReader.getBlockData().Items[1];
 | 
			
		||||
        } while (restCraftCnt > 0);
 | 
			
		||||
 | 
			
		||||
        // Finally output
 | 
			
		||||
        if (restCraftCnt > 0) {
 | 
			
		||||
          log.warn(`Only craft ${recipe.Count - restCraftCnt} times`);
 | 
			
		||||
        } else {
 | 
			
		||||
          log.info(`Finish craft ${recipe.Count}x ${craftOutputItem?.id}`);
 | 
			
		||||
        }
 | 
			
		||||
        craftManager.pushAll(itemsContainer);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  main();
 | 
			
		||||
} catch (error: unknown) {
 | 
			
		||||
  log.error(textutils.serialise(error as object));
 | 
			
		||||
} finally {
 | 
			
		||||
  log.close();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										203
									
								
								src/lib/CraftManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/lib/CraftManager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
			
		||||
import { CCLog } from "./ccLog";
 | 
			
		||||
 | 
			
		||||
const log = new CCLog("CraftManager.log");
 | 
			
		||||
 | 
			
		||||
// ComputerCraft Turtle inventory layout:
 | 
			
		||||
// 1,  2,  3,  4
 | 
			
		||||
// 5,  6,  7,  8
 | 
			
		||||
// 9,  10, 11, 12
 | 
			
		||||
// 13, 14, 15, 16
 | 
			
		||||
 | 
			
		||||
const TURTLE_SIZE = 16;
 | 
			
		||||
// const CRAFT_SLOT_CNT = 9;
 | 
			
		||||
const CRAFT_SLOT_TABLE: number[] = [1, 2, 3, 5, 6, 7, 9, 10, 11];
 | 
			
		||||
// const REST_SLOT_CNT = 7;
 | 
			
		||||
// const REST_SLOT_TABLE: number[] = [4, 8, 12, 13, 14, 15, 16];
 | 
			
		||||
 | 
			
		||||
interface CreatePackageTag {
 | 
			
		||||
  Items: {
 | 
			
		||||
    Items: {
 | 
			
		||||
      id: string;
 | 
			
		||||
      Count: number;
 | 
			
		||||
      Slot: number;
 | 
			
		||||
    }[];
 | 
			
		||||
    Size: number;
 | 
			
		||||
  };
 | 
			
		||||
  Fragment: {
 | 
			
		||||
    Index: number;
 | 
			
		||||
    OrderContext: {
 | 
			
		||||
      OrderedCrafts: {
 | 
			
		||||
        Pattern: {
 | 
			
		||||
          Entries: {
 | 
			
		||||
            Item: {
 | 
			
		||||
              id: string;
 | 
			
		||||
              Count: number;
 | 
			
		||||
              tag?: object;
 | 
			
		||||
            };
 | 
			
		||||
            Amount: number;
 | 
			
		||||
          }[];
 | 
			
		||||
        };
 | 
			
		||||
        Count: number;
 | 
			
		||||
      }[];
 | 
			
		||||
      OrderedStacks: {
 | 
			
		||||
        Entries: {
 | 
			
		||||
          Item: {
 | 
			
		||||
            id: string;
 | 
			
		||||
            Count: number;
 | 
			
		||||
          };
 | 
			
		||||
          Amount: number;
 | 
			
		||||
        }[];
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
    IsFinal: number;
 | 
			
		||||
    OrderId: number;
 | 
			
		||||
    LinkIndex: number;
 | 
			
		||||
    IsFinalLink: number;
 | 
			
		||||
  };
 | 
			
		||||
  Address: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface CraftRecipeItem {
 | 
			
		||||
  Item: {
 | 
			
		||||
    id: string;
 | 
			
		||||
    Count: number;
 | 
			
		||||
  };
 | 
			
		||||
  Amount: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface CraftRecipe {
 | 
			
		||||
  PatternEntries: Record<number, CraftRecipeItem>;
 | 
			
		||||
  Count: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CraftMode = "keep" | "keepProduct" | "keepIngredient";
 | 
			
		||||
 | 
			
		||||
class CraftManager {
 | 
			
		||||
  private localName: string;
 | 
			
		||||
 | 
			
		||||
  constructor(modem: WiredModemPeripheral | string) {
 | 
			
		||||
    if (turtle == undefined) {
 | 
			
		||||
      throw new Error("Script must be run in a turtle computer");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (modem == undefined) {
 | 
			
		||||
      throw new Error("Please provide a valid modem");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let name = "";
 | 
			
		||||
    if (typeof modem === "string") {
 | 
			
		||||
      name = modem;
 | 
			
		||||
    } else {
 | 
			
		||||
      if (peripheral.getType(modem) !== "modem") {
 | 
			
		||||
        throw new Error("Please provide a valid modem");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      name = modem.getNameLocal();
 | 
			
		||||
      if (name === null) {
 | 
			
		||||
        throw new Error("Please provide a valid modem");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.localName = name;
 | 
			
		||||
    // log.info(`Get turtle name : ${name}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public pushAll(outputInventory: InventoryPeripheral): void {
 | 
			
		||||
    for (let i = 1; i <= TURTLE_SIZE; i++) {
 | 
			
		||||
      outputInventory.pullItems(this.localName, i);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public craft(dstInventory?: InventoryPeripheral, limit?: number): void {
 | 
			
		||||
    turtle.craft(limit);
 | 
			
		||||
 | 
			
		||||
    if (dstInventory != undefined) {
 | 
			
		||||
      dstInventory.pullItems(this.localName, 1, limit);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getPackageRecipe(
 | 
			
		||||
    item: BlockItemDetailData,
 | 
			
		||||
  ): CraftRecipe[] | undefined {
 | 
			
		||||
    if (
 | 
			
		||||
      !item.id.includes("create:cardboard_package") ||
 | 
			
		||||
      (item.tag as CreatePackageTag)?.Fragment?.OrderContext
 | 
			
		||||
        ?.OrderedCrafts?.[0] == undefined
 | 
			
		||||
    ) {
 | 
			
		||||
      return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const orderedCraft = (item.tag as CreatePackageTag).Fragment.OrderContext
 | 
			
		||||
      .OrderedCrafts;
 | 
			
		||||
    return orderedCraft.map((value, _) => ({
 | 
			
		||||
      PatternEntries: value.Pattern.Entries,
 | 
			
		||||
      Count: value.Count,
 | 
			
		||||
    }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public pullItems(
 | 
			
		||||
    recipe: CraftRecipe,
 | 
			
		||||
    inventory: InventoryPeripheral,
 | 
			
		||||
    limit: number,
 | 
			
		||||
  ): number {
 | 
			
		||||
    let maxCraftCount = limit;
 | 
			
		||||
 | 
			
		||||
    for (const index in recipe.PatternEntries) {
 | 
			
		||||
      const entry = recipe.PatternEntries[index];
 | 
			
		||||
      if (entry.Item.Count == 0 || entry.Item.id == "minecraft:air") {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const ingredientList = inventory.list();
 | 
			
		||||
      let restCount = maxCraftCount;
 | 
			
		||||
      for (const key in ingredientList) {
 | 
			
		||||
        // Get item detail and check max count
 | 
			
		||||
        const slot = parseInt(key);
 | 
			
		||||
        const ingredient = inventory.getItemDetail(slot)!;
 | 
			
		||||
        if (entry.Item.id != ingredient.name) {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const ingredientMaxCount = ingredient.maxCount;
 | 
			
		||||
        if (maxCraftCount > ingredientMaxCount) {
 | 
			
		||||
          maxCraftCount = ingredientMaxCount;
 | 
			
		||||
          restCount = maxCraftCount;
 | 
			
		||||
        }
 | 
			
		||||
        log.info(
 | 
			
		||||
          `Slot ${slot} ${ingredient.name} max count: ${ingredientMaxCount}`,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // TODO: Process multi count entry item
 | 
			
		||||
        if (ingredient.count >= restCount) {
 | 
			
		||||
          inventory.pushItems(
 | 
			
		||||
            this.localName,
 | 
			
		||||
            slot,
 | 
			
		||||
            restCount,
 | 
			
		||||
            CRAFT_SLOT_TABLE[parseInt(index) - 1],
 | 
			
		||||
          );
 | 
			
		||||
          restCount = 0;
 | 
			
		||||
          break;
 | 
			
		||||
        } else {
 | 
			
		||||
          inventory.pushItems(
 | 
			
		||||
            this.localName,
 | 
			
		||||
            slot,
 | 
			
		||||
            ingredient.count,
 | 
			
		||||
            CRAFT_SLOT_TABLE[parseInt(index) - 1],
 | 
			
		||||
          );
 | 
			
		||||
          restCount -= ingredient.count;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (restCount > 0) return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return maxCraftCount;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  CraftManager,
 | 
			
		||||
  CraftRecipe,
 | 
			
		||||
  CraftMode,
 | 
			
		||||
  CraftRecipeItem,
 | 
			
		||||
  CreatePackageTag,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										97
									
								
								src/lib/PeripheralManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/lib/PeripheralManager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
type PeripheralType = "inventory" | "modem" | "wiredModem" | "blockReader";
 | 
			
		||||
type BlockSide = "top" | "bottom" | "left" | "right" | "front" | "back";
 | 
			
		||||
 | 
			
		||||
// Declare the function signature for findBySide
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: "inventory",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): InventoryPeripheral | undefined;
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: "modem",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): ModemPeripheral | undefined;
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: "wiredModem",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): WiredModemPeripheral | undefined;
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: "blockReader",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): BlockReaderPeripheral | undefined;
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  side: BlockSide,
 | 
			
		||||
): IPeripheral | undefined;
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  devName: string,
 | 
			
		||||
): IPeripheral | undefined;
 | 
			
		||||
 | 
			
		||||
// Implement the function signature for findBySide
 | 
			
		||||
function findByName(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  devName: string,
 | 
			
		||||
): IPeripheral | undefined {
 | 
			
		||||
  const dev = peripheral.find(
 | 
			
		||||
    devType == "wiredModem" ? "modem" : devType,
 | 
			
		||||
    (name: string, _) => {
 | 
			
		||||
      return name == devName;
 | 
			
		||||
    },
 | 
			
		||||
  )[0];
 | 
			
		||||
 | 
			
		||||
  // Seperate Modem and wiredModem
 | 
			
		||||
  if (
 | 
			
		||||
    devType == "modem" &&
 | 
			
		||||
    ((dev as ModemPeripheral).isWireless == undefined ||
 | 
			
		||||
      (dev as ModemPeripheral).isWireless() == false)
 | 
			
		||||
  )
 | 
			
		||||
    return undefined;
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    devType == "wiredModem" &&
 | 
			
		||||
    (dev as ModemPeripheral).isWireless != undefined &&
 | 
			
		||||
    (dev as ModemPeripheral).isWireless() == true
 | 
			
		||||
  )
 | 
			
		||||
    return undefined;
 | 
			
		||||
 | 
			
		||||
  return dev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Declare the function signature for findBySideRequired
 | 
			
		||||
function findByNameRequired(
 | 
			
		||||
  devType: "inventory",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): InventoryPeripheral;
 | 
			
		||||
function findByNameRequired(devType: "modem", devName: string): ModemPeripheral;
 | 
			
		||||
function findByNameRequired(
 | 
			
		||||
  devType: "wiredModem",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): WiredModemPeripheral;
 | 
			
		||||
function findByNameRequired(
 | 
			
		||||
  devType: "blockReader",
 | 
			
		||||
  devName: string,
 | 
			
		||||
): BlockReaderPeripheral;
 | 
			
		||||
function findByNameRequired<T extends IPeripheral>(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  side: BlockSide,
 | 
			
		||||
): T;
 | 
			
		||||
function findByNameRequired<T extends IPeripheral>(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  devName: string,
 | 
			
		||||
): T;
 | 
			
		||||
 | 
			
		||||
// Implement the function signature for findBySideRequired
 | 
			
		||||
function findByNameRequired<T extends IPeripheral>(
 | 
			
		||||
  devType: PeripheralType,
 | 
			
		||||
  side: string,
 | 
			
		||||
): T {
 | 
			
		||||
  const dev = findByName(devType, side);
 | 
			
		||||
  if (!dev) {
 | 
			
		||||
    throw new Error(
 | 
			
		||||
      `Required peripheral of type '${devType}' not found on side '${side}'`,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  return dev as T;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { PeripheralType, BlockSide, findByName, findByNameRequired };
 | 
			
		||||
							
								
								
									
										67
									
								
								src/lib/ccLog.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/lib/ccLog.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
enum LogLevel {
 | 
			
		||||
  Info = 0,
 | 
			
		||||
  Warn = 1,
 | 
			
		||||
  Error = 2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class CCLog {
 | 
			
		||||
  private fp: LuaFile | undefined;
 | 
			
		||||
  constructor(filename?: string) {
 | 
			
		||||
    term.clear();
 | 
			
		||||
    term.setCursorPos(1, 1);
 | 
			
		||||
    if (filename != undefined && filename.length != 0) {
 | 
			
		||||
      const filepath = shell.dir() + "/" + filename;
 | 
			
		||||
      const [file, error] = io.open(filepath, fs.exists(filepath) ? "a" : "w+");
 | 
			
		||||
      if (file != undefined) {
 | 
			
		||||
        this.fp = file;
 | 
			
		||||
      } else {
 | 
			
		||||
        throw Error(error);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getFormatMsg(msg: string, level: LogLevel): string {
 | 
			
		||||
    const date = os.date("*t");
 | 
			
		||||
    return `[ ${date.year}/${date.month}/${date.day} -- ${date.hour}:${date.min}:${date.sec} ${LogLevel[level]} ] : ${msg}\r\n`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public writeLine(msg: string, color?: Color) {
 | 
			
		||||
    let originalColor: Color = 0;
 | 
			
		||||
    if (color != undefined) {
 | 
			
		||||
      originalColor = term.getTextColor();
 | 
			
		||||
      term.setTextColor(color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Log
 | 
			
		||||
    term.write(msg);
 | 
			
		||||
    if (this.fp != undefined) {
 | 
			
		||||
      this.fp.write(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (color != undefined) {
 | 
			
		||||
      term.setTextColor(originalColor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Next line
 | 
			
		||||
    term.setCursorPos(1, term.getCursorPos()[1] + 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public info(msg: string) {
 | 
			
		||||
    this.writeLine(this.getFormatMsg(msg, LogLevel.Info), colors.green);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public warn(msg: string) {
 | 
			
		||||
    this.writeLine(this.getFormatMsg(msg, LogLevel.Warn), colors.orange);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public error(msg: string) {
 | 
			
		||||
    this.writeLine(this.getFormatMsg(msg, LogLevel.Error), colors.red);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public close() {
 | 
			
		||||
    if (this.fp !== undefined) {
 | 
			
		||||
      this.fp.close();
 | 
			
		||||
      this.fp = undefined;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										374
									
								
								src/lib/event.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								src/lib/event.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,374 @@
 | 
			
		||||
// You may comment out any events you don't need to save space. Make sure to
 | 
			
		||||
// delete them from eventInitializers as well.
 | 
			
		||||
 | 
			
		||||
export interface IEvent {
 | 
			
		||||
    get_name(): string;
 | 
			
		||||
    get_args(): any[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class CharEvent implements IEvent {
 | 
			
		||||
    public character: string = "";
 | 
			
		||||
    public get_name() {return "char";}
 | 
			
		||||
    public get_args() {return [this.character];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "char") return null;
 | 
			
		||||
        let ev = new CharEvent();
 | 
			
		||||
        ev.character = (args[1] as string);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class KeyEvent implements IEvent {
 | 
			
		||||
    public key: Key = 0;
 | 
			
		||||
    public isHeld: boolean = false;
 | 
			
		||||
    public isUp: boolean = false;
 | 
			
		||||
    public get_name() {return this.isUp ? "key_up" : "key";}
 | 
			
		||||
    public get_args() {return [this.key, (this.isUp ? null : this.isHeld)];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "key" && (args[0] as string) != "key_up")) return null;
 | 
			
		||||
        let ev = new KeyEvent();
 | 
			
		||||
        ev.key = (args[1] as number);
 | 
			
		||||
        ev.isUp = (args[0] as string) == "key_up";
 | 
			
		||||
        ev.isHeld = ev.isUp ? false : (args[2] as boolean);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class PasteEvent implements IEvent {
 | 
			
		||||
    public text: string = "";
 | 
			
		||||
    public get_name() {return "paste";}
 | 
			
		||||
    public get_args() {return [(this.text as any)];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "paste") return null;
 | 
			
		||||
        let ev = new PasteEvent();
 | 
			
		||||
        ev.text = (args[1] as string);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TimerEvent implements IEvent {
 | 
			
		||||
    public id: number = 0;
 | 
			
		||||
    public isAlarm: boolean = false;
 | 
			
		||||
    public get_name() {return this.isAlarm ? "alarm" : "timer";}
 | 
			
		||||
    public get_args() {return [this.id];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "timer" && (args[0] as string) != "alarm")) return null;
 | 
			
		||||
        let ev = new TimerEvent();
 | 
			
		||||
        ev.id = (args[1] as number);
 | 
			
		||||
        ev.isAlarm = (args[0] as string) == "alarm";
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TaskCompleteEvent implements IEvent {
 | 
			
		||||
    public id: number = 0;
 | 
			
		||||
    public success: boolean = false;
 | 
			
		||||
    public error: string | null = null;
 | 
			
		||||
    public params: any[] = [];
 | 
			
		||||
    public get_name() {return "task_complete";}
 | 
			
		||||
    public get_args() {
 | 
			
		||||
        if (this.success) return [this.id, this.success].concat(this.params);
 | 
			
		||||
        else return [this.id, this.success, this.error];
 | 
			
		||||
    }
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "task_complete") return null;
 | 
			
		||||
        let ev = new TaskCompleteEvent();
 | 
			
		||||
        ev.id = (args[1] as number);
 | 
			
		||||
        ev.success = (args[2] as boolean);
 | 
			
		||||
        if (ev.success) {
 | 
			
		||||
            ev.error = null;
 | 
			
		||||
            ev.params = args.slice(3);
 | 
			
		||||
        } else {
 | 
			
		||||
            ev.error = (args[3] as string);
 | 
			
		||||
            ev.params = [];
 | 
			
		||||
        }
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class RedstoneEvent implements IEvent {
 | 
			
		||||
    public get_name() {return "redstone";}
 | 
			
		||||
    public get_args() {return [];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "redstone") return null;
 | 
			
		||||
        let ev = new RedstoneEvent();
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TerminateEvent implements IEvent {
 | 
			
		||||
    public get_name() {return "terminate";}
 | 
			
		||||
    public get_args() {return [];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "terminate") return null;
 | 
			
		||||
        let ev = new TerminateEvent();
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DiskEvent implements IEvent {
 | 
			
		||||
    public side: string = "";
 | 
			
		||||
    public eject: boolean = false;
 | 
			
		||||
    public get_name() {return this.eject ? "disk_eject" : "disk";}
 | 
			
		||||
    public get_args() {return [this.side];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "disk" && (args[0] as string) != "disk_eject")) return null;
 | 
			
		||||
        let ev = new DiskEvent();
 | 
			
		||||
        ev.side = (args[1] as string);
 | 
			
		||||
        ev.eject = (args[0] as string) == "disk_eject";
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class PeripheralEvent implements IEvent {
 | 
			
		||||
    public side: string = "";
 | 
			
		||||
    public detach: boolean = false;
 | 
			
		||||
    public get_name() {return this.detach ? "peripheral_detach" : "peripheral";}
 | 
			
		||||
    public get_args() {return [this.side];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "peripheral" && (args[0] as string) != "peripheral_detach")) return null;
 | 
			
		||||
        let ev = new PeripheralEvent();
 | 
			
		||||
        ev.side = (args[1] as string);
 | 
			
		||||
        ev.detach = (args[0] as string) == "peripheral_detach";
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class RednetMessageEvent implements IEvent {
 | 
			
		||||
    public sender: number = 0;
 | 
			
		||||
    public message: any;
 | 
			
		||||
    public protocol: string | null = null;
 | 
			
		||||
    public get_name() {return "rednet_message";}
 | 
			
		||||
    public get_args() {return [this.sender, this.message, this.protocol];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "rednet_message") return null;
 | 
			
		||||
        let ev = new RednetMessageEvent();
 | 
			
		||||
        ev.sender = (args[1] as number);
 | 
			
		||||
        ev.message = args[2];
 | 
			
		||||
        ev.protocol = (args[3] as string);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ModemMessageEvent implements IEvent {
 | 
			
		||||
    public side: string = "";
 | 
			
		||||
    public channel: number = 0;
 | 
			
		||||
    public replyChannel: number = 0;
 | 
			
		||||
    public message: any;
 | 
			
		||||
    public distance: number = 0;
 | 
			
		||||
    public get_name() {return "modem_message";}
 | 
			
		||||
    public get_args() {return [this.side, this.channel, this.replyChannel, this.message, this.distance];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "modem_message") return null;
 | 
			
		||||
        let ev = new ModemMessageEvent();
 | 
			
		||||
        ev.side = (args[1] as string);
 | 
			
		||||
        ev.channel = (args[2] as number);
 | 
			
		||||
        ev.replyChannel = (args[3] as number);
 | 
			
		||||
        ev.message = args[4];
 | 
			
		||||
        ev.distance = (args[5] as number);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class HTTPEvent implements IEvent {
 | 
			
		||||
    public url: string = "";
 | 
			
		||||
    public handle: HTTPResponse | null = null;
 | 
			
		||||
    public error: string | null = null;
 | 
			
		||||
    public get_name() {return this.error == null ? "http_success" : "http_failure";}
 | 
			
		||||
    public get_args() {return [this.url, (this.error == null ? this.handle : this.error), (this.error != null ? this.handle : null)];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "http_success" && (args[0] as string) != "http_failure")) return null;
 | 
			
		||||
        let ev = new HTTPEvent();
 | 
			
		||||
        ev.url = (args[1] as string);
 | 
			
		||||
        if ((args[0] as string) == "http_success") {
 | 
			
		||||
            ev.error = null;
 | 
			
		||||
            ev.handle = (args[2] as HTTPResponse);
 | 
			
		||||
        } else {
 | 
			
		||||
            ev.error = (args[2] as string);
 | 
			
		||||
            if (ev.error == null) ev.error = "";
 | 
			
		||||
            ev.handle = (args[3] as HTTPResponse);
 | 
			
		||||
        }
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class WebSocketEvent implements IEvent {
 | 
			
		||||
    public handle: WebSocket | null = null;
 | 
			
		||||
    public error: string | null = null;
 | 
			
		||||
    public get_name() {return this.error == null ? "websocket_success" : "websocket_failure";}
 | 
			
		||||
    public get_args() {return [this.handle == null ? this.error : this.handle];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "websocket_success" && (args[0] as string) != "websocket_failure")) return null;
 | 
			
		||||
        let ev = new WebSocketEvent();
 | 
			
		||||
        if ((args[0] as string) == "websocket_success") {
 | 
			
		||||
            ev.handle = (args[1] as WebSocket);
 | 
			
		||||
            ev.error = null;
 | 
			
		||||
        } else {
 | 
			
		||||
            ev.error = (args[1] as string);
 | 
			
		||||
            ev.handle = null;
 | 
			
		||||
        }
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum MouseEventType {
 | 
			
		||||
    Click,
 | 
			
		||||
    Up,
 | 
			
		||||
    Scroll,
 | 
			
		||||
    Drag,
 | 
			
		||||
    Touch,
 | 
			
		||||
    Move,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class MouseEvent implements IEvent {
 | 
			
		||||
    public button: number = 0;
 | 
			
		||||
    public x: number = 0;
 | 
			
		||||
    public y: number = 0;
 | 
			
		||||
    public side: string | null = null;
 | 
			
		||||
    public type: MouseEventType = MouseEventType.Click;
 | 
			
		||||
    public get_name() {
 | 
			
		||||
        return {
 | 
			
		||||
            [MouseEventType.Click]: "mouse_click",
 | 
			
		||||
            [MouseEventType.Up]: "mouse_up",
 | 
			
		||||
            [MouseEventType.Scroll]: "mouse_scroll",
 | 
			
		||||
            [MouseEventType.Drag]: "mouse_drag",
 | 
			
		||||
            [MouseEventType.Touch]: "monitor_touch",
 | 
			
		||||
            [MouseEventType.Move]: "mouse_move"
 | 
			
		||||
        }[this.type];
 | 
			
		||||
    }
 | 
			
		||||
    public get_args() {return [(this.type == MouseEventType.Touch ? this.side : this.button), this.x, this.y];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string")) return null;
 | 
			
		||||
        let ev = new MouseEvent();
 | 
			
		||||
        const type = args[0] as string;
 | 
			
		||||
        if (type == "mouse_click") {ev.type = MouseEventType.Click; ev.button = (args[1] as number); ev.side = null;}
 | 
			
		||||
        else if (type == "mouse_up") {ev.type = MouseEventType.Up; ev.button = (args[1] as number); ev.side = null;}
 | 
			
		||||
        else if (type == "mouse_scroll") {ev.type = MouseEventType.Scroll; ev.button = (args[1] as number); ev.side = null;}
 | 
			
		||||
        else if (type == "mouse_drag") {ev.type = MouseEventType.Drag; ev.button = (args[1] as number); ev.side = null;}
 | 
			
		||||
        else if (type == "monitor_touch") {ev.type = MouseEventType.Touch; ev.button = 0; ev.side = (args[1] as string);}
 | 
			
		||||
        else if (type == "mouse_move") {ev.type = MouseEventType.Move; ev.button = (args[1] as number); ev.side = null;}
 | 
			
		||||
        else return null;
 | 
			
		||||
        ev.x = (args[2] as number);
 | 
			
		||||
        ev.y = (args[3] as number);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ResizeEvent implements IEvent {
 | 
			
		||||
    public side: string | null = null;
 | 
			
		||||
    public get_name() {return this.side == null ? "term_resize" : "monitor_resize";}
 | 
			
		||||
    public get_args() {return [this.side];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || ((args[0] as string) != "term_resize" && (args[0] as string) != "monitor_resize")) return null;
 | 
			
		||||
        let ev = new ResizeEvent();
 | 
			
		||||
        if ((args[0] as string) == "monitor_resize") ev.side = (args[1] as string);
 | 
			
		||||
        else ev.side = null;
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TurtleInventoryEvent implements IEvent {
 | 
			
		||||
    public get_name() {return "turtle_inventory";}
 | 
			
		||||
    public get_args() {return [];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "turtle_inventory") return null;
 | 
			
		||||
        let ev = new TurtleInventoryEvent();
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SpeakerAudioEmptyEvent implements IEvent {
 | 
			
		||||
    public side: string = "";
 | 
			
		||||
    public get_name() {return "speaker_audio_empty";}
 | 
			
		||||
    public get_args() {return [this.side];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "speaker_audio_empty") return null;
 | 
			
		||||
        let ev: SpeakerAudioEmptyEvent;
 | 
			
		||||
        ev.side = args[1] as string;
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ComputerCommandEvent implements IEvent {
 | 
			
		||||
    public args: string[] = [];
 | 
			
		||||
    public get_name() {return "computer_command";}
 | 
			
		||||
    public get_args() {return this.args;}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "computer_command") return null;
 | 
			
		||||
        let ev: ComputerCommandEvent;
 | 
			
		||||
        ev.args = args.slice(1);
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
class Event implements IEvent {
 | 
			
		||||
    
 | 
			
		||||
    public get_name() {return "";}
 | 
			
		||||
    public get_args() {return [(: any)];}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        if (!(typeof args[0] === "string") || (args[0] as string) != "") return null;
 | 
			
		||||
        let ev: Event;
 | 
			
		||||
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
export class GenericEvent implements IEvent {
 | 
			
		||||
    public args: any[] = [];
 | 
			
		||||
    public get_name() {return (this.args[0] as string);}
 | 
			
		||||
    public get_args() {return this.args.slice(1);}
 | 
			
		||||
    public static init(args: any[]): IEvent | null {
 | 
			
		||||
        let ev = new GenericEvent();
 | 
			
		||||
        ev.args = args;
 | 
			
		||||
        return ev;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let eventInitializers: ((args: any[]) => IEvent | null)[] = [
 | 
			
		||||
    CharEvent.init,
 | 
			
		||||
    KeyEvent.init,
 | 
			
		||||
    PasteEvent.init,
 | 
			
		||||
    TimerEvent.init,
 | 
			
		||||
    TaskCompleteEvent.init,
 | 
			
		||||
    RedstoneEvent.init,
 | 
			
		||||
    TerminateEvent.init,
 | 
			
		||||
    DiskEvent.init,
 | 
			
		||||
    PeripheralEvent.init,
 | 
			
		||||
    RednetMessageEvent.init,
 | 
			
		||||
    ModemMessageEvent.init,
 | 
			
		||||
    HTTPEvent.init,
 | 
			
		||||
    WebSocketEvent.init,
 | 
			
		||||
    MouseEvent.init,
 | 
			
		||||
    ResizeEvent.init,
 | 
			
		||||
    TurtleInventoryEvent.init,
 | 
			
		||||
    SpeakerAudioEmptyEvent.init,
 | 
			
		||||
    ComputerCommandEvent.init,
 | 
			
		||||
    GenericEvent.init
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
type Constructor<T extends {} = {}> = new (...args: any[]) => T;
 | 
			
		||||
export function pullEventRaw(filter: string | null = null): IEvent | null {
 | 
			
		||||
    let args = table.pack(...coroutine.yield(filter));
 | 
			
		||||
    for (let init of eventInitializers) {
 | 
			
		||||
        let ev = init(args);
 | 
			
		||||
        if (ev != null) return ev;
 | 
			
		||||
    }
 | 
			
		||||
    return GenericEvent.init(args);
 | 
			
		||||
}
 | 
			
		||||
export function pullEvent(filter: string | null = null): IEvent | null {
 | 
			
		||||
    let ev = pullEventRaw(filter);
 | 
			
		||||
    if (ev instanceof TerminateEvent) throw "Terminated";
 | 
			
		||||
    return ev;
 | 
			
		||||
}
 | 
			
		||||
export function pullEventRawAs<T extends IEvent>(type: Constructor<T>, filter: string | null = null): T | null {
 | 
			
		||||
    let ev = pullEventRaw(filter);
 | 
			
		||||
    if ((ev instanceof type)) return ev as T;
 | 
			
		||||
    else return null;
 | 
			
		||||
}
 | 
			
		||||
export function pullEventAs<T extends IEvent>(type: Constructor<T>, filter: string | null = null): T | null {
 | 
			
		||||
    let ev = pullEvent(filter);
 | 
			
		||||
    if ((ev instanceof type)) return ev as T;
 | 
			
		||||
    else return null;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								tsconfig.autocraft.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tsconfig.autocraft.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "https://raw.githubusercontent.com/MCJack123/TypeScriptToLua/master/tsconfig-schema.json",
 | 
			
		||||
  "extends": "./tsconfig.json",
 | 
			
		||||
  "tstl": {
 | 
			
		||||
    "luaBundle": "build/autocraft.lua",
 | 
			
		||||
    "luaBundleEntry": "src/autocraft/main.ts"
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["src/autocraft/*.ts"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "https://raw.githubusercontent.com/MCJack123/TypeScriptToLua/master/tsconfig-schema.json",
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "ESNext",
 | 
			
		||||
    "lib": ["ESNext"],
 | 
			
		||||
    "baseUrl": ".",
 | 
			
		||||
    "moduleResolution": "node",
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "types": [
 | 
			
		||||
      "@sikongjueluo/advanced-peripherals-types",
 | 
			
		||||
      "@jackmacwindows/lua-types/cc",
 | 
			
		||||
      "@jackmacwindows/craftos-types",
 | 
			
		||||
      "@jackmacwindows/cc-types",
 | 
			
		||||
      "@typescript-to-lua/language-extensions"
 | 
			
		||||
    ],
 | 
			
		||||
    "paths": {
 | 
			
		||||
      "@/*": ["./src/*"],
 | 
			
		||||
      "@jackmacwindows/craftos-types": ["./types/craftos"],
 | 
			
		||||
      "@jackmacwindows/lua-types/cc": ["./types/cc"],
 | 
			
		||||
      "@sikongjueluo/advanced-peripherals-types": [
 | 
			
		||||
        "./types/advanced-peripherals"
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "tstl": {
 | 
			
		||||
    "luaTarget": "CC",
 | 
			
		||||
    "luaLibImport": "require-minimal",
 | 
			
		||||
    "tstlVerbose": true,
 | 
			
		||||
    "noImplicitSelf": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["./*.ts", "./src/**/*.ts", "./types/**/*.ts"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								types/advanced-peripherals/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								types/advanced-peripherals/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
declare interface BlockItemDetailData {
 | 
			
		||||
  id: string;
 | 
			
		||||
  tag: object;
 | 
			
		||||
  Count: number;
 | 
			
		||||
  Slot: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare interface BlockDetailData {
 | 
			
		||||
  Items: Record<number, BlockItemDetailData>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare class BlockReaderPeripheral {
 | 
			
		||||
  getBlockData(): BlockDetailData;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								types/advanced-peripherals/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								types/advanced-peripherals/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@sikongjueluo/advanced-peripherals-types",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "TypeScript type definitions for base Advanced Peripherals APIs.",
 | 
			
		||||
  "types": "./index.d.ts",
 | 
			
		||||
  "files": [
 | 
			
		||||
    "./index.d.ts"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "SikongJueluo",
 | 
			
		||||
  "license": "MIT"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								types/cc/audio/dfpwm.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								types/cc/audio/dfpwm.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.audio.dfpwm" {
 | 
			
		||||
    export function make_encoder(): (pcm: number[]) => string;
 | 
			
		||||
    export function encode(pcm: number[]): string;
 | 
			
		||||
    export function make_decoder(): (dfpwm: string) => number[];
 | 
			
		||||
    export function decode(dfpwm: string): number[];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								types/cc/completion.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								types/cc/completion.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.completion" {
 | 
			
		||||
    export function choice(text: string, choices: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function peripheral(text: string, add_space?: boolean): string[];
 | 
			
		||||
    export function side(text: string, add_space?: boolean): string[];
 | 
			
		||||
    export function setting(text: string, add_space?: boolean): string[];
 | 
			
		||||
    export function command(text: string, add_space?: boolean): string[];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								types/cc/expect.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								types/cc/expect.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc/expect" {
 | 
			
		||||
    namespace expect {
 | 
			
		||||
        function expect(index: number, value: any, ...types: string[]): any;
 | 
			
		||||
        function field(tbl: Object|LuaTable, index: string, ...types: string[]): any;
 | 
			
		||||
        function range(num: number, min?: number, max?: number): number;
 | 
			
		||||
    }
 | 
			
		||||
    function expect(index: number, value: any, ...types: string[]): any;
 | 
			
		||||
    export = expect;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								types/cc/image/nft.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								types/cc/image/nft.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.image.nft" {
 | 
			
		||||
    type Image = {text: string, foreground: string, background: string}[];
 | 
			
		||||
    export function parse(image: string): Image;
 | 
			
		||||
    export function load(path: string): Image;
 | 
			
		||||
    export function draw(image: Image, xPos: number, yPos: number, target?: ITerminal): void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								types/cc/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								types/cc/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import "audio/dfpwm.d.ts";
 | 
			
		||||
import "completion.d.ts";
 | 
			
		||||
import "expect.d.ts";
 | 
			
		||||
import "image.nft.d.ts";
 | 
			
		||||
import "pretty.d.ts";
 | 
			
		||||
import "require.d.ts";
 | 
			
		||||
import "shell/completion.d.ts";
 | 
			
		||||
import "strings.d.ts";
 | 
			
		||||
							
								
								
									
										9
									
								
								types/cc/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								types/cc/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@jackmacwindows/cc-types",
 | 
			
		||||
    "version": "1.0.1",
 | 
			
		||||
    "description": "TypeScript type definitions for CraftOS modules.",
 | 
			
		||||
    "types": "index.d.ts",
 | 
			
		||||
    "files": ["./*.d.ts", "./audio", "./image", "./shell"],
 | 
			
		||||
    "author": "JackMacWindows",
 | 
			
		||||
    "license": "MIT"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								types/cc/pretty.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								types/cc/pretty.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.pretty" {
 | 
			
		||||
    type Doc = {};
 | 
			
		||||
    export const empty: Doc;
 | 
			
		||||
    export const space: Doc;
 | 
			
		||||
    export const line: Doc;
 | 
			
		||||
    export const space_line: Doc;
 | 
			
		||||
    export function text(text: string, color?: number): Doc;
 | 
			
		||||
    export function concat(...args: (Doc|string)[]): Doc;
 | 
			
		||||
    export function nest(depth: number, doc: Doc): Doc;
 | 
			
		||||
    export function group(doc: Doc): Doc;
 | 
			
		||||
    export function write(doc: Doc, ribbon_frac?: number): void;
 | 
			
		||||
    export function print(doc: Doc, ribbon_frac?: number): void;
 | 
			
		||||
    export function render(doc: Doc, width?: number, ribbon_frac?: number): string;
 | 
			
		||||
    export function pretty(obj: any, options?: {function_args?: boolean, function_source: boolean}): Doc;
 | 
			
		||||
    export function pretty_print(obj: any, options?: {function_args?: boolean, function_source: boolean}, ribbon_frac?: number): void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								types/cc/require.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								types/cc/require.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.require" {
 | 
			
		||||
    export function make(env: Object|LuaTable, dir: string): LuaMultiReturn<[(name: string) => any, Object|LuaTable]>;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								types/cc/shell/completion.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								types/cc/shell/completion.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.shell.completion" {
 | 
			
		||||
    export function file(shell: Object|LuaTable, text: string): string[];
 | 
			
		||||
    export function dir(shell: Object|LuaTable, text: string): string[];
 | 
			
		||||
    export function dirOrFile(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function program(shell: Object|LuaTable, text: string): string[];
 | 
			
		||||
    export function programWithArgs(shell: Object|LuaTable, text: string, previous: string[], starting: number): string[];
 | 
			
		||||
    export function help(shell: Object|LuaTable, text: string, previous: string[]): string[];
 | 
			
		||||
    export function choice(shell: Object|LuaTable, text: string, previous: string[], choices: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function peripheral(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function side(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function setting(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function command(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[];
 | 
			
		||||
    export function build(...args: (null | ((text: string, previous: string[]) => string[]) | [(text: string, previous: string[], ...args: any[]) => string[], ...any[]])[]): (index: number, arg: string, previous: string[]) => string[];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								types/cc/strings.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								types/cc/strings.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
/** @noSelfInFile **/
 | 
			
		||||
/** @noResolution **/
 | 
			
		||||
declare module "cc.strings" {
 | 
			
		||||
    export function wrap(text: string, width?: number): string[];
 | 
			
		||||
    export function ensure_width(text: string, width?: number): string;
 | 
			
		||||
    export function split(str: string, deliminator: string, plain?: boolean, limit?: number): string[];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1125
									
								
								types/craftos/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1125
									
								
								types/craftos/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								types/craftos/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								types/craftos/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@jackmacwindows/craftos-types",
 | 
			
		||||
  "version": "1.1.3",
 | 
			
		||||
  "description": "TypeScript type definitions for base CraftOS APIs.",
 | 
			
		||||
  "types": "./index.d.ts",
 | 
			
		||||
  "files": [
 | 
			
		||||
    "./index.d.ts"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "JackMacWindows",
 | 
			
		||||
  "license": "MIT"
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user