This commit is contained in:
jie 2024-11-03 20:56:43 +08:00
commit 916150eea2
17 changed files with 6510 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
./dist
node_modules/*

13
.secret.json Normal file
View File

@ -0,0 +1,13 @@
{
"main": {
"token": "",
"protocol": "http",
"hostname": "127.0.0.1",
"port": "21025",
"path": "/",
"branch": "default"
},
"local": {
"copyPath": "C:\\Users\\jie\\AppData\\Local\\Screeps\\scripts\\127_0_0_1___21025\\default"
}
}

3341
dist/main.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
dist/main.js.map.js vendored Normal file

File diff suppressed because one or more lines are too long

2763
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "screep",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rollup -cw",
"push": "rollup -cw --environment DEST:main",
"local": "rollup -cw --environment DEST:local"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-node-resolve": "^15.3.0",
"rollup": "^4.24.3",
"rollup-plugin-clear": "^2.0.7",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-screeps": "^1.0.1",
"rollup-plugin-typescript2": "^0.36.0",
"typescript": "^5.6.3"
},
"dependencies": {
"@types/lodash": "^3.10.1",
"@types/screeps": "^3.3.8",
"source-map": "^0.6.1"
}
}

57
rollup.config.mjs Normal file
View File

@ -0,0 +1,57 @@
import clear from 'rollup-plugin-clear'
import screeps from 'rollup-plugin-screeps'
import copy from 'rollup-plugin-copy'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from 'rollup-plugin-typescript2' // <== 新增这一行
let config
// 根据指定的目标获取对应的配置项
if (!process.env.DEST) console.log("未指定目标, 代码将被编译但不会上传")
else if (!(config = require("./.secret.json")[process.env.DEST])) {
throw new Error("无效目标,请检查 secret.json 中是否包含对应配置")
}
// 根据指定的配置决定是上传还是复制到文件夹
const pluginDeploy = config && config.copyPath ?
// 复制到指定路径
copy({
targets: [
{
src: 'dist/main.js',
dest: config.copyPath
},
{
src: 'dist/main.js.map',
dest: config.copyPath,
rename: name => name + '.map.js',
transform: contents => `module.exports = ${contents.toString()};`
}
],
hook: 'writeBundle',
verbose: true
}) :
// 更新 .map 到 .map.js 并上传
screeps({ config, dryRun: !config })
export default {
input: 'src/main.ts',
output: {
file: 'dist/main.js',
format: 'cjs',
sourcemap: true
},
plugins: [
// 清除上次编译成果
clear({ targets: ["dist"] }),
//打包依赖
resolve(),
//模块化依赖
commonjs(),
//编译ts
typescript({tsconfig: "./tsconfig.json"}),
// 执行上传或者复制
pluginDeploy
]
};

3
src/index.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
interface CreepMemory{
role: string
}

4
src/main.ts Normal file
View File

@ -0,0 +1,4 @@
import { errorMapper } from "./modules/errorMapping";
export const loop = errorMapper(() => {
console.log("Game Start");
})

View File

@ -0,0 +1,95 @@
/**
* 校正异常的堆栈信息
*
* 由于 rollup 会打包所有代码到一个文件所以异常的调用栈定位和源码的位置是不同的
* 本模块就是用来将异常的调用栈映射至源代码位置
*
* @see https://github.com/screepers/screeps-typescript-starter/blob/master/src/utils/ErrorMapper.ts
*/
import { SourceMapConsumer } from 'source-map'
// 缓存 SourceMap
let consumer = null
// 第一次报错时创建 sourceMap
const getConsumer = function () {
if (consumer == null) consumer = new SourceMapConsumer(require("main.js.map"))
return consumer
}
// 缓存映射关系以提高性能
const cache = {}
/**
* 使用源映射生成堆栈跟踪并生成原始标志位
* 警告 - global 重置之后的首次调用会产生很高的 cpu 消耗 (> 30 CPU)
* 之后的每次调用会产生较低的 cpu 消耗 (~ 0.1 CPU / )
*
* @param {Error | string} error 错误或原始追踪栈
* @returns {string} 映射之后的源代码追踪栈
*/
const sourceMappedStackTrace = function (error) {
const stack = error instanceof Error ? error.stack : error
// 有缓存直接用
if (cache.hasOwnProperty(stack)) return cache[stack]
const re = /^\s+at\s+(.+?\s+)?\(?([0-z._\-\\\/]+):(\d+):(\d+)\)?$/gm
let match
let outStack = error.toString()
console.log("ErrorMapper -> sourceMappedStackTrace -> outStack", outStack)
while ((match = re.exec(stack))) {
// 解析完成
if (match[2] !== "main") break
// 获取追踪定位
const pos = getConsumer().originalPositionFor({
column: parseInt(match[4], 10),
line: parseInt(match[3], 10)
})
// 无法定位
if (!pos.line) break
// 解析追踪栈
if (pos.name) outStack += `\n at ${pos.name} (${pos.source}:${pos.line}:${pos.column})`
else {
// 源文件没找到对应文件名,采用原始追踪名
if (match[1]) outStack += `\n at ${match[1]} (${pos.source}:${pos.line}:${pos.column})`
// 源文件没找到对应文件名并且原始追踪栈里也没有,直接省略
else outStack += `\n at ${pos.source}:${pos.line}:${pos.column}`
}
}
cache[stack] = outStack
return outStack
}
/**
* 错误追踪包装器
* 用于把报错信息通过 source-map 解析成源代码的错误位置
* 和原本 wrapLoop 的区别是wrapLoop 会返回一个新函数而这个会直接执行
*
* @param next 玩家代码
*/
export const errorMapper = function (next) {
return () => {
try {
// 执行玩家代码
next()
}
catch (e) {
if (e instanceof Error) {
// 渲染报错调用栈,沙盒模式用不了这个
const errorMessage = Game.rooms.sim ?
`沙盒模式无法使用 source-map - 显示原始追踪栈<br>${_.escape(e.stack)}` :
`${_.escape(sourceMappedStackTrace(e))}`
console.log(`<text style="color:#ef9a9a">${errorMessage}</text>`)
}
// 处理不了,直接抛出
else throw e
}
}
}

37
src/oldjs/builder.js Normal file
View File

@ -0,0 +1,37 @@
let util = require("util");
module.exports = {
/**@param {Creep} creep */
run: function (creep) {
if (creep.memory.working && creep.store[RESOURCE_ENERGY] == 0) {
creep.memory.working = false;
creep.say("harvest")
}
if (!creep.memory.working && creep.store.getFreeCapacity(RESOURCE_ENERGY) == 0) {
creep.memory.working = true
creep.say("builder")
}
if (creep.memory.working) {
let target = creep.room.find(FIND_CONSTRUCTION_SITES);
if (target.length > 0) {
if (creep.build(target[0]) == ERR_NOT_IN_RANGE) {
creep.moveTo(target[0], {visualizePathStyle: {stroke: "#ffaa00"}});
}
} else {
let targets = util.FindCapacity(creep);
if (targets.length > 0) {
target.sort();
if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo(targets[0], {visualizePathStyle: {stroke: "#ffaa00"}});
}
}
}
} else {
creep.memory.working = false
let sources = creep.room.find(FIND_SOURCES);
if (creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
creep.moveTo(sources[0], {visualizePathStyle: {stroke: "#ffaa00"}});
}
}
}
}

22
src/oldjs/harvester.js Normal file
View File

@ -0,0 +1,22 @@
let util = require("util")
module.exports = {
/**@param {Creep} creep */
run: function(creep){
if(creep.store.getFreeCapacity() > 0){
let sources = creep.room.find(FIND_SOURCES);
sources.sort();
if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE){
creep.moveTo(sources[0], {visualizePathStyle: {stroke: "#ffaa00"}});
}
}else{
let target = util.FindCapacity(creep);
if(target.length > 0){
if(creep.transfer(target[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE){
creep.moveTo(target[0], {visualizePathStyle: {stroke: "#ffaa00"}});
}
}
}
}
}

27
src/oldjs/main.js Normal file
View File

@ -0,0 +1,27 @@
let spawnCreeps = require("spawnCreeps");
let harvester = require("harvester")
let upgrader = require("upgrader")
let builder = require("builder")
module.exports.loop = function(){
let mainSpawn = Game.spawns["Spawn1"];
spawnCreeps.run(mainSpawn);
for(var name in Memory.creeps) {
if(!Game.creeps[name]) {
delete Memory.creeps[name];
console.log('Clearing non-existing creep memory:', name);
}
}
for (var name in Game.creeps){
let creep = Game.creeps[name];
if(creep.memory.role == "Harvester"){
harvester.run(creep);
}else if(creep.memory.role == "Upgrader"){
upgrader.run(creep)
}else if(creep.memory.role == "Builder"){
builder.run(creep)
}
}
}

72
src/oldjs/spawnCreeps.js Normal file
View File

@ -0,0 +1,72 @@
let harvesterCount = 2;
let builderCount = 3;
let upgraderCount = 6;
/**@param {StructureSpawn} spawn */
var createDefaultHarvester = (spawn) => {
let name = "Harvester" + Game.time;
return spawn.spawnCreep([WORK, CARRY, MOVE], name, { memory: { role: "Harvester" } });
}
/**@param {StructureSpawn} spawn */
var createDefaultBuilder = (spawn) => {
let name = "Builder" + Game.time;
return spawn.spawnCreep([WORK, CARRY, MOVE], name, { memory: { role: "Builder" } });
}
/**@param {StructureSpawn} spawn */
var createDefaultUpgrader = (spawn) => {
let name = "Upgrader" + Game.time;
return spawn.spawnCreep([WORK, CARRY, MOVE], name, { memory: { role: "Upgrader" } });
}
module.exports = {
/**@param {StructureSpawn} spawn*/
run: function (spawn) {
if (spawn.spawning) return;
let harvesters = _.filter(Game.creeps,
/**@param {Creep} creep*/
(creep) => {
return creep.memory.role == "Harvester";
});
let builders = _.filter(Game.creeps,
/**@param {Creep} creep*/
(creep) => {
return creep.memory.role == "Builder";
});
let upgraders = _.filter(Game.creeps,
/**@param {Creep} creep*/
(creep) => {
return creep.memory.role == "Upgrader";
});
if (harvesters.length < harvesterCount) {
if (createDefaultHarvester(spawn) == 0) {
console.log("Spawn Harvester")
}
}
if (upgraders.length < upgraderCount) {
if(createDefaultUpgrader(spawn) == 0){
console.log("Spawn Upgrader")
}
}
if (builders.length < builderCount) {
if(createDefaultBuilder(spawn) == 0){
console.log("Spawn Builder")
}
}
if (spawn.spawning) {
var spawningCreep = Game.creeps[spawn.spawning.name];
spawn.room.visual.text(
'🛠️' + spawningCreep.memory.role,
spawn.pos.x + 1,
spawn.pos.y,
{ align: 'left', opacity: 0.8 });
}
}
}

25
src/oldjs/upgrader.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
/**@param {Creep} creep */
run: function (creep) {
if (creep.memory.upgrading && creep.store[RESOURCE_ENERGY] == 0) {
creep.memory.upgrading = false;
creep.say('🔄 harvest');
}
if (!creep.memory.upgrading && creep.store.getFreeCapacity() == 0) {
creep.memory.upgrading = true;
creep.say('⚡ upgrade');
}
if (creep.memory.upgrading) {
if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
creep.moveTo(creep.room.controller, { visualizePathStyle: { stroke: '#ffffff' } });
}
}
else {
var sources = creep.room.find(FIND_SOURCES);
if (creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
creep.moveTo(sources[0], { visualizePathStyle: { stroke: '#ffaa00' } });
}
}
}
}

18
src/oldjs/util.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
/**@param {Creep} creep */
FindCapacity: function(creep){
return creep.room.find(FIND_STRUCTURES, {
/**@param {Structure} structure */
filter: (structure)=>{
let type = structure.structureType;
return ((type == STRUCTURE_EXTENSION) ||
(type == STRUCTURE_SPAWN )) &&
structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0;
}
});
},
/** @param {Creep} creep */
Log: function(creep, msg){
console.log(creep.name + " " + msg)
}
}

0
tsconfig.json Normal file
View File