screeps游戏 打接口

2022-07-23  本文已影响0人  6g3y

前置依赖+获取当前账号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"])
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}))
}
image.png

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))

上一篇下一篇

猜你喜欢

热点阅读