猫史档案馆


官方代码&&问题出在哪

用户:TBRO魔导师TBRO魔导师查看:0 回复:1 评论:0 创建时间:2022-02-05T19:26:06


async function initTable() {//创建玩家数据表
    return await db.sql`
        CREATE TABLE IF NOT EXISTS "player" (
            "coin" INT NOT NULL,--金币
            "exp" INT NOT NULL,--经验
            "item" TEXT NOT NULL,--物品列表
            "userKey" CHAR(16) PRIMARY KEY UNIQUE NOT NULL --用户识别码
        )
    `;
}
async function saveUser(user) {//玩家存档
    await db.sql`
        INSERT INTO "player" (-- player虽然是小写, 建议统一用""包住
            "exp",-- 经验
            "coin",-- 金币
            "item",-- 道具
            "userKey"-- 用户识别码
        ) VALUES (
            ${user.exp}, --尝试新建经验值
            ${user.coin}, --尝试新建金币值
            ${JSON.stringify(user.item)}, --尝试新建道具值
            ${user.player.userKey} --尝试新建当前玩家识别码
        )
        ON CONFLICT("userKey") -- 如果已经存在同样的用户识别码
        DO UPDATE SET
            "exp"=excluded."exp",-- 更新经验值
            "coin"=excluded."coin",-- 虽然是小写, 建议统一用""包住
            "item"=excluded."item"-- 虽然是小写, 建议统一用""包住
    `
}
async function loadUser(user) {//玩家读档
    const [data] = await db.sql`SELECT * FROM "player" WHERE "userKey"=${user.player.userKey} LIMIT 1`
    if (data) {//如果这个玩家已经有存档
        user.exp = data.exp
        user.coin = data.coin
        user.item = JSON.parse(data.item)
    }
    else {//玩家无存档
        saveUser(user)
    }
}
async function deleteUser(user) {//删除玩家存档
    await db.sql`DELETE FROM "player" WHERE "userKey"=${user.player.userKey}`
}
async function showAllPlaySideUser() {//显示游玩端玩家数据, 地图发布后运行才不会报错
    for (const e of await db.sql`SELECT * FROM play."player"`) {
        console.log(JSON.stringify(e))
    }
}

async function showAllEditSideUser() {//显示编辑端玩家数据
    for (const e of await db.sql`SELECT * FROM edit."player"`) {
        console.log(JSON.stringify(e))
    }
}

async function poll(fn, msg) {//无限轮询执行sql语句直到成功
    while (true) {
        try {
            return await fn()//一旦成功执行, 停止无限轮询, 并返回查询结果
        } catch (e) {
            const m = e.message//需要简略显示的异常消息
            //sql偶尔会执行超时, 但如果反复显示timeout 15秒以上一直不停, 大概是数据库出了故障只能等官方修复
            if (m.includes('timeout')) {
                world.say(m)
            }
            else {
                world.say(msg || e.stack)//如果sql执行出错, 广播错误消息, 用来排查错误原因
            }
        }
        await sleep(2000) //每2秒重试一次
    }
}

poll(initTable, '等待pg数据库启动中...')

world.onPlayerJoin(async ({ entity }) => {
    //初始化玩家属性
    entity.exp = 0
    entity.coin = 50
    entity.item = ['剑', '盾']

    await loadUser(entity)//尝试读取存档

    entity.onVoxelContact(() => {//每走1格增加1经验
        entity.coin += 1
    })

    entity.player.onPress(async ({ button }) => {//右键显示状态栏
        if (button == Box3ButtonType.ACTION1) {
            const sel = await entity.player.dialog({
                type: Box3DialogType.SELECT,
                content: `
                金币:${entity.coin}
                经验:${entity.exp}
                道具:[${entity.item}]
                `,
                options: ['保存','删档'],
            })
            if (sel) {
                if (sel.value == '保存') {
                    await saveUser(entity)
                    entity.player.directMessage('保存完毕')
                }
                else if (sel.value == '删档') {
                    await deleteUser(entity)
                    entity.player.directMessage('删档完毕')
                }
               
            }
        }
    })
})
async function initTable() {//创建玩家数据表
    return await db.sql`
        CREATE TABLE IF NOT EXISTS "player" (
            "money" INT NOT NULL,--金币
            "lv" INT NOT NULL,--经验
            "item" TEXT NOT NULL,--物品列表
            "userKey" CHAR(16) PRIMARY KEY UNIQUE NOT NULL --用户识别码
        )
    `;
}
async function saveUser(user) {//玩家存档
    await db.sql`
        INSERT INTO "player" (-- player虽然是小写, 建议统一用""包住
            "lv",-- 经验
            "money",-- 金币
            "item",-- 道具
            "userKey"-- 用户识别码
        ) VALUES (
            ${user.exp}, --尝试新建经验值
            ${user.money}, --尝试新建金币值
            ${JSON.stringify(user.item)}, --尝试新建道具值
            ${user.player.userKey} --尝试新建当前玩家识别码
        )
        ON CONFLICT("userKey") -- 如果已经存在同样的用户识别码
        DO UPDATE SET
            "lv"=excluded."lv",-- 更新经验值
            "money"=excluded."money",-- 虽然是小写, 建议统一用""包住
            "item"=excluded."item"-- 虽然是小写, 建议统一用""包住
    `
}
async function loadUser(user) {//玩家读档
    const [data] = await db.sql`SELECT * FROM "player" WHERE "userKey"=${user.player.userKey} LIMIT 1`
    if (data) {//如果这个玩家已经有存档
        user.lv = data.lv
        user.money = data.money
        user.item = JSON.parse(data.item)
    }
    else {//玩家无存档
        saveUser(user)
    }
}
async function deleteUser(user) {//删除玩家存档
    await db.sql`DELETE FROM "player" WHERE "userKey"=${user.player.userKey}`
}
async function showAllPlaySideUser() {//显示游玩端玩家数据, 地图发布后运行才不会报错
    for (const e of await db.sql`SELECT * FROM play."player"`) {
        console.log(JSON.stringify(e))
    }
}


async function showAllEditSideUser() {//显示编辑端玩家数据
    for (const e of await db.sql`SELECT * FROM edit."player"`) {
        console.log(JSON.stringify(e))
    }
}


async function poll(fn, msg) {//无限轮询执行sql语句直到成功
    while (true) {
        try {
            return await fn()//一旦成功执行, 停止无限轮询, 并返回查询结果
        } catch (e) {
            const m = e.message//需要简略显示的异常消息
            //sql偶尔会执行超时, 但如果反复显示timeout 15秒以上一直不停, 大概是数据库出了故障只能等官方修复
            if (m.includes('timeout')) {
                world.say(m)
            }
            else {
                world.say(msg || e.stack)//如果sql执行出错, 广播错误消息, 用来排查错误原因
            }
        }
        await sleep(2000) //每2秒重试一次
    }
}


poll(initTable, '等待pg数据库启动中...')


world.onPlayerJoin(async ({ entity }) => {
    //初始化玩家属性
    entity.player.money = 0
    entity.player.lv = 0
    entity.item = ['']


    await loadUser(entity)//尝试读取存档


  
    entity.player.onPress(async ({ button }) => {//右键显示状态栏
        if (button == Box3ButtonType.ACTION1) {
            const sel = await entity.player.dialog({
                type: Box3DialogType.SELECT,
                content: `
                金币:${entity.player.money}
                经验:${entity.player.lv}
                道具:[${entity.item}]
                `,
                options: ['保存','删档'],
            })
            if (sel) {
                if (sel.value == '保存') {
                    await saveUser(entity)
                    entity.player.directMessage('保存完毕')
                }
                else if (sel.value == '删档') {
                    await deleteUser(entity)
                    entity.player.directMessage('删档完毕')
                }
               
            }
        }
    })
})

center_image


回复

上一页1 页 / 共 1下一页
TBRO魔导师TBRO魔导师

center_image

点赞0


评论