用户:
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('删档完毕')
}
}
}
})
})
