实现新api的进房和准备/观战

修复不会刷新在线人数
This commit is contained in:
MrZ_26
2022-10-19 23:29:45 +08:00
parent ccb05230f2
commit dc1973e049
7 changed files with 131 additions and 114 deletions

View File

@@ -12,7 +12,7 @@ return{
bgm={'battle','beat5th','cruelty','distortion','echo','far','final','here','hope','memory','moonbeam','push','rectification','secret7th remix','secret7th','secret8th remix','secret8th','shift','shining terminal','storm','super7th','there','truth','vapor','waterfall'},
},
load=function()
for k,v in next,NET.roomState.roomData do
for k,v in next,NET.roomState.data do
GAME.modeEnv[k]=v
end
GAME.modeEnv.allowMod=false

View File

@@ -9,12 +9,16 @@ local NET={
name=false,
type=false,
version=false,
description=false,
},
data={},
count={
Gamer=0,
Spectator=0,
},
roomData={},
count=false,
capacity=false,
private=false,
start=false,
state='Playing',
},
spectate=false,-- If player is spectating
@@ -33,6 +37,22 @@ function NET.connectLost()
while SCN.stack[#SCN.stack-1]~='main' and #SCN.stack>0 do SCN.pop() end
SCN.back()
end
function NET.freshRoomState()
local playCount,readyCount=0,0
for j=1,#NETPLY.list do
if NETPLY.list[j].playMode=='Gamer' then playCount=playCount+1 end
if NETPLY.list[j].readyMode=='Ready' then readyCount=readyCount+1 end
end
if playCount-readyCount==1 then
local p=NETPLY.map[USER.uid]
if p.playMode=='Gamer' and p.readyMode~='Ready' then
SFX.play('warn_2',.5)
end
end
NET.roomReadyState=playCount>0 and playCount==readyCount
end
--------------------------<NEW HTTP API>
local availableErrorTextType={info=1,warn=1,error=1}
@@ -352,11 +372,11 @@ local actMap={
player_updateConf= 1200,
player_finish= 1201,
player_joinGroup= 1202,
player_setReady= 1203,
player_setReadyMode= 1203,
player_setHost= 1204,
player_setState= 1205,
player_stream= 1206,
player_setPlaying= 1207,
player_setPlayMode= 1207,
room_chat= 1300,
room_create= 1301,
room_getData= 1302,
@@ -373,7 +393,7 @@ local actMap={
local function wsSend(act,data)
-- print(("Send: $1 -->"):repD(act))
-- print(("Send: $1 -->"):repD(act)) print(type(data)=='table' and TABLE.dump(data) or tostring(data),"\n")
print(("Send: $1 -->"):repD(act)) print(type(data)=='table' and TABLE.dump(data) or tostring(data),"\n")
WS.send('game',JSON.encode{
action=assert(act),
data=data,
@@ -382,11 +402,12 @@ end
--Remove player when leave
local function _playerLeaveRoom(uid)
NETPLY.remove(uid)
for i=1,#PLAYERS do if PLAYERS[i].uid==uid then table.remove(PLAYERS,i) break end end
for i=1,#PLY_ALIVE do if PLY_ALIVE[i].uid==uid then table.remove(PLAYERS,i) break end end
if uid==USER.uid and SCN.cur=='net_game' then
SCN.back()
else
NETPLY.remove(uid)
end
end
@@ -407,20 +428,11 @@ function NET.room_chat(msg,rid)
return true
end
end
function NET.room_create(roomName,description,capacity,roomType,roomData,password)
function NET.room_create(data)
if not TASK.lock('createRoom',10) then MES.new('warn',text.tooFrequently) return end
TABLE.coverR(data,NET.roomState)
WAIT{timeout=12}
wsSend(actMap.room_create,{
capacity=capacity,
info={
name=roomName,
type=roomType,
version=VERSION.room,
description=description,
},
data=roomData,
password=password,
})
wsSend(actMap.room_create,data)
end
function NET.room_getData(rid)
wsSend(actMap.room_getData,{
@@ -491,8 +503,8 @@ end
function NET.player_joinGroup(gid)
wsSend(actMap.player_joinGroup,gid)
end
function NET.player_setReady(bool)
wsSend(actMap.player_setReady,bool)
function NET.player_setReadyMode(mode)
wsSend(actMap.player_setReadyMode,mode)
end
function NET.player_setHost(pid)
wsSend(actMap.player_setHost,{
@@ -506,8 +518,8 @@ end
function NET.player_stream(stream)
wsSend(actMap.player_stream,stream)
end
function NET.player_setPlaying(playing)
wsSend(actMap.player_setPlaying,playing and 'Gamer' or 'Spectator')
function NET.player_setPlayMode(mode)
wsSend(actMap.player_setPlayMode,mode)
end
-- Match
@@ -535,24 +547,37 @@ function NET.wsCallBack.room_create(body)
NET.wsCallBack.room_enter(body)
end
function NET.wsCallBack.room_getData(body)
NET.roomState.roomData=body.data
NET.roomState.data=body.data
end
function NET.wsCallBack.room_setData(body)
NET.wsCallBack.room_getData(body)
end
function NET.wsCallBack.room_getInfo(body)
NET.roomState.roomInfo=body.info
NET.roomState.info=body.info
end
function NET.wsCallBack.room_setInfo(body)
NET.wsCallBack.room_getInfo(body)
end
function NET.wsCallBack.room_enter(body)-- TODO
function NET.wsCallBack.room_enter(body)
TASK.unlock('enterRoom')
-- NET.roomState=...
NET.textBox.hide=true
NET.inputBox.hide=true
NET.textBox:clear()
NET.inputBox:clear()
NET.roomState=body.data
NETPLY.clear()
if body.data.players then
for _,p in next,body.data.players do
NETPLY.add{
uid=p.playerId,
playMode=p.type,
readyMode=p.state,
config=p.config,
}
end
end
loadGame('netBattle',true,true)
WAIT.interrupt()
end
@@ -561,10 +586,10 @@ function NET.wsCallBack.room_kick(body)
_playerLeaveRoom(body.data.playerId)
end
function NET.wsCallBack.room_leave(body)
if body.data.playerId~=USER.uid then
MES.new('info',text.leaveRoom:repD(body.data.playerId))
if body.data then
MES.new('info',text.leaveRoom:repD(body.data.playerId),2.6)
end
_playerLeaveRoom(body.data.playerId)
_playerLeaveRoom(body.data and body.data.playerId or USER.uid)
end
function NET.wsCallBack.room_fetch(body)
TASK.unlock('fetchRoom')
@@ -577,21 +602,24 @@ function NET.wsCallBack.room_remove()
MES.new('info',text.roomRemoved)
_playerLeaveRoom(USER.uid)
end
function NET.wsCallBack.player_updateConf(body)-- TODO
function NET.wsCallBack.player_updateConf(body)
NETPLY.setConf(body.data.playerId,body.data.config)
end
function NET.wsCallBack.player_finish(body)-- TODO
end
function NET.wsCallBack.player_joinGroup(body)-- TODO
end
function NET.wsCallBack.player_setReady(body)-- TODO
end
function NET.wsCallBack.player_setHost(body)-- TODO
end
function NET.wsCallBack.player_setState(body)-- TODO
end
function NET.wsCallBack.player_stream(body)-- TODO
end
function NET.wsCallBack.player_setPlaying(body)-- TODO
function NET.wsCallBack.player_setPlayMode(body)
NETPLY.setPlayMode(body.data.playerId,body.data.type)
end
function NET.wsCallBack.player_setReadyMode(body)
NETPLY.setReadyMode(body.data.playerId,body.data.type)
end
function NET.ws_connect()
@@ -642,7 +670,7 @@ function NET.ws_update()
if WS.status('game')=='dead' then return end
updateOnlineCD=updateOnlineCD%626+1
if updateOnlineCD==0 then NET.global_getOnlineCount() end
if updateOnlineCD==1 then NET.global_getOnlineCount() end
local msg,op=WS.read('game')
if msg then
@@ -660,7 +688,7 @@ function NET.ws_update()
elseif msg then
msg=JSON.decode(msg)
-- print(("Recv: <-- $1 err:$2"):repD(msg.action,msg.errno))
-- print(("Recv: <-- $1 err:$2"):repD(msg.action,msg.errno)) print(TABLE.dump(msg),"\n")
print(("Recv: <-- $1 err:$2"):repD(msg.action,msg.errno)) print(TABLE.dump(msg),"\n")
if msg.errno~=0 then
parseError(msg.message~=nil and msg.message or msg)
else

View File

@@ -71,8 +71,8 @@ local nullIndex={
MES.new('error',"User not loaded: "..k)
NETPLY.add{
uid=k,
username="Stacker",
mode=0,
playMode='Spectator',
readyMode='Standby',
config="",
}
return self[k]
@@ -106,10 +106,10 @@ end
function NETPLY.add(d)
local p={
uid=d.uid,
username=d.username,
mode=d.mode,
config=d.config,
connected=false,
playMode=d.playMode,-- 'Gamer'|'Spectator'
readyMode=d.readyMode,-- 'Standby'|'Ready'|'Playing'|'Finished'
config=d.config,-- A long string generated by dumpBasicConfig()
place=1e99,
stat=false,
}
@@ -132,34 +132,26 @@ function NETPLY.remove(uid)
end
function NETPLY.getCount() return #PLYlist end
function NETPLY.getSelfJoinMode() return PLYmap[USER.uid].mode end
function NETPLY.getSelfReady() return PLYmap[USER.uid].mode>0 end
function NETPLY.getSelfPlayMode() return PLYmap[USER.uid].playMode end
function NETPLY.getSelfReadyMode() return PLYmap[USER.uid].playMode end
function NETPLY.getSelfReady() return PLYmap[USER.uid].readyMode end
function NETPLY.setPlayerObj(ply,p) ply.p=p end
function NETPLY.setConf(uid,config) PLYmap[uid].config=config end
function NETPLY.setJoinMode(uid,ready)
for _,p in next,PLYlist do
if p.uid==uid then
if p.mode~=ready then
p.mode=ready
if ready==0 then NET.roomReadyState=false end
SFX.play('spin_0',.6)
if p.uid==USER.uid then
TASK.unlock('ready')
elseif PLYmap[USER.uid].mode==0 then
for j=1,#PLYlist do
if not p.uid==USER.uid and PLYlist[j].mode==0 then
return
end
end
SFX.play('warn_2',.5)
end
end
return
end
function NETPLY.setPlayMode(uid,mode)
local p=PLYmap[uid]
if p and p.playMode~=mode then
p.playMode=mode
NET.freshRoomState()
end
end
function NETPLY.setReadyMode(uid,mode)
local p=PLYmap[uid]
if p and p.ReadyMode~=mode then
p.ReadyMode=mode
NET.freshRoomState()
end
end
function NETPLY.setConnect(uid) PLYmap[uid].connected=true end
function NETPLY.setPlace(uid,place) PLYmap[uid].place=place end
function NETPLY.setStat(uid,S)
PLYmap[uid].stat={
@@ -170,8 +162,7 @@ function NETPLY.setStat(uid,S)
end
function NETPLY.resetState()
for i=1,#PLYlist do
PLYlist[i].mode=0
PLYlist[i].connected=false
PLYlist[i].playMode=0
end
end
@@ -209,18 +200,19 @@ function NETPLY.draw()
local p=PLYlist[i]
gc_translate(p.x,p.y)
-- Rectangle
gc_setColor(COLOR[
p.mode==0 and 'lH' or
p.mode==1 and 'N' or
p.mode==2 and 'F'
])
if p.playMode=='Gamer' then
gc_setColor(COLOR[
p.playMode=='Spectator' and 'lH' or
p.playMode=='Gamer' and (
p.readyMode=='Standby' and 'Z' or
'N'
) or 'dH'
])
else
gc_setColor(COLOR.lH)
end
gc_setLineWidth(2)
gc_rectangle('line',0,0,p.w,p.h)
if p.connected then
local c=p.mode==1 and COLOR.N or COLOR.F
gc_setColor(c[1],c[2],c[3],.26)
gc_rectangle('fill',0,0,p.w,p.h)
end
-- Stencil
stencilW,stencilH=p.w,p.h
@@ -236,12 +228,12 @@ function NETPLY.draw()
if p.h>=47 then
setFont(40)
gc_print("#"..p.uid,50,-5)
gc_print(p.username,210,-5)
gc_print(USERS.getUsername(p.uid),210,-5)
else
setFont(15)
gc_print("#"..p.uid,46,-1)
setFont(30)
gc_print(p.username,p.h,8)
gc_print(USERS.getUsername(p.uid),p.h,8)
end
-- Stat
@@ -273,7 +265,7 @@ function NETPLY.draw()
setFont(30)
gc_print("#"..selP.uid,75,0)
setFont(35)
gc_print(selP.username,75,25)
gc_print(USERS.getUsername(selP.uid),75,25)
setFont(20)
gc_printf(USERS.getMotto(selP.uid),5,70,390)
if selP.stat then

View File

@@ -157,12 +157,6 @@ function scene.draw()
-- Player
PLAYERS[1]:draw()
-- Profile
drawSelfProfile()
-- Player count
drawOnlinePlayerCount()
end
scene.widgetList={

View File

@@ -27,14 +27,15 @@ local function _hideReadyUI()
end
local function _setCancel()
NET.player_setPlaying(true)
NET.player_setReady(true)
NET.player_setPlayMode('Gamer')
NET.player_setReadyMode(false)
end
local function _setReady()
NET.player_setReady(true)
NET.player_setPlayMode('Gamer')
NET.player_setReadyMode(true)
end
local function _setSpectate()
NET.player_setPlaying(false)
NET.player_setPlayMode('Spectator')
end
local function _gotoSetting()
@@ -153,7 +154,7 @@ function scene.keyDown(key,isRep)
end
elseif not _hideReadyUI() then
if key=='space' then
if NETPLY.getSelfJoinMode()==0 then
if NETPLY.getSelfPlayMode()~='Gamer' then
(kb.isDown('lctrl','rctrl','lalt','ralt') and _setSpectate or _setReady)()
else
_setCancel()
@@ -323,8 +324,8 @@ function scene.draw()
gc_print("M",430,10)
end
end
local function _hideF_ingame() return _hideReadyUI() or NETPLY.getSelfReady() end
local function _hideF_ingame2() return _hideReadyUI() or not NETPLY.getSelfReady() end
local function _hideF_ingame() return _hideReadyUI() or NETPLY.getSelfReadyMode()=='Spectator' end
local function _hideF_ingame2() return _hideReadyUI() or NETPLY.getSelfReadyMode()=='Gamer' end
scene.widgetList={
textBox,
inputBox,

View File

@@ -36,14 +36,17 @@ local function _createRoom()
if #roomname==0 then
roomname=(USERS.getUsername(USER.uid) or "Anonymous").."'s room"
end
NET.room_create(
roomname,
descriptionBox.value,
ROOMENV.capacity,
"normal",
ROOMENV,
pw
)
NET.room_create{
capacity=ROOMENV.capacity,
info={
name=roomname,
type="normal",
version=VERSION.room,
description=descriptionBox.value,
},
data=ROOMENV,
password=pw,
}
end
end

View File

@@ -62,28 +62,27 @@ local USERS={}
avatar_frame=0,
}]]
function USERS.updateUserData(data)
local id=data.id
db[id].username=data.username
db[id].motto=data.motto
if type(data.avatar_hash)=='string' and (db[id].hash~=data.avatar_hash or not fs.getInfo("cache/"..data.avatar_hash)) then
db[id].hash=data.avatar_hash
NET.getAvatar(id)
local uid=data.id
db[uid].username=data.username
db[uid].motto=data.motto
if type(data.avatar_hash)=='string' and (db[uid].hash~=data.avatar_hash or not fs.getInfo("cache/"..data.avatar_hash)) then
db[uid].hash=data.avatar_hash
NET.getAvatar(uid)
end
fs.write("cache/user"..id..".dat",JSON.encode{
fs.write("cache/user"..uid..".dat",JSON.encode{
username=data.username,
motto=data.motto,
hash=db[id].hash,
hash=db[uid].hash,
})
end
function USERS.updateAvatar(id,imgData)
local hash=db[id].hash
function USERS.updateAvatar(uid,imgData)
local hash=db[uid].hash
fs.write("cache/"..hash,love.data.decode('string','base64',imgData:sub(imgData:find(",")+1)))
db_img[id]=_loadAvatar("cache/"..hash)
db_img[uid]=_loadAvatar("cache/"..hash)
end
function USERS.getUsername(uid) return db[uid].username end
function USERS.getMotto(uid) return db[uid].motto end
function USERS.getHash(uid) return db[uid].hash or "" end
function USERS.getAvatar(uid)
if uid then
if not db[uid].new then