前置依赖+获取当前账号x-token
let xToken
let updateXToken = ()=>{
if(!xToken){
let t = window.location.href
window.location.href = t+"1"
window.location.href = t
}
}
if(!XMLHttpRequest.prototype._open){
XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (...args) {
return XMLHttpRequest.prototype._open.apply(this, args);
};
let responseHook = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, "response");
let responseProcess = e=>e;
responseProcess = e=>{return e};
Object.defineProperty(XMLHttpRequest.prototype, "response", {
get: function () {
let response = responseHook.get.call(this);
response=responseProcess(response)
return response;
},
set: function (str) {
return responseHook.set.call(this, str);
},
configurable: true,
});
let sendProcess = (req)=>{
const oldOnreadystatechange = req.onreadystatechange
req.onreadystatechange = function () {
oldOnreadystatechange && oldOnreadystatechange(arguments)
const headers = this.getAllResponseHeaders()
let xt = headers.split("\n").filter(e=>e.indexOf("x-token")>=0)[0]
// console.log(headers)
if(xt){
xt = xt.replace("x-token:","").trim()
if(xt.length)xToken = xt
}
}
};
XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send
XMLHttpRequest.prototype.send = function () {
sendProcess(this);
XMLHttpRequest.prototype._send.apply(this, arguments);
}
updateXToken();
}
let servers = {screeps: 'https://screeps.com'}
const $get = (path ,params, headers={}, server = 'screeps') => {
const url = /http/.test(path) ? path : servers[server] + path
return JSON.parse($.ajax({ url, params, method: 'get', headers ,async:false}).responseText)
}
const $post = (path, data = {}, headers = {}, server= 'screeps') => {
data = JSON.stringify(data)
const url = /http/.test(path) ? path : servers[server] + path
return JSON.parse($.ajax({ url:url,contentType:"application/json;charset=UTF-8", dataType:'json', data:data, method: 'post', headers: headers ,async:false}).responseText)
}
查看某个人的全部资源
let player = "likeafox"
let id = $get("/api/user/find?username="+player, {}, { 'x-token': xToken }).user._id
let playerRooms = $get("/api/user/rooms?reservation&id="+id, {}, { 'x-token': xToken })
let addStore = (store,b)=> {for(let v in b) if(b[v]>0)store[v]=(store[v]||0)+b[v];return store}
let all = {}
Object.keys(playerRooms.shards).forEach(shard=>{
playerRooms.shards[shard].forEach(rn=>{
let room = $get("/api/game/room-objects?room="+rn+"&shard="+shard, {}, { 'x-token': xToken })
let storages = room.objects.filter(e=>e.type=="storage"||e.type=="terminal"||e.type=="factory")
storages.forEach(e=>addStore(all,e.store))
// console.log(storages.map(e=>e))
})
})
all
自动上背景贴纸(墙壁、地板)
let id = $get("/api/auth/me", {}, { 'x-token': xToken })._id;
let invs = $get("/api/user/decorations/inventory", {}, { 'x-token': xToken }).list;
let playerRooms = $get("/api/user/rooms?reservation&id="+id, {}, { 'x-token': xToken });
["wallLandscape","floorLandscape"].forEach(type=>{
let vis = invs.filter(e=>e.active&&e.decoration.rarity==3&&e.decoration.type==type).map(e=>e.active.shard+"_"+e.active.room)
let needs = Object.keys(playerRooms.reservations).map(shard=> playerRooms.reservations[shard].map(rn=>[shard,rn])).flat().filter(e=>vis.indexOf(e[0]+"_"+e[1])==-1)
let inv = invs.filter(e=>!e.active&&e.decoration.rarity==3&&e.decoration.type==type)
console.log(inv,needs,_.zip(inv,needs))
_.zip(inv,_.shuffle(needs)).filter(e=>e[0]&&e[1]).forEach(a=>{
let active = {}
if(!a[0].decoration)console.log(a[0])
Object.keys(a[0].decoration.props).forEach(e=>{
active[e]=a[0].decoration.props[e].default
})
active.shard=a[1][0]
active.room=a[1][1]
let data = {_id:a[0]._id,active:active}
console.log(data)
console.log($post("/api/user/decorations/activate", data, { 'x-token': xToken}))
})
})
自动上Creep皮肤
let id = $get("/api/auth/me", {}, { 'x-token': xToken })._id;
let invs = $get("/api/user/decorations/inventory", {}, { 'x-token': xToken }).list;
let avoid = new Set(["C-00127:CC:Y","C-00071:CC:X","C-00227:CC:Y","C-00160:CC:X","C-00024:DE:A","C-00096:CC:X","C-00226:CC:X","C-00103:CC:Y","C-00098:CC:X"])
let creepSkins = invs.filter(e=>e.decoration.type=="creep"&&e.active&&!avoid.has(e.decoration.name))
let getNameFilter = (n)=>{
let base36 = Math.pow(36,2)
let randomId = ()=>_.padLeft(Math.ceil(Math.random()*base36).toString(36).toLocaleUpperCase(),2,"0")
let result = ""
let set = new Set()
for(let i=0;i<n;i++){
let p = randomId()
if(set.has(p)) i-=1
else{
if(i>0)result+="!SEP!"
set.add(p)
result+=p
}
}
return result
}
creepSkins.forEach(e=>{
e.active.nameFilter = getNameFilter(18)
e.active.exclude = false
let data = {_id:e._id,active:e.active}
console.log(data)
console.log($post("/api/user/decorations/deactivate", {decorations:[e._id]}, { 'x-token': xToken}))
console.log($post("/api/user/decorations/activate", data, { 'x-token': xToken}))
})
对应的creep的名字生成原理
let base36 = Math.pow(36,10)
randomId = ()=>_.padLeft(Math.ceil(Math.random()*base36).toString(36).toLocaleUpperCase(),10,"0")
自动上贴纸
/**
* 全自动上1-3级贴图
* 会检测已有的贴图不会重叠
* 默认按位置大小从大到小先放置(全局)
* 控制台会输出贴图位置
* 如果上错了,可以按日期来取消贴图
*/
let getRoomTerrain = (shard,room)=>Array(...$get("/api/game/room-terrain?room="+room+"&shard="+shard+"&encoded=1", {}, { 'x-token': xToken }).terrain[0].terrain);
let id = $get("/api/auth/me", {}, { 'x-token': xToken })._id;
let playerRooms = $get("/api/user/rooms?reservation&id="+id, {}, { 'x-token': xToken });
let invs =()=> $get("/api/user/decorations/inventory", {}, { 'x-token': xToken }).list;
let items = ()=> invs().filter(e=>!e.active&&e.decoration.rarity<=3&&e.decoration.type=="wallGraffiti")
let active_item = ()=> invs().filter(e=>e.active&&e.decoration.type=="wallGraffiti")
let roomDpStr=(terr)=>{let str = "";for(let x=0;x<50;x++){for(let y=0;y<50;y++) {let p = terr[x*50+y];str+=(p>0?p:" ")+" "}str+="\n"}return str}
let roomTerrStr=(terr)=>{let str = "";for(let x=0;x<50;x++){for(let y=0;y<50;y++) {let p = terr[x*50+y];if(p==0||p>=4)str+=" █░▒ϟ/".charAt(p);str+=" █░▒ϟ/".charAt(p)}str+="\n"}return str}
let clearTerr=(terr,xx,yy,h,w,n)=>{for(let x=0;x<h;x++){for(let y=0;y<w;y++){terr[parseInt(xx-x)*50+parseInt(yy-y)]=n}}}
let dpRoom = (terr)=>{
let arr = []
for(let i=0;i<50;i++){for(let j=0;j<50;j++) {
let cur = 1;
let left = i>0?arr[i*50-50+j]:0;
let top = j>0?arr[i*50+j-1]:0;
let left_top = (j>0&&i>0)?arr[i*50+j-51]:0;
cur=Math.min(left+1,top+1,left_top+1)
if(terr[i*50+j]!="1")cur = 0
arr.push(cur)
}}
return arr
}
let avoidSize = 9;// 超过多大的空间不给放,用来放 紫色和金色的
let rooms = Object.keys(playerRooms.shards).flatMap(shard=>playerRooms.shards[shard].map(e=>[shard,e]))
rooms.forEach(roomCur=>{
// let roomCur = ["shard2","E56S29"]
// let roomCur = ['shard2', 'E54S28']
let roomCurItems = active_item().filter(e=>e.active&&e.active.shard==roomCur[0]&&e.active.room==roomCur[1])
let terrain = getRoomTerrain (...roomCur)
roomCurItems.forEach(e=>{for(let x=0;x<e.active.height;x++){for(let y=0;y<e.active.width;y++){terrain[parseInt(e.active.y+x)*50+parseInt(e.active.x+y)]=4}}})
let dp = dpRoom(terrain)
if (dp.filter(e => e >= avoidSize).length) {
dp.forEach((e,i)=>{
if(e<avoidSize)return;
clearTerr(terrain,i/50,i%50,e,e,5)
})
console.log("https://screeps.com/a/#!/room/"+roomCur.join("/"))
console.log("%c"+roomTerrStr(terrain),"font-family: Monospace;")
}
roomCur.push(terrain)
roomCur.push(Math.max(...dpRoom(terrain)))
})
let minSize = 5;
Array.prototype.randomGet= function(){return this[Math.floor(this.length*Math.random())]};
let tryCnt = items().length
let activeId = []
while(tryCnt>0){tryCnt--;
let maxRoom = Math.max(...rooms.map(e=>e[3]))
let roomCur = rooms.filter(e=>e[3]==maxRoom).randomGet()
let roomCurItems = active_item().filter(e=>e.active&&e.active.shard==roomCur[0]&&e.active.room==roomCur[1])
let terrain = roomCur[2]
roomCurItems.forEach(e=>{for(let x=0;x<e.active.height;x++){for(let y=0;y<e.active.width;y++){terrain[parseInt(e.active.y+x)*50+parseInt(e.active.x+y)]=4}}})
let dp = dpRoom(terrain)
let max = Math.max(...dp)
let pos = dp.map((e,i)=>[e,i]).filter(e=>e[0]>=minSize&&e[0]==max).randomGet()
if(!pos)break;
clearTerr(terrain,pos[1]/50,pos[1]%50,pos[0],pos[0],5)
console.log("%c"+roomTerrStr(terrain),"font-family: Monospace;")
roomCur[3]=Math.max(...dpRoom(terrain))
let it = items().randomGet();
it.active={}
Object.keys(it.decoration.props).forEach(e=>{
it.active[e]=it.decoration.props[e].default
})
it.active.x = pos[1]%50-pos[0]+1
it.active.y = Math.floor(pos[1]/50)-pos[0]+1
it.active.height=pos[0]
it.active.width=pos[0]
it.active.shard=roomCur[0]
it.active.room=roomCur[1]
activeId.push(it._id)
let data = {_id:it._id,active:it.active}
console.log($post("/api/user/decorations/activate", data, { 'x-token': xToken}))
}
creeps 死亡情况
const CHAR_0 = '0'.charCodeAt(0)
const MAP_DIRECT = {E:1,N:-1,W:-1,S:1} //东西南北坐标
const MAP_OFFSET = {E:0,N:-1,W:-1,S:0} //东西南北坐标
let getRoomCoordinate = function (roomName) {
let tmp={x:0,y:0}
let sh = 0;
let pow = 1;
for(let i=roomName.length-1;i>=0;i--){
let cc = roomName.charCodeAt(i)-CHAR_0;
if(cc>=0&&cc<=9){
if(sh==0){
tmp.y+=cc*pow
}else{
tmp.x+=cc*pow
}
pow*=10;
}else{
let c = roomName[i];
if(sh==0){
tmp.y*=MAP_DIRECT[c]
tmp.y+=MAP_OFFSET[c]
}else{
tmp.x*=MAP_DIRECT[c]
tmp.x+=MAP_OFFSET[c]
}
pow = 1
sh+=1
}
}
return tmp
}
function getRoomNameByXY (x,y) {
if(x.x){
y=x.y
x=x.x
}
return `${x >= 0 ? "E" : "W"}${x >= 0 ? x : -1 - x}${y >= 0 ? "S" : "N"}${y >= 0 ? y : -1 - y}`;
}
function isHighWay(roomName){
let cnt=0
for(let i=roomName.length-1;i>=0;i--) {
if (roomName.charCodeAt(i) == CHAR_0) {
cnt+=1
}
}
return cnt>=1
}
// let id = $get("/api/user/find?username=Tigga", {}, { 'x-token': xToken }).user._id
let id = $get("/api/auth/me", {}, { 'x-token': xToken })._id;
let playerRooms = $get("/api/user/rooms?reservation&id="+id, {}, { 'x-token': xToken });
function isMyRoom(shard,roomName){
return playerRooms.reservations[shard].concat(playerRooms.shards[shard]).filter(e=>e==roomName).length!=0
}
// let stateName = "creepsLost"+180
let stateName = "creepsLost"+1440
playerRooms
let allDead = Object.keys(playerRooms.shards).map(shard=> {
let allRooms = playerRooms.reservations[shard].concat(playerRooms.shards[shard])
let myRemoterRooms = Array.from(new Set(allRooms.map(getRoomCoordinate).map(pos=>{
let arr = []
for(let i=-10;i<=10;i++){
for(let j=-10;j<=10;j++) {
arr.push({
x:pos.x+i,
y:pos.y+j,
})
}
}
return arr
}).flat().map(getRoomNameByXY)))
let data = $post("/api/game/map-stats", {rooms:myRemoterRooms,shard:shard,statName: stateName}, { 'x-token': xToken });
return Object.entries(data.stats).map(e=>{e[1].shard = shard;e[1].roomName = e[0];return e[1];})
}).flat().filter(e=>e[stateName]).filter(e=>e[stateName].filter(t=>t.user==id).length).flat().map(e=>{
return [e.shard,e.roomName,e[stateName].filter(t=>t.user==id)[0].value]
}).sort((a,b)=>b[2]-a[2])
// .map(e=>e.value).reduce((a,b)=>a+b,0)
console.log("过道死亡:"+allDead.filter(e=>isHighWay(e[1])).map(e=>e[2]).reduce((a,b)=>a+b,0))
console.log("外矿死亡:"+allDead.filter(e=>isMyRoom(e[0],e[1])).map(e=>e[2]).reduce((a,b)=>a+b,0))
console.log("其他死亡:"+allDead.filter(e=>!isHighWay(e[1])&&!isMyRoom(e[0],e[1])).map(e=>e[2]).reduce((a,b)=>a+b,0))