Merge branch 'ci_new_online'

This commit is contained in:
MrZ_26
2022-10-24 14:27:27 +08:00
278 changed files with 5180 additions and 4937 deletions

View File

@@ -16,17 +16,15 @@
-- Var leak check
-- setmetatable(_G,{__newindex=function(self,k,v)print('>>'..k)print(debug.traceback():match("\n.-\n\t(.-): "))rawset(self,k,v)end})
-- setmetatable(_G,{__newindex=function(self,k,v) print('>>'..k..string.rep(" ",26-#k),debug.traceback():match("\n.-\n\t(.-): "))rawset(self,k,v) end})
-- System Global Vars Declaration
local fs=love.filesystem
VERSION=require"version"
TIME=love.timer.getTime
YIELD=coroutine.yield
SYSTEM=love.system.getOS() if SYSTEM=='OS X' then SYSTEM='macOS' end
FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol
MOBILE=SYSTEM=='Android' or SYSTEM=='iOS'
SAVEDIR=fs.getSaveDirectory()
-- Global Vars & Settings
SFXPACKS={'chiptune'}
@@ -107,7 +105,7 @@ require'parts.gameFuncs'
-- Load shader files from SOURCE ONLY
SHADER={}
for _,v in next,fs.getDirectoryItems('parts/shaders') do
if isSafeFile('parts/shaders/'..v)then
if FILE.isSafe('parts/shaders/'..v) then
local name=v:sub(1,-6)
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
end
@@ -148,6 +146,7 @@ do--Z.setCursor
{'dCirc',8,8,7},
{'fCirc',8,8,3},
}
local _
Z.setCursor(function(time,x,y)
if not SETTING.sysCursor then
local R=math.floor((time+1)/2)%7+1
@@ -179,6 +178,12 @@ Z.setOnFnKeys({
function() for k,v in next,_G do print(k,v) end end,
function() if love['_openConsole'] then love['_openConsole']() end end,
})
Z.setOnGlobalKey('f11',function()
SETTING.fullscreen=not SETTING.fullscreen
applySettings()
saveSettings()
end)
Z.setVersionText(VERSION.string)
Z.setDebugInfo{
{"Cache",gcinfo},
{"Tasks",TASK.getCount},
@@ -223,7 +228,16 @@ do--Z.setOnFocus
end
end)
end
Z.setOnQuit(destroyPlayers)
Z.setOnBeforeQuit(function()
NET.ws_close()
TASK.new(function()
TEST.yieldT(.26)
love.event.quit()
end)
end)
Z.setOnQuit(function()
destroyPlayers()
end)
-- Load settings and statistics
if
@@ -347,7 +361,7 @@ SKIN.load{
SFX.init((function()--[Warning] Not loading files here, just get the list of sound needed
local L={}
for _,v in next,fs.getDirectoryItems('media/effect/chiptune/') do
if isSafeFile('media/effect/chiptune/'..v,"Dangerous file : %SAVE%/media/effect/chiptune/"..v)then
if FILE.isSafe('media/effect/chiptune/'..v,"Dangerous file : %SAVE%/media/effect/chiptune/"..v) then
table.insert(L,v:sub(1,-5))
end
end
@@ -356,7 +370,7 @@ end)())
BGM.init((function()
local L={}
for _,v in next,fs.getDirectoryItems('media/music') do
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
if FILE.isSafe('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v) then
L[v:sub(1,-5)]='media/music/'..v
end
end
@@ -411,7 +425,7 @@ table.insert(_LOADTIMELIST_,("Initialize Parts: %.3fs"):format(TIME()-_LOADTIME_
-- Load background files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems('parts/backgrounds') do
if isSafeFile('parts/backgrounds/'..v)and v:sub(-3)=='lua'then
if FILE.isSafe('parts/backgrounds/'..v) and v:sub(-3)=='lua' then
local name=v:sub(1,-5)
BG.add(name,require('parts.backgrounds.'..name))
end
@@ -419,7 +433,7 @@ end
BG.remList('none')BG.remList('gray')BG.remList('custom')
-- Load scene files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems('parts/scenes') do
if isSafeFile('parts/scenes/'..v)then
if FILE.isSafe('parts/scenes/'..v) then
local sceneName=v:sub(1,-5)
SCN.add(sceneName,require('parts.scenes.'..sceneName))
LANG.addScene(sceneName)
@@ -428,13 +442,13 @@ end
-- Load mode files
for i=1,#MODES do
local m=MODES[i]-- Mode template
if isSafeFile('parts/modes/'..m.name)then
if FILE.isSafe('parts/modes/'..m.name) then
TABLE.complete(require('parts.modes.'..m.name),MODES[i])
MODES[m.name],MODES[i]=MODES[i]
end
end
for _,v in next,fs.getDirectoryItems('parts/modes') do
if isSafeFile('parts/modes/'..v)and not MODES[v:sub(1,-5)]then
if FILE.isSafe('parts/modes/'..v) and not MODES[v:sub(1,-5)] then
local M={name=v:sub(1,-5)}
local modeData=require('parts.modes.'..M.name)
if modeData.env then
@@ -546,7 +560,7 @@ do
STAT.version=VERSION.code
needSave=true
end
SETTING.appLock,SETTING.dataSaving,SETTING.swap=nil
SETTING.appLock,SETTING.dataSaving,SETTING.swap,SETTING.autoLogin=nil
if not SETTING.VKSkin then SETTING.VKSkin=1 end
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
if not RSlist[SETTING.RS] then SETTING.RS='TRS' end
@@ -662,7 +676,7 @@ for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i])end
-- Launch testing task if launch param received
if TABLE.find(arg,'-- test') then
TASK.new(function()
while not LOADED do YIELD()end
while not LOADED do coroutine.yield() end
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
BGM.setVol(0)SFX.setVol(0)
@@ -684,7 +698,7 @@ if TABLE.find(arg,'--test')then
end)
TASK.new(function()
while true do
YIELD()
coroutine.yield()
if Z.getErr(1) then break end
end
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.getErr(1).mes,"\n").."\27[91m\nAborting\27[0m")
@@ -692,4 +706,6 @@ if TABLE.find(arg,'--test')then
love.event.quit(1)
end)
end
WS.switchHost('101.43.110.22','10026','/tech/socket/v1')
WS.switchHost('cafuuchino1.3322.org','10026','/techmino/ws/v1')
HTTP.setHost("cafuuchino1.3322.org:10026")
HTTP.setThreadCount(1)

View File

@@ -8,7 +8,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control and P.atkBufferSum==0 then
local D=P.modeData
if D.wave==50 then

View File

@@ -8,7 +8,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control and P.atkBufferSum<4 then
local D=P.modeData
if D.wave==50 then

View File

@@ -10,7 +10,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.counter=D.counter+1

View File

@@ -10,7 +10,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.counter=D.counter+1

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -53,7 +53,7 @@ return{
P.modeData.rankPoint=0
P.modeData.rankName=sectionName[1]
while true do
YIELD()
coroutine.yield()
if P.stat.frame>=3600 then
P.modeData.rankPoint=math.min(P.modeData.rankPoint+passPoint,140)
P.modeData.rankName=sectionName[math.floor(P.modeData.rankPoint/10)+1]

View File

@@ -289,7 +289,7 @@ return{
local decayRate={125,80,80,50,45,45,45,40,40,40,40,40,30,30,30,20,20,20,20,20,15,15,15,15,15,15,15,15,15,15,10,10,10,9,9,9,8,8,8,7,7,7,6}
local decayTimer=0
while true do
YIELD()
coroutine.yield()
P.modeData.grade=getGrade()
P.modeData.gradePts=math.max(math.min(math.floor(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets),#gradeList),1)
if P.stat.frame-prevSectTime > reg_time[math.ceil(P.modeData.pt/100+0.01)] and not (isInRoll or isInRollTrans) then
@@ -336,7 +336,7 @@ return{
rollGrades=rollGrades+(cools>8 and 1.6 or 0.5)
P.modeData.grade=getGrade()
P.modeData.gradePts=math.min(math.floor(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets),#gradeList)
YIELD()
coroutine.yield()
P:win('finish')
end
end

View File

@@ -72,7 +72,7 @@ return{
P.modeData.pt=0
P.modeData.target=100
while true do
YIELD()
coroutine.yield()
if P.holdTime==0 and P.waiting<=0 and not held then
hidetimer=0
held=true

View File

@@ -11,7 +11,7 @@ local function task_PC(P)
P:pushNextList(L,symmetry)
P.control=false
if P.frameRun>180 then for _=1,26 do YIELD()end end
if P.frameRun>180 then for _=1,26 do coroutine.yield() end end
P.control=true
local base=PCbase[difficulty]

View File

@@ -14,7 +14,7 @@ local function task_PC(P)
P:pushNextList(L,symmetry)
P.control=false
if P.frameRun>180 then for _=1,26 do YIELD()end end
if P.frameRun>180 then for _=1,26 do coroutine.yield() end end
P.control=true
local base=PCbase[difficulty]

View File

@@ -7,9 +7,9 @@ return{
PLY.draw.drawTargetLine(P,r)
end,
task=function(P)
YIELD()
coroutine.yield()
while true do
for _=1,P.holeRND:random(40,200)do YIELD()end
for _=1,P.holeRND:random(40,200) do coroutine.yield() end
local r=P.holeRND:random(7)
if r==1 then
if P.cur and not P:ifoverlap(P.cur.bk,P.curX-1,P.curY) then

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1
@@ -18,7 +18,7 @@ return{
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(10)),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3})
P.atkBufferSum=P.atkBufferSum+4
P.stat.recv=P.stat.recv+4
if D.wave==60 then
if D.wave==90 then
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
P:shakeField(3)

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -6,7 +6,7 @@ return{
end,
task=function(P)
while true do
YIELD()
coroutine.yield()
if P.control then
local D=P.modeData
D.timer=D.timer+1

View File

@@ -21,7 +21,7 @@ return{
BGM.seek(0)
P.modeData.section=1
while true do
YIELD()
coroutine.yield()
while P.stat.frame>=warnTime[P.modeData.section] do
if P.modeData.section<9 then
P.modeData.section=P.modeData.section+1

View File

@@ -2,7 +2,7 @@ local gc_push,gc_pop=GC.push,GC.pop
local gc_origin,gc_replaceTransform=GC.origin,GC.replaceTransform
local gc_setLineWidth,gc_setColor=GC.setLineWidth,GC.setColor
local gc_setShader=GC.setShader
local gc_draw,gc_rectangle,gc_line,gc_printf=GC.draw,GC.rectangle,GC.line,GC.printf
local gc_draw,gc_rectangle,gc_printf=GC.draw,GC.rectangle,GC.printf
local ins,rem=table.insert,table.remove
local int,rnd=math.floor,math.random
@@ -10,7 +10,6 @@ local approach=MATH.expApproach
local SETTING,GAME,SCR=SETTING,GAME,SCR
local PLAYERS=PLAYERS
local playSFX=SFX.play
@@ -93,13 +92,6 @@ do--function loadFile(name,args), function saveFile(data,name,args)
end
end
end
function isSafeFile(file,mes)
if love.filesystem.getRealDirectory(file)~=SAVEDIR then
return true
elseif mes then
MES.new('warn',mes)
end
end
function saveStats()
return saveFile(STAT,'conf/data')
end
@@ -107,8 +99,14 @@ function saveProgress()
return saveFile(RANKS,'conf/unlock')
end
function saveSettings()
if WS.status('game')=='running' then
NET.player_updateConf()
end
return saveFile(SETTING,'conf/settings')
end
function saveUser()
return saveFile(USER.__data,'conf/user')
end
do-- function applySettings()
local saturateValues={
normal={0,1},
@@ -288,25 +286,25 @@ end
function playClearSFX(cc)
if cc<=0 or cc%1~=0 then return end
if cc<=4 then
playSFX('clear_'..cc)
SFX.play('clear_'..cc)
elseif cc<=6 then
playSFX('clear_4')
SFX.play('clear_4')
elseif cc<=12 then
playSFX('clear_4',.8)
SFX.play('clear_4',.8)
if cc<=9 then
Snd('bass','A3','E4')
else
Snd('bass','A3','E4','A4')
end
elseif cc<=16 then
playSFX('clear_5',.7)
SFX.play('clear_5',.7)
if cc<=14 then
Snd('bass',.8,'A3','E4')Snd('lead','A4','E5')
else
Snd('bass',.8,'A3','G4')Snd('lead','B4','G5')
end
else
playSFX('clear_6',.6)
SFX.play('clear_6',.6)
if cc==17 then Snd('bass',.8,'A3','A4')Snd('lead','E5','G5')
elseif cc==18 then Snd('bass',.7,'A4')Snd('lead',.8,'C4','G5')Snd('bell','D5')
elseif cc==19 then Snd('bass',.7,'A4')Snd('lead',.8,'A4','E5')Snd('bell','B5')
@@ -493,7 +491,7 @@ end
function loadGame(mode,ifQuickPlay,ifNet)-- Load a mode and go to game scene
freshDate()
if legalGameTime() then
if not MODES[mode]and love.filesystem.getRealDirectory('parts/modes/'..mode)~=SAVEDIR then
if not MODES[mode] and FILE.isSafe('parts/modes/'..mode) then
MODES[mode]=require('parts.modes.'..mode)
MODES[mode].name=mode
end
@@ -513,7 +511,7 @@ function loadGame(mode,ifQuickPlay,ifNet)--Load a mode and go to game scene
local modeText=text.modes[mode] or{"["..MODES[mode].name.."]",""}
TEXTOBJ.modeName:set(modeText[1].." "..modeText[2])
SCN.go('game',ifQuickPlay and 'swipeD' or 'fade_togame')
playSFX('enter')
SFX.play('enter')
end
end
end
@@ -577,7 +575,7 @@ function gameOver()--Save record
P:_showText(text.newRecord,0,-100,100,'beat',.5)
if SETTING.autoSave and DATA.saveReplay() then
GAME.saved=true
playSFX('connected')
SFX.play('connected')
MES.new('check',text.saveDone)
end
end
@@ -695,7 +693,7 @@ do--function resetGameData(args)
local function task_showMods()
local time=0
while true do
YIELD()
coroutine.yield()
time=time+1
if time%20==0 then
local M=GAME.mod[time/20]
@@ -832,27 +830,9 @@ end
-- Game draw
do-- function drawSelfProfile()
local lvColor={COLOR.J,COLOR.A,COLOR.C,COLOR.N,COLOR.S,COLOR.V,COLOR.P,COLOR.M,COLOR.W,COLOR.R,COLOR.O,COLOR.Y}
local lvIcon=setmetatable({},{__index=function(self,lv)
local c=lvColor[int((lv-1)/26)+1]or COLOR.Z
local img=GC.DO{25,25,
{"clear",0,0,0,0},
{"setLW",2},
{"setCL",c[1],c[2],c[3],.6},
{"fRect",2,2,21,21,2},
{"setCL",c},
{"dRect",2,2,21,21,2},
{"setCL",COLOR.Z},
{"mText",(lv-1)%26+1,13,-1},
}
rawset(self,lv,img)
return img
end})
local name
local textObj,scaleK,width,offY
function drawSelfProfile()
local selfAvatar=USERS.getAvatar(USER.uid)
gc_push('transform')
gc_replaceTransform(SCR.xOy_ur)
@@ -861,7 +841,7 @@ do--function drawSelfProfile()
gc_setColor(COLOR.X)gc_rectangle('fill',0,0,-300,80)
gc_setColor(1,1,1)gc_rectangle('line',-300,0,300,80,5)
gc_rectangle('line',-73,7,66,66,2)
gc_draw(selfAvatar,-72,8,nil,.5)
gc_draw(USERS.getAvatar(USER.uid),-72,8,nil,.5)
-- Draw username
if name~=USERS.getUsername(USER.uid) then
@@ -873,11 +853,6 @@ do--function drawSelfProfile()
end
gc_draw(textObj,-82,26,nil,scaleK,nil,width,offY)
--Draw lv. & xp.
gc_draw(lvIcon[USER.lv],-295,50)
gc_line(-270,55,-80,55,-80,70,-270,70)
gc_rectangle('fill',-210,55,150*USER.xp/USER.lv/USER.lv,15)
gc_pop()
end
end
@@ -886,7 +861,7 @@ function drawOnlinePlayerCount()
gc_setColor(1,1,1)
gc_push('transform')
gc_replaceTransform(SCR.xOy_ur)
gc_printf(("%s: %s/%s/%s"):format(text.onlinePlayerCount,NET.UserCount,NET.PlayCount,NET.StreamCount),-600,80,594,'right')
gc_printf(text.onlinePlayerCount:repD(NET.onlineCount),-600,80,594,'right')
gc_pop()
end
function drawWarning()

View File

@@ -574,14 +574,24 @@ do--Game data tables
REPLAY={}-- Replay objects (not include stream data)
end
do-- Userdata tables
USER={--User infomation
--Network infos
USER=setmetatable({-- User infomation
__data={
uid=false,
authToken=false,
--Local data
xp=0,lv=1,
}
email=false,
password=false,
rToken=false,
aToken=false,
},
},{
__index=function(self,k)
return self.__data[k]
end,
__newindex=function(self,k,v)
if self.__data[k]~=nil and v~=nil then
self.__data[k]=v
end
end,
})
SETTING={-- Settings
-- Tuning
das=10,arr=2,
@@ -598,7 +608,6 @@ do--Userdata tables
menuPos='middle',
fine=false,
autoSave=false,
autoLogin=true,
simpMode=false,
sysCursor=true,
maxFPS=60,

View File

@@ -104,6 +104,14 @@ return{
dictNote="==Copied from TetroDictionary==",
Techrater={-- Server's warn/error messages
-- TODO
},
tooFrequently="Request too frequently",
roomPasswordChanged="Room password changed",
getNoticeFail="Failed to fetch announcements",
oldVersion="Version $1 is now available",
needUpdate="Newer version required!",
@@ -114,23 +122,23 @@ return{
noUsername="Please enter your username",
wrongEmail="Invalid email address",
wrongCode="Invalid verification code",
noPassword="Please enter your password",
diffPassword="Passwords dont match",
registerRequestSent="A sign up request has been sent.",
registerOK="Sign up successful!",
loginOK="You are now logged in!",
accessOK="Access granted",
checkEmail="A sign up request has been sent.",
wsConnecting="Websocket connecting…",
wsFailed="WebSocket connection failed",
wsClose="WebSocket closed:",
wsFailed="WebSocket connection failed: $1",
wsClose="WebSocket closed: $1",
netTimeout="Connection timed out",
serverDown="Oops! Server is down",
requestFailed="Request failed",
onlinePlayerCount="Online",
onlinePlayerCount="Online: $1",
createRoomSuccessed="Room created",
playerKicked="[$1] removed [$2] from room",
started="Playing",
joinRoom="has entered the room.",
leaveRoom="has left the room.",
joinRoom="$1 has entered the room.",
leaveRoom="$1 has left the room.",
ready="Ready",
connStream="Connecting",
waitStream="Waiting",
@@ -139,6 +147,8 @@ return{
chatStart="------Beginning of log------",
chatHistory="------New messages below------",
keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete",
customBGhelp="Drop image file here to apply custom background",
customBGloadFailed="Unsupport image format for custom background",
@@ -322,6 +332,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Support the author",
WidgetText={
@@ -361,6 +372,7 @@ return{
league="Tech League",
ffa="FFA",
rooms="Rooms",
resetPW="Reset password",
logout="Log out",
},
net_league={
@@ -437,7 +449,6 @@ return{
sysCursor="Use System Cursor",
autoPause="Pause When Unfocused",
autoSave="Auto-save New Records",
autoLogin="Auto-login on Start",
simpMode="Simplistic Mode",
},
setting_video={
@@ -688,24 +699,29 @@ return{
music="BGMs",
label="label",
},
login={
login_pw={
title="Sign In",
register="Sign Up",
login_mail="Login with E-mail/Sign Up",
email="Email Address",
password="Password",
showEmail="Show Email",
keepPW="Remember me",
login="Log In",
},
register={
title="Sign Up",
login="Sign In",
username="Username",
login_mail={
title="Sign In/Sign Up",
login_pw="Password Sign In",
email="Email Address",
send="Send code",
code="Verification Code",
verify="Verify",
},
reset_password={
title="Reset Password",
send="Send code",
code="Verification Code",
password="Password",
password2="Re-enter Password",
register="Sign Up",
registering="Waiting for response…",
setPW="Set Password",
},
account={
title="Account",

View File

@@ -103,6 +103,14 @@ return{
dictNote="==Copia de TetroDictionary==",
Techrater={-- Server's warn/error messages
-- TODO
},
-- tooFrequently="Request too frequently",
-- roomPasswordChanged="Room password changed",
getNoticeFail="Error al buscar novedades.",
oldVersion="¡Está disponible la nueva versión $1!",
needUpdate="¡Nueva versión requerida!",
@@ -113,23 +121,23 @@ return{
noUsername="Por favor ingresa un nombre de usuario",
wrongEmail="Correo electrónico inválido",
-- wrongCode="Invalid verification code",
noPassword="Por favor ingresa la contraseña",
diffPassword="Las contraseñas no coinciden",
registerRequestSent="Petición de registro enviada con éxito",
registerOK="¡Registro exitoso!",
loginOK="¡Ingreso con éxito!",
accessOK="¡Autorizado exitoso!",
checkEmail="Petición de registro enviada con éxito",
wsConnecting="Websocket Conectando",
wsFailed="WebSocket conexión fallida",
wsClose="WebSocket cerrado:",
wsFailed="WebSocket conexión fallida: $1",
wsClose="WebSocket cerrado: $1",
netTimeout="Tiempo de conexión agotado",
-- serverDown="Oops! Server is down",
-- requestFailed="Request failed",
onlinePlayerCount="En línea",
onlinePlayerCount="En línea: $1",
createRoomSuccessed="¡Sala creada con éxito!",
-- playerKicked="[$1] removed [$2] from room",
started="En juego",
joinRoom="entró a la sala.",
leaveRoom="salió de la sala.",
joinRoom="$1 entró a la sala.",
leaveRoom="$1 salió de la sala.",
ready="LISTO",
connStream="CONECTANDO",
waitStream="ESPERANDO",
@@ -138,6 +146,8 @@ return{
chatStart="------Comienzo del historial------",
chatHistory="------Nuevos mensajes------",
keySettingInstruction="Pulsa la tecla a mapear\nEsc.: Cancelar\nBackspace: Borrar",
customBGhelp="Suelta una imagen aquí para aplicarla de fondo",
customBGloadFailed="Formato de imagen no soportado",
@@ -322,6 +332,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Apoyen al Autor",
WidgetText={
@@ -361,6 +372,7 @@ return{
league="Liga Tech",
ffa="FFA",
rooms="Salas",
-- resetPW="Reset password",
logout="Desconec.",
},
net_league={
@@ -437,7 +449,6 @@ return{
sysCursor="Usar cursor del sistema",
autoPause="Pausar cuando la ventana no está enfocada",
autoSave="Autograbar Récords",
autoLogin="Autologueo al Iniciar",
simpMode="Modo Sencillo",
},
setting_video={
@@ -680,24 +691,29 @@ return{
music="BGMs",
label="Etiq.",
},
login={
login_pw={
title="Entrar",
register="Registrarse",
-- login_mail="Login with E-mail/Sign Up",
email="Correo Elec.",
password="Contraseña",
showEmail="Mostrar Correo",
keepPW="Recordar credenciales",
login="Entrar",
},
register={
title="Registrarse",
login="Entrar",
username="Nombre de Usuario",
login_mail={
title="Entrar/Registrarse",
-- login_pw="Password Sign In",
email="Correo Elec.",
-- send="Send code",
-- code="Verification Code",
-- verify="Verify",
},
reset_password={
-- title="Reset Password",
-- send="Send code",
-- code="Verification Code",
password="Contraseña",
password2="Repetir Contr.",
register="Registrarse",
registering="Esperando respuesta...",
-- setPW="Set Password",
},
account={
title="Cuenta",

View File

@@ -94,6 +94,14 @@ return{
-- dictNote="==Copied from TetroDictionary==",
Techrater={-- Server's warn/error messages
-- TODO
},
-- tooFrequently="Request too frequently",
-- roomPasswordChanged="Room password changed",
getNoticeFail="Echec de l'obtention de la notice",
oldVersion="La version $1 est disponible !",
-- versionNotMatch="Version do not match!",
@@ -104,23 +112,23 @@ return{
noUsername="Entrez votre nom d'utilisateur",
wrongEmail="Mauvaise adresse email",
-- wrongCode="Invalid verification code",
noPassword="Entrez votre mot de passe",
diffPassword="Les mots de passe ne se correspondent pas",
-- registerRequestSent="Registration request sent",
registerOK="Enregistré avec succès !",
loginOK="Connecté avec succès !",
accessOK="Autorisé avec succès !",
-- checkEmail="Registration request sent",
-- wsConnecting="Websocket Connecting",
wsFailed="WebSocket connection échouée",
-- wsClose="WebSocket Closed:",
wsFailed="WebSocket connection échouée: $1",
-- wsClose="WebSocket Closed: $1",
-- netTimeout="Network connection timeout",
-- serverDown="Oops! Server is down",
-- requestFailed="Request failed",
-- onlinePlayerCount="Online",
-- onlinePlayerCount="Online: $1",
createRoomSuccessed="Salon créé avec succès !",
-- playerKicked="[$1] removed [$2] from room",
-- started="Playing",
joinRoom="a rejoint le salon.",
leaveRoom="a quitté le salon.",
joinRoom="$1 a rejoint le salon.",
leaveRoom="$1 a quitté le salon.",
-- ready="READY",
-- connStream="CONNECTING",
-- waitStream="WAITING",
@@ -129,6 +137,8 @@ return{
chatStart="--------Début des logs--------",
chatHistory="-Nouveaux messages en dessous-",
-- keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete",
-- customBGhelp="Drop image file here to apply custom background",
-- customBGloadFailed="Unsupport image format for custom background",
@@ -289,6 +299,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Aider le créateur",
WidgetText={
@@ -324,6 +335,7 @@ return{
-- league="Tech League",
ffa="FFA",
rooms="Salons",
-- resetPW="Reset password",
-- logout="Log out",
},
net_league={
@@ -400,7 +412,6 @@ return{
-- sysCursor="Use system cursor",
autoPause="Mettre en pause en cas de perte de focus",
-- autoSave="Auto save new-best",
-- autoLogin="Auto Login on Start",
-- simpMode="Simple mode",
},
setting_video={
@@ -642,24 +653,29 @@ return{
music="Musique",
-- label="label",
},
login={
login_pw={
title="Connexion",
register="Enregistrement",
-- login_mail="Login with E-mail/Sign Up",
email="E-mail",
password="Mot de passe",
-- showEmail="Show Email",
-- keepPW="Remember me",
login="Connexion",
},
register={
title="Enregistrement",
login="Connexion",
username="Nom d'utilisateur",
login_mail={
title="Connexion/Enregistrement",
-- login_pw="Password Sign In",
email="E-mail",
-- send="Send code",
-- code="Verification Code",
-- verify="Verify",
},
reset_password={
-- title="Reset Password",
-- send="Send code",
-- code="Verification Code",
password="Mot de passe",
password2="Confirmer le mot de passe",
register="Enregistrement",
-- registering="Waiting for response...",
-- setPW="Set Password",
},
account={
title="Compte",

View File

@@ -105,6 +105,14 @@ return{
dictNote="==Tersalin dari TetroDictionary==",
Techrater={-- Server's warn/error messages
-- TODO
},
-- tooFrequently="Request too frequently",
-- roomPasswordChanged="Room password changed",
getNoticeFail="Gagal mengambil pengumuman-pengumuman",
oldVersion="Versi $1 sekarang tersedia",
needUpdate="Butuh versi lebih baru!",
@@ -115,23 +123,23 @@ return{
noUsername="Silahkan memasukan username Anda",
wrongEmail="Alamat email tidak sah",
-- wrongCode="Invalid verification code",
noPassword="Silahkan memasukan kata sandi Anda",
diffPassword="Kata sandi tidak sama",
registerRequestSent="Permintaan daftar telah terkirim.",
registerOK="Pendaftaran sukses!",
loginOK="Anda telah gabung!",
accessOK="Akses diberikan",
checkEmail="Permintaan daftar telah terkirim.",
wsConnecting="Menghubungkan websocket…",
wsFailed="Koneksi websocket gagal",
wsClose="Websocket tertutup:",
wsFailed="Koneksi websocket gagal: $1",
wsClose="Websocket tertutup: $1",
netTimeout="Koneksi waktu habis",
-- serverDown="Oops! Server is down",
-- requestFailed="Request failed",
onlinePlayerCount="Online",
onlinePlayerCount="Online: $1",
createRoomSuccessed="Ruang terbuat",
-- playerKicked="[$1] removed [$2] from room",
started="Bermain",
joinRoom="telah memasuki ruangan.",
leaveRoom="telah keluar dari ruangan.",
joinRoom="$1 telah memasuki ruangan.",
leaveRoom="$1 telah keluar dari ruangan.",
ready="Siap",
connStream="Memuat",
waitStream="Menunggu",
@@ -140,6 +148,8 @@ return{
chatStart="------Awal percakapan------",
chatHistory="------Pesan-pesan baru di bawah ini------",
keySettingInstruction="Tekan untuk menghubung tombol ke aksi tertentu\nescape: batal\nbackspace: hapus",
customBGhelp="Seret file gambar di sini untuk memasangkan background",
customBGloadFailed="Format file gambar tidak didukung untuk background",
@@ -323,6 +333,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Dukung pencipta",
WidgetText={
@@ -362,6 +373,7 @@ return{
league="Tech League",
ffa="FFA",
rooms="Ruang-ruang",
-- resetPW="Reset password",
logout="Log out",
},
net_league={
@@ -438,7 +450,6 @@ return{
sysCursor="Guna Mouse Bawaan",
autoPause="Jeda Jika Tidak Difokus",
autoSave="Simpan Rekor Otomatis",
autoLogin="Auto-login Saat Membuka",
simpMode="Mode Sederhana",
},
setting_video={
@@ -689,24 +700,29 @@ return{
music="Musik",
label="label",
},
login={
login_pw={
title="Masuk",
register="Daftar",
-- login_mail="Login with E-mail/Sign Up",
email="Alamat Email",
password="Password",
showEmail="Tunjukkan Email",
keepPW="Ingat Saya",
login="Masuk",
},
register={
title="Daftar",
login="Masuk",
username="Username",
login_mail={
title="Masuk/Daftar",
-- login_pw="Password Sign In",
email="Alamat Email",
-- send="Send code",
-- code="Verification Code",
-- verify="Verify",
},
reset_password={
-- title="Reset Password",
-- send="Send code",
-- code="Verification Code",
password="Password",
password2="Ulangi Password",
register="Daftar",
registering="Menunggu respon…",
-- setPW="Set Password",
},
account={
title="Akun",

View File

@@ -105,6 +105,14 @@ return{
dictNote="==TetroDictionaryからコピーしました==",
Techrater={-- Server's warn/error messages
-- TODO
},
-- tooFrequently="Request too frequently",
-- roomPasswordChanged="Room password changed",
getNoticeFail="お知らせ情報を取得できませんでした",
oldVersion="バージョン$1のダウンロードが可能になりました",
needUpdate="最新バージョンに更新してください",
@@ -115,23 +123,23 @@ return{
noUsername="ユーザーネームを入力してください!",
wrongEmail="メールアドレスが無効です!",
-- wrongCode="Invalid verification code",
noPassword="パスワードを入力してください!",
diffPassword="パスワードが一致しません!",
registerRequestSent="Sign Upリクエストを送信しました!",
registerOK="サインアップ成功!",
loginOK="ログインしています!",
accessOK="アクセス権限を取得しました!",
checkEmail="Sign Upリクエストを送信しました!",
wsConnecting="ウェブソケットに接続中…",
wsFailed="ウェブソケットとの通信に失敗しました",
wsClose="ウェブソケットとの通信を終了:",
wsFailed="ウェブソケットとの通信に失敗しました: $1",
wsClose="ウェブソケットとの通信を終了: $1",
netTimeout="接続がタイムアウトしました",
-- serverDown="Oops! Server is down",
-- requestFailed="Request failed",
onlinePlayerCount="オンライン人数",
onlinePlayerCount="オンライン人数: $1",
createRoomSuccessed="部屋を建てました",
-- playerKicked="[$1] removed [$2] from room",
started="プレイ中",
joinRoom="が入室しました",
leaveRoom="が退出しました",
joinRoom="$1 が入室しました",
leaveRoom="$1 が退出しました",
ready="準備OK",
connStream="接続中……",
waitStream="待機中……",
@@ -140,6 +148,8 @@ return{
chatStart="------チャットの先頭------",
chatHistory="------新しいメッセージ------",
keySettingInstruction="選択してキーを入力\nEscape: キャンセル\nBackspace: キーを削除",
customBGhelp="カスタム背景にする画像ファイルをドロップ",
customBGloadFailed="サポートされていないフォーマットのファイルです",
@@ -324,6 +334,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Support the Author",
WidgetText={
@@ -363,6 +374,7 @@ return{
league="テクリーグ",
ffa="自由乱闘戦",
rooms="ルーム・プライベート戦",
-- resetPW="Reset password",
logout="ログアウト",
},
net_league={
@@ -439,7 +451,6 @@ return{
sysCursor="システムカーソル",
autoPause="ゲーム中断時のオートポーズ",
autoSave="最高得点を更新したときオートセーブ",
autoLogin="オートログイン",
simpMode="シンプルなホーム画面",
},
setting_video={
@@ -690,24 +701,29 @@ return{
music="",
label="ラベル",
},
login={
login_pw={
title="サインイン",
register="サインアップ",
-- login_mail="Login with E-mail/Sign Up",
email="Eメールアドレス",
password="パスワード",
-- showEmail="Show Email",
keepPW="常にログイン",
login="ログイン",
},
register={
title="サインアップ",
login="サインイン",
username="ユーザーネーム",
login_mail={
title="サインイン/サインアップ",
-- login_pw="Password Sign In",
email="Eメールアドレス",
-- send="Send code",
-- code="Verification Code",
-- verify="Verify",
},
reset_password={
-- title="Reset Password",
-- send="Send code",
-- code="Verification Code",
password="パスワード",
password2="パスワード(確認)",
register="これで登録する",
registering="応答待機中...",
-- setPW="Set Password",
},
account={
title="アカウント",

View File

@@ -92,6 +92,14 @@ return{
-- dictNote="==Copied from TetroDictionary==",
Techrater={-- Server's warn/error messages
-- TODO
},
-- tooFrequently="Request too frequently",
-- roomPasswordChanged="Room password changed",
getNoticeFail="Não conseguiu ter anúncios",
oldVersion="Versão $1 esta disponível agora!",
-- versionNotMatch="Version do not match!",
@@ -102,23 +110,23 @@ return{
noUsername="Insira seu nome de usuário",
wrongEmail="Endereço de email errado",
-- wrongCode="Invalid verification code",
noPassword="Insira sua senha ",
diffPassword="Senhas não combinam",
-- registerRequestSent="Registration request sent",
registerOK="Registrado com sucesso!",
loginOK="Logado com sucesso!",
accessOK="Autorizado com sucesso!",
-- checkEmail="Registration request sent",
-- wsConnecting="Websocket Connecting",
wsFailed="WebSocket falha na conexão",
wsClose="WebSocket closed:",
wsFailed="WebSocket falha na conexão: $1",
wsClose="WebSocket closed: $1",
-- netTimeout="Network connection timeout",
-- serverDown="Oops! Server is down",
-- requestFailed="Request failed",
-- onlinePlayerCount="Online",
-- onlinePlayerCount="Online: $1",
-- createRoomSuccessed="Room successfully created!",
-- playerKicked="[$1] removed [$2] from room",
-- started="Playing",
joinRoom="Entrou a sala.",
leaveRoom="Saiu da sala.",
joinRoom="$1 Entrou a sala.",
leaveRoom="$1 Saiu da sala.",
-- ready="READY",
-- connStream="CONNECTING",
-- waitStream="WAITING",
@@ -127,6 +135,8 @@ return{
chatStart="------Começo do log------",
chatHistory="------Novas mensagens abaixo------",
-- keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete",
-- customBGhelp="Drop image file here to apply custom background",
-- customBGloadFailed="Unsupport image format for custom background",
@@ -311,6 +321,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="Support author",
WidgetText={
@@ -350,6 +361,7 @@ return{
-- league="Tech League",
ffa="FFA",
rooms="Salas",
-- resetPW="Reset password",
-- logout="Log out",
},
net_league={
@@ -426,7 +438,6 @@ return{
-- sysCursor="Use system cursor",
autoPause="Pausar quando foco for perco",
-- autoSave="Auto save new-best",
-- autoLogin="Auto Login on Start",
-- simpMode="Simple mode",
},
setting_video={
@@ -678,24 +689,29 @@ return{
-- music="BGMs",
-- label="label",
},
login={
login_pw={
title="Log in",
register="Registrar",
-- login_mail="Login with E-mail/Sign Up",
email="Endereço De Email",
password="Senha",
-- showEmail="Show Email",
-- keepPW="Remember me",
login="Log in",
},
register={
title="Registrar",
login="Log in",
username="Nome De Usuário",
login_mail={
title="Log in/Registrar",
-- login_pw="Password Sign In",
email="Endereço De Email",
-- send="Send code",
-- code="Verification Code",
-- verify="Verify",
},
reset_password={
-- title="Reset Password",
-- send="Send code",
-- code="Verification Code",
password="Senha",
password2="Entre Senha Novamente",
register="Registrar",
-- registering="Waiting for response...",
-- setPW="Set Password",
},
account={
title="Conta",

View File

@@ -166,6 +166,7 @@ return{
league="TL",
ffa="FFA",
rooms="< >",
resetPW="R ***",
logout="@_@x",
},
net_league={
@@ -242,7 +243,6 @@ return{
sysCursor="?→*",
autoPause="A||",
autoSave="!!!>%",
autoLogin="#Log in#",
simpMode=".",
},
setting_video={
@@ -484,24 +484,29 @@ return{
music="~~~",
label="...",
},
login={
login_pw={
title="Log in",
register="Sign up",
-- login_mail="Login with E-mail/Sign Up",
email="@",
password="*",
showEmail="?",
keepPW="!",
login="Log in",
login="",
},
register={
title="Sign up",
login="Log in",
username="#",
login_mail={
title="Log in/Sign up",
login_pw="*** →",
email="@",
send="",
code="",
verify="!",
},
reset_password={
title="R ***",
send="",
code="",
password="*",
password2="*",
register="Sign up",
registering="......",
setPW="##",
},
account={
title="@_@",

View File

@@ -104,6 +104,14 @@ return{
dictNote="==复制于小z词典==",
Techrater={-- Server's warn/error messages
-- TODO
},
tooFrequently="操作太频繁",
roomPasswordChanged="房间密码已更改",
getNoticeFail="拉取公告失败",
oldVersion="最新版本$1可以下载了",
needUpdate="请更新游戏!",
@@ -113,24 +121,24 @@ return{
jsonError="json错误",
noUsername="请填写用户名",
wrongEmail="邮箱格式错误",
wrongEmail="无效邮箱地址",
wrongCode="无效验证码",
noPassword="请填写密码",
diffPassword="两次密码不一致",
registerRequestSent="注册请求已发送",
registerOK="注册成功!",
loginOK="登录成功",
accessOK="身份验证成功",
checkEmail="请查看邮箱验证码",
wsConnecting="正在连接",
wsFailed="连接失败",
wsClose="连接被断开:",
wsFailed="连接失败: $1",
wsClose="连接断开: $1",
netTimeout="连接超时",
serverDown="唉哟!服务器不在线",
requestFailed="请求失败",
onlinePlayerCount="在线人数",
onlinePlayerCount="在线人数: $1",
createRoomSuccessed="创建房间成功!",
playerKicked="<$1>把<$2>移出了房间",
started="游戏中",
joinRoom="进入房间",
leaveRoom="离开房间",
joinRoom="$1 进入房间",
leaveRoom="$1 离开房间",
ready="各就各位!",
connStream="正在连接",
waitStream="等待其他人连接",
@@ -139,12 +147,14 @@ return{
chatStart="------消息的开头------",
chatHistory="------以上是历史消息------",
keySettingInstruction="点击添加键位绑定\nesc取消选中\n退格键清空选中",
customBGhelp="把图片文件拖到这个窗口里使用自定义背景",
customBGloadFailed="自定义背景的图片文件格式不支持",
errorMsg="Techmino遭受了雷击需要重新启动。\n我们已收集了一些错误信息,你可以向作者进行反馈。",
tryAnotherBuild="[解码UTF-8错误] 如果你现在用的是Windows系统请重新下载 Techmino-32位 或者 Techmino-64位 (和现在运行的不一样的那个)。",
tryAnotherBuild="[解码UTF-8错误] 如果你现在用的是Windows系统请重新下载 Techmino-32/64位 (和现在运行的不一样的那个)。",
modInstruction="选择你要使用的Mod\n不同Mod会用不同的方式改变初始游戏规则(可能导致不能正常游玩)\n来开发新玩法或者挑战自我吧!\n提醒:开启一些Mod会让成绩无效你也可以用键盘开关Mod按住shift反向",
modInfo={
@@ -323,6 +333,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="支持作者",
WidgetText={
@@ -362,6 +373,7 @@ return{
league="Tech League",
ffa="FFA",
rooms="房间列表",
resetPW="重置密码",
logout="退出登录",
},
net_league={
@@ -438,7 +450,6 @@ return{
sysCursor="使用系统光标",
autoPause="失去焦点自动暂停",
autoSave="破纪录自动保存",
autoLogin="启动时自动登录",
simpMode="简洁模式",
},
setting_video={
@@ -688,24 +699,29 @@ return{
path="打开存储目录",
save="用户档案管理",
},
login={
login_pw={
title="登录",
register="注册",
login_mail="邮箱登录/注册",
email="邮箱",
password="密码",
showEmail="显示邮箱",
keepPW="保存密码",
login="登录",
},
register={
title="注册",
login="登录",
username="用户名",
email="邮箱:",
password="密码:",
password2="确认密码:",
register="注册",
registering="等待服务器响应……",
login_mail={
title="登录/注册",
login_pw="密码登录",
email="邮箱",
send="发送验证码",
code="验证码",
verify="验证邮箱",
},
reset_password={
title="重置密码",
send="发送验证码",
code="验证码",
password="密码",
password2="确认密码",
setPW="设置密码",
},
account={
title="帐户",

View File

@@ -104,9 +104,17 @@ return{
dictNote="#!CopySource=Zictionary",
Techrater={-- Server's warn/error messages
-- TODO
},
tooFrequently="Error.requestTooFrequently();",
roomPasswordChanged="Info.roomPwChanged();",
getNoticeFail="Error.FetchAnnouncement();",
oldVersion="Version.New($1);",
needUpdate="Version.NeedUpdate()",
needUpdate="Version.NeedUpdate();",
versionNotMatch="Version.NotMatch();",
notFinished="ComingSoon();",
@@ -114,23 +122,23 @@ return{
noUsername="Error.NoUsername();",
wrongEmail="Error.WrongEmail();",
wrongCode="Error.WrongVerificationCode();",
noPassword="Error.NoPassword();",
diffPassword="Error.DiffPassword();",
registerRequestSent="register.RequestSent=true",
registerOK="register.Success=true",
loginOK="login.Success=true",
accessOK="Access.Granted=true",
checkEmail="register.RequestSent=true",
wsConnecting="Websocket.Connect();",
wsFailed="Error.Websocket.Failed();",
wsClose="Error.Websocket.Close=",
wsFailed="Error.Websocket.Failed=$1",
wsClose="Error.Websocket.Close=$1",
netTimeout="Error.ConnectTimeOut();",
serverDown="Error.ServerDown();",
requestFailed="Error.RequestFailed();",
onlinePlayerCount="OnlinePlayerCount",
onlinePlayerCount="OnlinePlayerCount=$1",
createRoomSuccessed="CreateRoom.Successs=true",
playerKicked="[$1]: roomKick([$2])",
started="Room.Playing();",
joinRoom="Room.Join();",
leaveRoom="Room.Leave();",
joinRoom="Room.Join($1);",
leaveRoom="Room.Leave($1);",
ready="Ready();",
connStream="Stream.Connecting();",
waitStream="Stream.Waiting();",
@@ -139,12 +147,14 @@ return{
chatStart="#!Log.Beginning();",
chatHistory="#!NewMassagesBelow();",
keySettingInstruction="Key.Bind(Press);\nKey.Bind.Cancel(Escspe);\nKey.Bind.Delete(Backspace);",
customBGhelp="Ctm.BG(DropHere);",
customBGloadFailed="Error.Ctm.BG(UnsupportFormat);",
errorMsg="Error.Fatal();\n//请检查语法错误或向作者进行反馈。",
tryAnotherBuild="Error.DecodeUTF8(); //如果你现在用的是Windows系统请重新下载 Techmino-32位 或者 Techmino-64位 (和现在运行的不一样的那个)。",
tryAnotherBuild="Error.DecodeUTF8(); //如果你现在用的是Windows系统请重新下载 Techmino-32/64位 (和现在运行的不一样的那个)。",
modInstruction="Mod.Instruction();\n/*选择你要使用的Mod\n不同Mod会用不同的方式改变初始游戏规则(可能导致不能正常游玩)\n提醒:开启一些Mod会让成绩无效你也可以用键盘开关Mod按住shift反向*/",
modInfo={
@@ -324,6 +334,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="支持作者",
WidgetText={
@@ -363,6 +374,7 @@ return{
league="M.TechLeague();",
ffa="M.FFA",
rooms="M.Rooms();",
resetPW="M.ResetPW",
logout="M.Logout();",
},
net_league={
@@ -439,7 +451,6 @@ return{
sysCursor="Set.SysCursor",
autoPause="Set.AutoPause",
autoSave="Set.AutoSave",
autoLogin="Set.AutoLogin",
simpMode="Set.SimpMode",
},
setting_video={
@@ -689,24 +700,29 @@ return{
path="OpenPath();",
save="DataManagement();",
},
login={
login_pw={
title="LogIn.UI",
register="Register();",
login_mail="Login_mail_sign_up()",
email="Email=",
password="Password=",
showEmail="ShowEmail",
keepPW="KeepPassword",
login="Login();",
},
register={
title="Register.UI",
login="Login();",
username="Username=",
login_mail={
title="LogIn_Register.UI",
login_pw="Login_pw();",
email="Email=",
send="Send();",
code="V-code=",
verify="Verify();",
},
reset_password={
title="Reset_Password.UI",
send="Send();",
code="V-code=",
password="Password=",
password2="RePassword=",
register="Register();",
registering="Waiting();",
setPW="SetPassword();",
},
account={
title="Account.UI",

View File

@@ -104,6 +104,14 @@ return{
dictNote="==拷貝自小z辭典==",
Techrater={-- Server's warn/error messages
-- TODO
},
tooFrequently="操作太頻繁",
roomPasswordChanged="房間密碼已更改",
getNoticeFail="無法獲取公告",
oldVersion="版本 $1 現已推出",
needUpdate="請更新遊戲!",
@@ -114,23 +122,23 @@ return{
noUsername="請輸入用戶名",
wrongEmail="無效的電郵地址",
wrongCode="無效的驗證碼",
noPassword="請輸入密碼",
diffPassword="密碼不匹配",
registerRequestSent="已發送註冊請求",
registerOK="註冊成功!",
loginOK="登錄成功",
accessOK="身份認證成功",
checkEmail="已發送註冊請求",
wsConnecting="正在連接……",
wsFailed="連接失敗",
wsClose="連接斷開:",
wsFailed="連接失敗: $1",
wsClose="連接斷開: $1",
netTimeout="連接超時",
serverDown="哎唷!服務器不在线",
requestFailed="請求失敗",
onlinePlayerCount="在線用戶數",
onlinePlayerCount="在線用戶數: $1",
createRoomSuccessed="房間已創建!",
playerKicked="<$1>把<$2>移出了房間",
started="遊戲中",
joinRoom="進入房間",
leaveRoom="離開房間",
joinRoom="$1 進入房間",
leaveRoom="$1 離開房間",
ready="準備!",
connStream="正在連接……",
waitStream="等待其他用戶連接……",
@@ -139,6 +147,8 @@ return{
chatStart="------訊息開始------",
chatHistory="------以上為歷史訊息------",
keySettingInstruction="點擊來設置鍵位\n按esc來取消選中\n按退格鍵來清除選中",
customBGhelp="把圖片檔案拖到這個視窗裏使用自定義背景",
customBGloadFailed="自定義背景的圖片檔案格式不支持",
@@ -323,6 +333,7 @@ return{
Cold_Clear [MinusKelvin]
json.lua [rxi]
profile.lua [itraykov]
sha2 [Egor Skriptunoff]
]],
support="支持作者",
WidgetText={
@@ -362,6 +373,7 @@ return{
league="Tech League",
ffa="FFA",
rooms="房間列表",
resetPW="重設密碼",
logout="登出",
},
net_league={
@@ -438,7 +450,6 @@ return{
sysCursor="使用系統光標",
autoPause="失去焦點時暫停",
autoSave="打破紀錄時自動保存",
autoLogin="啟動時自動登錄",
simpMode="簡潔模式",
},
setting_video={
@@ -688,24 +699,29 @@ return{
path="打開存儲目錄",
save="用戶資料管理",
},
login={
login_pw={
title="登錄",
register="註冊",
login_mail="電郵登錄/注册",
email="電郵",
password="密碼",
showEmail="顯示郵箱",
keepPW="保存密碼",
login="登錄",
},
register={
title="註冊",
login="登錄",
username="用戶名",
login_mail={
title="登錄/註冊",
login_pw="密碼登錄",
email="電郵",
send="發送驗證碼",
code="驗證碼",
verify="驗證郵箱",
},
reset_password={
title="重設密碼",
send="發送驗證碼",
code="驗證碼",
password="密碼",
password2="確認密碼",
register="註冊",
registering="等待伺服器響應……",
setPW="設置密碼",
},
account={
title="賬戶",

View File

@@ -5,7 +5,7 @@ return{
sequence=function(P)
for _=1,3 do P:getNext(7) end
while true do
YIELD()
coroutine.yield()
if not P.nextQueue[1] then
local height=TABLE.new(0,10)
local max=#P.field

View File

@@ -1,4 +1,4 @@
local yield=YIELD
local yield=coroutine.yield
local function marginTask(P)
local S=P.stat
while true do yield() if S.frame>90*60 then P.strength=1;P:setFrameColor(1)break end end
@@ -12,19 +12,26 @@ 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
GAME.modeEnv.task=marginTask
local L=TABLE.copy(NETPLY.list)
local L=TABLE.shift(NETPLY.list,0)
table.sort(L,function(a,b) return a.uid<b.uid end)
math.randomseed(GAME.seed)
for i=#L,1,-1 do
table.insert(NETPLY.list,table.remove(NETPLY.list,math.random(i)))
end
TABLE.clear(NET.uid_sid)
for i=1,#L do NET.uid_sid[L[i].uid]=i end
local N=1
for i,p in next,L do
if p.uid==USER.uid then
if p.connected then
if p.playMode=='Gamer' then
PLY.newPlayer(1)
PLAYERS[1].sid=NETPLY.getSID(USER.uid)
N=2
end
table.remove(L,i)
@@ -32,7 +39,7 @@ return{
end
end
for _,p in next,L do
if p.connected then
if p.playMode=='Gamer' then
PLY.newRemotePlayer(N,false,p)
N=N+1
end

File diff suppressed because it is too large Load Diff

View File

@@ -71,9 +71,8 @@ local nullIndex={
MES.new('error',"User not loaded: "..k)
NETPLY.add{
uid=k,
username="Stacker",
sid=-1,
mode=0,
playMode='Spectator',
readyMode='Standby',
config="",
}
return self[k]
@@ -107,11 +106,10 @@ end
function NETPLY.add(d)
local p={
uid=d.uid,
username=d.username,
sid=d.sid,
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,
}
@@ -122,9 +120,9 @@ function NETPLY.add(d)
PLYmap[p.uid]=p
_freshPos()
end
function NETPLY.remove(sid)
function NETPLY.remove(uid)
for i=1,#PLYlist do
if PLYlist[i].sid==sid then
if PLYlist[i].uid==uid then
PLYmap[PLYlist[i].uid]=nil
rem(PLYlist,i)
_freshPos()
@@ -133,36 +131,6 @@ function NETPLY.remove(sid)
end
end
function NETPLY.getCount()return #PLYlist end
function NETPLY.getSID(uid)return PLYmap[uid].sid end
function NETPLY.getSelfJoinMode()return PLYmap[USER.uid].mode end
function NETPLY.getSelfReady()return PLYmap[USER.uid].mode>0 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
NET.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
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={
@@ -171,12 +139,6 @@ function NETPLY.setStat(uid,S)
adpm=("%.1f %s"):format((S.atk+S.dig)/S.time*60,text.radarData[2]),
}
end
function NETPLY.resetState()
for i=1,#PLYlist do
PLYlist[i].mode=0
PLYlist[i].connected=false
end
end
local selP,mouseX,mouseY
function NETPLY.mouseMove(x,y)
@@ -212,18 +174,23 @@ 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
if p.readyMode=='Standby' then
gc_setColor(COLOR.Z)
elseif p.readyMode=='Ready' then
gc_setColor(COLOR.N)
else
gc_setColor(.26,.62,.26,.26)
gc_rectangle('fill',0,0,p.w,p.h)
gc_setColor(COLOR.lG)
end
else
gc_setColor(COLOR.dX)
gc_rectangle('fill',0,0,p.w,p.h)
gc_setColor(COLOR.dH)
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
@@ -239,12 +206,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
@@ -276,7 +243,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

@@ -121,7 +121,7 @@ local function _newEmptyPlayer(id,mini)
-- User-related
P.username=""
P.uid=false
P.sid=id
P.sid=false
-- Block states
--[[
@@ -399,19 +399,18 @@ function PLY.newDemoPlayer(id)
}
P:popNext()
end
function PLY.newRemotePlayer(id,mini,ply)
function PLY.newRemotePlayer(id,mini,p)
local P=_newEmptyPlayer(id,mini)
P.type='remote'
P.draw=ply_draw.norm
P:startStreaming()
NETPLY.setPlayerObj(ply,P)
P.uid=ply.uid
P.username=ply.username
P.sid=ply.sid
P.uid=p.uid
P.username=USERS.getUsername(p.uid)
P.sid=NET.uid_sid[p.uid]
_loadRemoteEnv(P,ply.config)
_loadRemoteEnv(P,p.config)
_applyGameEnv(P)
end
function PLY.newAIPlayer(id,AIdata,mini)
@@ -430,8 +429,9 @@ function PLY.newPlayer(id,mini)
P.type='human'
P.sound=true
P.uid=USER.uid
P.username=USERS.getUsername(USER.uid)
P.uid=USER.uid
P.sid=NET.uid_sid[USER.uid]
_loadGameEnv(P)
_applyGameEnv(P)

View File

@@ -2845,7 +2845,7 @@ function Player:lose(force)
gameOver()
self:newTask(#PLAYERS>1 and task_lose or task_finish)
if GAME.net and not NET.spectate then
NET.signal_die()
NET.player_finish({foo="-- TODO"})
else
TASK.new(task_autoPause)
end

View File

@@ -1,5 +1,5 @@
local ins,rem=table.insert,table.remove
local yield=YIELD
local yield=coroutine.yield
local seqGenerators={
none=function() while true do yield() end end,

View File

@@ -33,7 +33,7 @@ function scene.draw()
-- Lib used
setFont(15)
gc.print(text.used,495,462)--❤Flandre❤
gc.print(text.used,495,426)-- ❤Flandre❤
-- Logo
gc.draw(TEXTURE.title,280,610,.1,.4+.03*sin(TIME()*2.6),nil,580,118)

View File

@@ -17,6 +17,8 @@ local history,hisPtr={"?"}
local sumode=false
local the_secret=(0xe^2*10)..(2*0xb)
local scene={}
local commands={} do
--[[
format of elements in table 'commands':
@@ -131,7 +133,7 @@ local commands={}do
code=function()
local L=love.filesystem.getDirectoryItems""
for _,name in next,L do
if love.filesystem.getRealDirectory(name)==SAVEDIR then
if FILE.isSafe(name) then
tree("",name,0)
end
end
@@ -708,7 +710,7 @@ local commands={}do
outputBox.h=500
local button=WIDGET.newButton{name='bye',x=640,y=615,w=426,h=100,code=function()
TASK.new(function()
WIDGET.active.bye.hide=true
scene.widgetList.bye.hide=true
for _=1,30 do coroutine.yield() end
log{C.R,"Deleting all data in 10..."}SFX.play('ready')SFX.play('clear_1')TEST.yieldN(60)
log{C.R,"Deleting all data in 9..."}SFX.play('ready')SFX.play('clear_1')TEST.yieldN(60)
@@ -726,7 +728,7 @@ local commands={}do
end)
end}
button:setObject("Techmino is fun. Bye.")
ins(WIDGET.active,button)
ins(scene.widgetList,button)
else
log"Are you sure you want to reset everything?"
log"This will delete EVERYTHING in your saved game data, including but not limited to:"
@@ -895,39 +897,26 @@ local commands={}do
"Example: switchhost 127.0.0.1 26000 /sock",
},
}
function commands.manage()
if WS.status('manage')=='running'then
WS.close('manage')
log{C.Y,"Disconnected"}
else
if({[1]=0,[2]=0,[26]=0})[USER.uid]then
NET.wsconn_manage()
log{C.Y,"Connecting"}
else
log{C.R,"Permission denied"}
end
end
end
function commands.m_broadcast(str)
if #str>0 then
WS.send('manage','{"action":0,"data":'..JSON.encode{message=str}..'}')
WS.send('game',JSON.encode{action=0,data={message=str}})
log{C.Y,"Request sent"}
else
log{C.R,"Format error"}
end
end
function commands.m_shutdown(sec)
sec=tonumber(sec)
if sec and sec>0 and sec~=math.floor(sec) then
WS.send('manage','{"action":9,"data":'..JSON.encode{countdown=tonumber(sec)}..'}')
function commands.m_shutdown(time)
time=tonumber(time)
if time and time>1 then
WS.send('game',JSON.encode{action=0,data={countdown=time}})
log{C.Y,"Request sent"}
else
log{C.R,"Format error"}
end
end
function commands.m_connInfo()WS.send('manage','{"action":10}')end
function commands.m_playMgrInfo()WS.send('manage','{"action":11}')end
function commands.m_streamMgrInfo()WS.send('manage','{"action":12}')end
function commands.m_connInfo() WS.send('game',JSON.encode{action=10}) end
function commands.m_playMgrInfo() WS.send('game',JSON.encode{action=11}) end
function commands.m_streamMgrInfo() WS.send('game',JSON.encode{action=12}) end
for cmd,body in next,commands do
if type(body)=='function' then
@@ -1025,8 +1014,6 @@ userG.the_key=first_key
local scene={}
function scene.sceneInit()
WIDGET.focus(inputBox)
BG.set('none')

View File

@@ -72,7 +72,7 @@ function scene.keyDown(key)
local l={1,2,3,4,5,6,7}
repeat scene.keyDown(rem(l,math.random(#l))) until not l[1]
elseif key=='tab' then
WIDGET.active.sequence:scroll(kb.isDown('lshift','rshift')and -1 or 1)
scene.widgetList.sequence:scroll(kb.isDown('lshift','rshift') and -1 or 1)
elseif key=='c' and kb.isDown('lctrl','rctrl') or key=='cC' then
if #BAG>0 then
sys.setClipboardText("Techmino SEQ:"..DATA.copySequence())

View File

@@ -9,10 +9,7 @@ function scene.sceneInit()
sysAndScn=SYSTEM.."-"..VERSION.string.." scene:"..Z.getErr('#').scene
errorText=LOADED and text.errorMsg or "An error has occurred while the game was loading.\nAn error log has been created so you can send it to the author."
errorShot,errorInfo=Z.getErr('#').shot,Z.getErr('#').mes
NET.wsclose_app()
NET.wsclose_user()
NET.wsclose_play()
NET.wsclose_stream()
NET.ws_close()
if SETTING then
SFX.fplay('error',SETTING.voc*.8 or 0)
end

View File

@@ -18,24 +18,24 @@ local repRateStrings={[0]="pause",[.125]="0.125x",[.5]="0.5x",[1]="1x",[2]="2x",
local scene={}
local function _updateMenuButtons()
WIDGET.active.restart.hide=replaying
scene.widgetList.restart.hide=replaying
local pos=(GAME.tasUsed or replaying) and 'right' or SETTING.menuPos
modeTextWidK=math.min(280/TEXTOBJ.modeName:getWidth(),1)
if GAME.replaying then
WIDGET.active.pause.x=1195
scene.widgetList.pause.x=1195
modeTextPos=1185-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='right' then
WIDGET.active.restart.x=1125
WIDGET.active.pause.x=1195
scene.widgetList.restart.x=1125
scene.widgetList.pause.x=1195
modeTextPos=1115-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='middle' then
WIDGET.active.restart.x=360
WIDGET.active.pause.x=860
scene.widgetList.restart.x=360
scene.widgetList.pause.x=860
modeTextPos=940
elseif pos=='left' then
WIDGET.active.restart.x=120
WIDGET.active.pause.x=190
scene.widgetList.restart.x=120
scene.widgetList.pause.x=190
modeTextPos=1200-TEXTOBJ.modeName:getWidth()*modeTextWidK
end
end

View File

@@ -2,7 +2,7 @@ local scene={}
function scene.sceneInit()
BG.set('cubes')
WIDGET.active.texts:setTexts(require"parts.updateLog":split("\n"))
scene.widgetList.texts:setTexts(require"parts.updateLog":split("\n"))
end
function scene.wheelMoved(_,y)
@@ -10,13 +10,13 @@ function scene.wheelMoved(_,y)
end
function scene.keyDown(key)
if key=='up' then
WIDGET.active.texts:scroll(-5)
scene.widgetList.texts:scroll(-5)
elseif key=='down' then
WIDGET.active.texts:scroll(5)
scene.widgetList.texts:scroll(5)
elseif key=='pageup' then
WIDGET.active.texts:scroll(-20)
scene.widgetList.texts:scroll(-20)
elseif key=='pagedown' then
WIDGET.active.texts:scroll(20)
scene.widgetList.texts:scroll(20)
elseif key=='escape' then
SCN.back()
end

View File

@@ -3,9 +3,9 @@ function scene.sceneInit()
BG.set('cubes')
local fileData=love.filesystem.read("legals.md")
if fileData then
WIDGET.active.texts:setTexts(fileData:split('\n'))
scene.widgetList.texts:setTexts(fileData:split('\n'))
else
WIDGET.active.texts:setTexts{"[legals.md not found]"}
scene.widgetList.texts:setTexts{"[legals.md not found]"}
end
end
@@ -14,13 +14,13 @@ function scene.wheelMoved(_,y)
end
function scene.keyDown(key)
if key=='up' then
WIDGET.active.texts:scroll(-5)
scene.widgetList.texts:scroll(-5)
elseif key=='down' then
WIDGET.active.texts:scroll(5)
scene.widgetList.texts:scroll(5)
elseif key=='pageup' then
WIDGET.active.texts:scroll(-20)
scene.widgetList.texts:scroll(-20)
elseif key=='pagedown' then
WIDGET.active.texts:scroll(20)
scene.widgetList.texts:scroll(20)
elseif key=='escape' then
SCN.back()
end

View File

@@ -26,15 +26,15 @@ local loadingThread=coroutine.wrap(function()
logoColor1={COLOR.rainbow(r)}
logoColor2={COLOR.rainbow_light(r)}
end
YIELD()
YIELD('loadSFX')SFX.load('media/effect/'..SETTING.sfxPack..'/')
YIELD('loadSample')SFX.loadSample{name='bass',path='media/sample/bass',base='A2'}--A2~A4
YIELD('loadSample')SFX.loadSample{name='lead',path='media/sample/lead',base='A3'}--A3~A5
YIELD('loadSample')SFX.loadSample{name='bell',path='media/sample/bell',base='A4'}--A4~A6
YIELD('loadVoice')VOC.load('media/vocal/'..SETTING.vocPack..'/')
YIELD('loadFont')for i=1,17 do getFont(15+5*i)getFont(15+5*i,'mono')end
coroutine.yield()
coroutine.yield('loadSFX')SFX.load('media/effect/'..SETTING.sfxPack..'/')
coroutine.yield('loadSample')SFX.loadSample{name='bass',path='media/sample/bass',base='A2'}-- A2~A4
coroutine.yield('loadSample')SFX.loadSample{name='lead',path='media/sample/lead',base='A3'}-- A3~A5
coroutine.yield('loadSample')SFX.loadSample{name='bell',path='media/sample/bell',base='A4'}-- A4~A6
coroutine.yield('loadVoice')VOC.load('media/vocal/'..SETTING.vocPack..'/')
coroutine.yield('loadFont') for i=1,17 do getFont(15+5*i)getFont(15+5*i,'mono') end
YIELD('loadModeIcon')
coroutine.yield('loadModeIcon')
local modeIcons={}
modeIcons.marathon=GC.DO{64,64,
{'move',3,1},
@@ -91,20 +91,15 @@ local loadingThread=coroutine.wrap(function()
{'fRect',20,10,23,43},
}
YIELD('loadMode')
coroutine.yield('loadMode')
for _,M in next,MODES do
M.records=loadFile("record/"..M.name..".rec",'-luaon -canSkip') or M.score and{}
M.icon=M.icon and (modeIcons[M.icon] or GC.newImage("media/image/modeicon/"..M.icon..".png"))
end
YIELD('loadOther')
coroutine.yield('loadOther')
STAT.run=STAT.run+1
--Connect to server
if SETTING.autoLogin then
NET.wsconn_app()
end
SFX.play('enter',.8)
SFX.play('welcome')
VOC.play('welcome')

View File

@@ -1,47 +0,0 @@
local emailBox=WIDGET.newInputBox{name='email',x=380,y=200,w=500,h=60,limit=128}
local passwordBox=WIDGET.newInputBox{name='password',x=380,y=300,w=620,h=60,secret=true,regex="[ -~]",limit=64}
local savePW=false
local showEmail=true
local function _login()
local email,password=emailBox:getText(),passwordBox:getText()
if not STRING.simpEmailCheck(email)then
MES.new('error',text.wrongEmail)return
elseif #password==0 then
MES.new('error',text.noPassword)return
end
-- password=STRING.digezt(password)
NET.wsconn_user_pswd(email,password)
if savePW then
saveFile({email,password},'conf/account')
else
love.filesystem.remove('conf/account')
end
end
local scene={}
function scene.sceneInit()
local data=loadFile('conf/account','-canSkip')
if data then
savePW=true
showEmail=false
emailBox.secret=true
emailBox:setText(data[1])
passwordBox:setText(data[2])
end
end
scene.widgetList={
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
WIDGET.newButton{name='register', x=1140,y=100,w=170,h=80,color='lY',code=function()SCN.swapTo('register','swipeR')end},
emailBox,
passwordBox,
WIDGET.newSwitch{name='showEmail',x=550, y=420,disp=function()return showEmail end,code=function()showEmail=not showEmail emailBox.secret=not showEmail end},
WIDGET.newSwitch{name='keepPW', x=900, y=420,disp=function()return savePW end,code=function()savePW=not savePW end},
WIDGET.newKey{name='login', x=1140,y=540,w=170,h=80,font=40,code=_login},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -0,0 +1,54 @@
local scene={}
local function _getCode()
local email=scene.widgetList.email:getText()
if not STRING.simpEmailCheck(email) then
MES.new('error',text.wrongEmail)
else
USER.email=email
NET.getCode(email)
end
end
local function _codeLogin()
local code=scene.widgetList.code:getText():upper()
if #code~=8 then
MES.new('error',text.wrongCode)
else
NET.codeLogin(USER.email,code)
end
end
function scene.sceneInit()
scene.widgetList.email:setText(USER.email or "")
scene.widgetList.code:clear()
end
function scene.keyDown(key,rep)
if key=='escape' and not rep then
SCN.back()
elseif key=='return' then
if #scene.widgetList.code:getText():upper()==0 then
_getCode()
else
_codeLogin()
end
else
return true
end
end
scene.widgetList={
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
WIDGET.newButton{name='login_pw', x=1080,y=100,w=260,h=80,color='lY',code=function() SCN.swapTo('login_pw','swipeR') end},
WIDGET.newInputBox{name='email', x=380, y=200,w=626,h=60,limit=128},
WIDGET.newKey{name='send', x=640, y=330,w=300,h=80,font=40,code=_getCode},
WIDGET.newInputBox{name='code', x=380, y=400,w=626 ,h=60,limit=8},
WIDGET.newKey{name='verify', x=640, y=530,w=300,h=80,font=40,code=_codeLogin},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=pressKey'escape'},
}
return scene

40
parts/scenes/login_pw.lua Normal file
View File

@@ -0,0 +1,40 @@
local emailBox=WIDGET.newInputBox{name='email',x=380,y=200,w=500,h=60,limit=128}
local passwordBox=WIDGET.newInputBox{name='password',x=380,y=300,w=620,h=60,secret=true,regex="[ -~]",limit=64}
local showEmail=true
local function _login()
local email,password=emailBox:getText(),passwordBox:getText()
if not STRING.simpEmailCheck(email) then
MES.new('error',text.wrongEmail)return
elseif #password==0 then
MES.new('error',text.noPassword)return
end
NET.pwLogin(email,password)
end
local scene={}
function scene.sceneInit()
showEmail=false
emailBox.secret=true
emailBox:setText(USER.email)
passwordBox:setText("")
end
function scene.keyDown(key,rep)
if key~='return' or rep then return true end
_login()
end
scene.widgetList={
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
WIDGET.newButton{name='login_mail',x=1080,y=100,w=260,h=80,color='lY',code=function() SCN.swapTo('login_mail','swipeL') end},
emailBox,
passwordBox,
WIDGET.newSwitch{name='showEmail', x=550, y=420,disp=function() return showEmail end,code=function() showEmail=not showEmail emailBox.secret=not showEmail end},
WIDGET.newKey{name='login', x=1140,y=540,w=170,h=80,font=40,code=pressKey'return'},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -11,10 +11,10 @@ local widgetX0={
}
local enterConsole=coroutine.wrap(function()
while true do
Snd('bell',.6,'A4',.7,'E5',1,MATH.coin('A5','B5'))YIELD()
Snd('bell',.6,'A4',.7,'F5',1,MATH.coin('C6','D6'))YIELD()
Snd('bell',.6,'A4',.7,'G5',1,MATH.coin('E6','G6'))YIELD()
Snd('bell',.6,'A4',.7,'A5',1,'A6')SFX.play('ren_mega')SCN.go('app_console')YIELD()
Snd('bell',.6,'A4',.7,'E5',1,MATH.coin('A5','B5'))coroutine.yield()
Snd('bell',.6,'A4',.7,'F5',1,MATH.coin('C6','D6'))coroutine.yield()
Snd('bell',.6,'A4',.7,'G5',1,MATH.coin('E6','G6'))coroutine.yield()
Snd('bell',.6,'A4',.7,'A5',1,'A6')SFX.play('ren_mega')SCN.go('app_console')coroutine.yield()
end
end)
function scene.sceneInit()
@@ -47,16 +47,12 @@ function scene.mouseDown(x,y)
end
scene.touchDown=scene.mouseDown
local function _testButton(n)
if NET.getlock('access_and_login')then
MES.new('warn',text.wsConnecting)
else
if WIDGET.isFocus(scene.widgetList[n]) then
return true
else
WIDGET.focus(scene.widgetList[n])
end
end
end
function scene.keyDown(key,isRep)
if isRep then return true end
if key=='1' then
@@ -69,13 +65,7 @@ function scene.keyDown(key,isRep)
end
elseif key=='a' then
if _testButton(3) then
if WS.status('app')=='running'then
NET.tryLogin(false)
elseif WS.status('app')=='dead'then
NET.wsconn_app()
SFX.play('connect')
MES.new('info',text.wsConnecting)
end
NET.autoLogin()
end
elseif key=='z' then
if _testButton(4) then
@@ -167,20 +157,6 @@ function scene.draw()
-- Player
PLAYERS[1]:draw()
--Profile
drawSelfProfile()
--Player count
drawOnlinePlayerCount()
--Connecting mark
if NET.getlock('access_and_login')then
GC.setColor(COLOR.Z)
GC.setLineWidth(10)
local t=TIME()*6.26%6.2832
GC.arc('line','open',scene.widgetList[3].x+865,450,40,t,t+4.26)
end
end
scene.widgetList={

View File

@@ -4,9 +4,9 @@ function scene.sceneInit()
BG.set('cubes')
local fileData=FILE.load('parts/language/manual_'..(SETTING.locale:find'zh' and 'zh' or SETTING.locale:find'ja' and 'ja' or 'en')..'.txt','-string')
if fileData then
WIDGET.active.texts:setTexts(fileData:split('\n'))
scene.widgetList.texts:setTexts(fileData:split('\n'))
else
WIDGET.active.texts:setTexts{"[manual file not found]"}
scene.widgetList.texts:setTexts{"[manual file not found]"}
end
end
@@ -16,13 +16,13 @@ function scene.wheelMoved(_,y)
end
function scene.keyDown(key)
if key=='up' then
WIDGET.active.texts:scroll(-5)
scene.widgetList.texts:scroll(-5)
elseif key=='down' then
WIDGET.active.texts:scroll(5)
scene.widgetList.texts:scroll(5)
elseif key=='pageup' then
WIDGET.active.texts:scroll(-20)
scene.widgetList.texts:scroll(-20)
elseif key=='pagedown' then
WIDGET.active.texts:scroll(20)
scene.widgetList.texts:scroll(20)
elseif key=='escape' then
SCN.back()
end

View File

@@ -45,6 +45,7 @@ function scene.keyDown(key,isRep)
end
elseif not isRep then
if key=='return' or key=='space' then
playing=BGM.getPlaying()[1]
if playing~=bgmList[S] then
BGM.play(bgmList[S])
SFX.play('click')
@@ -52,7 +53,6 @@ function scene.keyDown(key,isRep)
BGM.stop()
SFX.play('click')
end
playing=BGM.getPlaying()[1]
elseif key=='tab' then
SCN.swapTo('launchpad','none')
elseif key=='escape' then
@@ -106,8 +106,7 @@ function scene.draw()
end
-- Music player
print(playing)
if BGM.isPlaying() and playing then
if playing then
setFont(45)
GC.shadedPrint(playing,710,508,'left',2)
GC.setColor(sin(t*.5)*.2+.8,sin(t*.7)*.2+.8,sin(t)*.2+.8)
@@ -132,7 +131,7 @@ scene.widgetList={
disp=function() return BGM.tell()/BGM.getDuration()%1 end,
show=false,
code=function(v) BGM.set('all','seek',v*BGM.getDuration()) end,
hideF=function()return not BGM.isPlaying()end
hideF=function() return not playing end
},
WIDGET.newSlider{name='bgm', x=760,y=80,w=400,disp=SETval('bgm'),code=function(v) SETTING.bgm=v BGM.setVol(SETTING.bgm) end},
WIDGET.newButton{name='up', x=200,y=250,w=120,sound=false,code=pressKey'up',hideF=function() return selected==1 end,font=60,fText=CHAR.key.up},

View File

@@ -10,33 +10,44 @@ local ins=table.insert
local SCR,VK,NET,NETPLY=SCR,VK,NET,NETPLY
local PLAYERS,GAME=PLAYERS,GAME
local textBox=WIDGET.newTextBox{name='texts',x=340,y=80,w=600,h=560}
local inputBox=WIDGET.newInputBox{name='input',x=340,y=660,w=600,h=50,limit=256}
local textBox=NET.textBox
local inputBox=NET.inputBox
local playing
local lastUpstreamTime
local upstreamProgress
local noTouch,noKey=false,false
local touchMoveLastFrame=false
local newMessageTimer
local function _hideReadyUI()
return
playing or
NET.roomState.start or
NET.getlock('ready')
TASK.getLock('ready')
end
local function _setCancel()
if NETPLY.map[USER.uid].playMode=='Gamer' then
NET.player_setReady(false)
else
NET.player_setPlayMode('Gamer')
end
end
local function _setReady()
NET.player_setPlayMode('Gamer')
NET.player_setReady(true)
end
local function _setSpectate()
NET.player_setPlayMode('Spectator')
end
local function _setCancel()NET.signal_setMode(0)end
local function _setReady()NET.signal_setMode(1)end
local function _setSpectate()NET.signal_setMode(2)end
local function _gotoSetting()
GAME.prevBG=BG.cur
SCN.go('setting_game')
end
local function _quit()
if tryBack() then
NET.signal_quit()
NET.room_leave()
if SCN.stack[#SCN.stack-1]=='net_newRoom' then
SCN.pop()
end
@@ -58,30 +69,21 @@ end
local scene={}
function scene.sceneInit()
textBox.hide=true
textBox:clear()
inputBox.hide=true
noTouch=not SETTING.VKSwitch
playing=false
lastUpstreamTime=0
upstreamProgress=1
newMessageTimer=0
if SCN.prev=='setting_game' then
NET.changeConfig()
NET.player_updateConf()
end
if GAME.prevBG then
BG.set(GAME.prevBG)
GAME.prevBG=false
end
if NET.specSRID then
NET.wsconn_stream(NET.specSRID)
NET.specSRID=false
end
end
function scene.sceneBack()
GAME.playing=false
TASK.unlock('netPlaying')
end
scene.mouseDown=NULL
@@ -137,8 +139,9 @@ function scene.keyDown(key,isRep)
elseif key=='return' then
local mes=STRING.trim(inputBox:getText())
if not inputBox.hide and #mes>0 then
NET.sendMessage(mes)
if NET.room_chat(mes) then
inputBox:clear()
end
else
_switchChat()
end
@@ -154,10 +157,10 @@ function scene.keyDown(key,isRep)
end
elseif not _hideReadyUI() then
if key=='space' then
if NETPLY.getSelfJoinMode()==0 then
(kb.isDown('lctrl','rctrl','lalt','ralt')and _setSpectate or _setReady)()
else
if NETPLY.map[USER.uid].playMode=='Spectator' or NETPLY.map[USER.uid].readyMode=='Ready' then
_setCancel()
else
(kb.isDown('lctrl','rctrl','lalt','ralt') and _setSpectate or _setReady)()
end
elseif key=='s' then
_gotoSetting()
@@ -193,50 +196,23 @@ function scene.gamepadUp(key)
end
end
function scene.socketRead(cmd,d)
if cmd=='join'then
textBox:push{
COLOR.lR,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.Y,text.joinRoom,
}
SFX.play('warn_1')
elseif cmd=='leave'then
textBox:push{
COLOR.lR,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.Y,text.leaveRoom,
}
elseif cmd=='talk'then
newMessageTimer=80
textBox:push{
COLOR.Z,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.N,d.message or"[_]",
}
elseif cmd=='go'then
if not playing then
playing=true
lastUpstreamTime=0
upstreamProgress=1
resetGameData('n',NET.seed)
NETPLY.mouseMove(0,0)
else
MES.new('warn',"Redundant [Go]")
end
elseif cmd=='finish'then
playing=false
BG.set()
end
end
function scene.update(dt)
if NET.checkPlayDisconn()then
NET.wsclose_stream()
if WS.status('game')~='running' then
TASK.unlock('netPlaying')
NET.ws_close()
SCN.back()
return
end
if playing then
if not TASK.getLock('netPlaying') then
playing=false
BG.set()
for i=1,#NETPLY.list do
NETPLY.list[i].readyMode='Standby'
end
NET.freshRoomAllReady()
return
else
local P1=PLAYERS[1]
touchMoveLastFrame=false
@@ -261,14 +237,23 @@ function scene.update(dt)
elseif #stream%3==2 then
stream=stream.."\0\0\0\0"
end
NET.uploadRecStream(stream)
NET.player_stream(stream)
lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99
end
end
else
NETPLY.update(dt)
if TASK.getLock('netPlaying') and not playing then
playing=true
TASK.lock('netPlaying')
lastUpstreamTime=0
upstreamProgress=1
resetGameData('n',NET.seed)
NETPLY.mouseMove(0,0)
for i=1,#NETPLY.list do
NETPLY.list[i].readyMode='Playing'
end
end
if newMessageTimer>0 then
newMessageTimer=newMessageTimer-1
end
end
@@ -296,28 +281,23 @@ function scene.draw()
-- Ready & Set mark
setFont(50)
if NET.roomReadyState=='allReady'then
gc_setColor(1,.85,.6,.9)
mStr(text.ready,640,15)
elseif NET.roomReadyState=='connecting'then
gc_setColor(.6,1,.9,.9)
mStr(text.connStream,640,15)
elseif NET.roomReadyState=='waitConn'then
if NET.roomAllReady then
gc_setColor(.6,.95,1,.9)
mStr(text.waitStream,640,15)
mStr(text.ready,640,15)
end
-- Room info.
gc_setColor(1,1,1)
setFont(25)
gc_printf(NET.roomState.roomInfo.name,0,685,1270,'right')
gc_printf(NET.roomState.info.name,0,685,1270,'right')
setFont(40)
gc_print(NETPLY.getCount().."/"..NET.roomState.capacity,70,655)
gc_print(#NETPLY.list.."/"..NET.roomState.capacity,70,655)
if NET.roomState.private then
gc_draw(IMG.lock,30,668)
end
if NET.roomState.start then
gc_setColor(0,1,0)gc_print(text.started,230,655)
gc_setColor(0,1,0)
gc_print(text.started,230,655)
end
-- Profile
@@ -328,21 +308,22 @@ function scene.draw()
end
-- New message
if newMessageTimer>0 then
local a=TASK.getLock('receiveMessage')
if a then
setFont(40)
gc_setColor(.3,.7,1,(newMessageTimer/60)^2)
gc_setColor(.3,.7,1,a^2)
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_ready() return _hideReadyUI() or (NETPLY.map[USER.uid].playMode=='Spectator' or NETPLY.map[USER.uid].readyMode=='Ready') end
local function _hideF_standby() return _hideReadyUI() or not (NETPLY.map[USER.uid].playMode=='Spectator' or NETPLY.map[USER.uid].readyMode=='Ready') end
scene.widgetList={
textBox,
inputBox,
WIDGET.newKey{name='setting', x=1200,y=160,w=90,h=90,font=60,fText=CHAR.icon.settings,code=_gotoSetting,hideF=_hideF_ingame},
WIDGET.newKey{name='ready', x=1060,y=510,w=360,h=90,color='lG',font=35, code=_setReady,hideF=_hideF_ingame},
WIDGET.newKey{name='spectate',x=1060,y=610,w=360,h=90,color='lO',font=35, code=_setSpectate,hideF=_hideF_ingame},
WIDGET.newKey{name='cancel', x=1060,y=560,w=360,h=120,color='lH',font=40,code=_setCancel,hideF=_hideF_ingame2},
WIDGET.newKey{name='setting', x=1200,y=160,w=90,h=90,font=60,fText=CHAR.icon.settings,code=_gotoSetting,hideF=_hideF_ready},
WIDGET.newKey{name='ready', x=1060,y=510,w=360,h=90,color='lG',font=35, code=_setReady,hideF=_hideF_ready},
WIDGET.newKey{name='spectate',x=1060,y=610,w=360,h=90,color='lO',font=35, code=_setSpectate,hideF=_hideF_ready},
WIDGET.newKey{name='cancel', x=1060,y=560,w=360,h=120,color='lH',font=40,code=_setCancel,hideF=_hideF_standby},
WIDGET.newKey{name='chat', x=390,y=45,w=60,fText="···", code=_switchChat},
WIDGET.newKey{name='quit', x=890,y=45,w=60,font=30,fText=CHAR.icon.cross_thick,code=_quit},
}

View File

@@ -4,7 +4,7 @@ function scene.sceneInit()
BG.set()
end
function scene.sceneBack()
NET.wsclose_play()
NET.ws_close()
end
function scene.draw()
@@ -17,18 +17,19 @@ scene.widgetList={
WIDGET.newButton{name='league',x=640, y=180,w=350,h=120,font=40,color='D',code=goScene'net_league'},
WIDGET.newButton{name='ffa', x=640, y=360,w=350,h=120,font=40,color='D',code=function() MES.new('warn',text.notFinished)--[[NET.enterRoom({name='ffa'})]] end},
WIDGET.newButton{name='rooms', x=640, y=540,w=350,h=120,font=40,code=goScene'net_rooms'},
WIDGET.newButton{name='resetPW',x=680,y=40,w=180,h=60,color='dG',code=goScene'reset_password'},
WIDGET.newButton{name='logout',x=880, y=40,w=180, h=60,color='dR',
code=function()
if tryBack() then
if USER.uid then
NET.wsclose_play()
NET.wsclose_user()
USER.uid=false
USER.authToken=false
saveFile(USER,'conf/user')
USER.__data.uid=false
USER.__data.email=false
USER.__data.password=false
USER.__data.rToken=false
USER.__data.aToken=false
love.filesystem.remove('conf/user')
NET.ws_close()
SCN.back()
end
end
end},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
}

View File

@@ -36,14 +36,17 @@ local function _createRoom()
if #roomname==0 then
roomname=(USERS.getUsername(USER.uid) or "Anonymous").."'s room"
end
NET.createRoom(
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

@@ -15,21 +15,34 @@ local roomList=WIDGET.newListBox{name='roomList',x=50,y=50,w=800,h=440,lineH=40,
gc_setColor(1,1,1,.3)
gc_rectangle('fill',0,0,800,40)
end
gc_setColor(1,1,1)
if item.private then
gc_draw(IMG.lock,10,5)
end
gc_print(item.count.."/"..item.capacity,670,-4)
gc_setColor(.9,.9,1)
gc_print(id,45,-4)
if item.start then
gc_setColor(.1,.5,.2)
else
gc_setColor(1,1,.7)
if type(item)=='table' then
gc_setColor(1,1,1)
if item.private then
gc_draw(IMG.lock,10,5)
end
if item.count then
gc_printf(
type(item.count.Spectator)=='number' and item.count.Spectator>0 and
("$1(+$2)/$3"):repD(item.count.Gamer or '?',item.count.Spectator or '?',item.capacity or '?')
or
("$1/$2"):repD(item.count.Gamer or '?',item.capacity or '?'),600,-4,180,'right')
end
if item.info and item.state then
if item.state=='Standby' then
gc_setColor(COLOR.Z)
elseif item.state=='Ready' then
gc_setColor(COLOR.lB)
elseif item.state=='Playing' then
gc_setColor(COLOR.G)
end
gc_print(item.info.name,200,-4)
end
end
gc_print(item.roomInfo.name,200,-4)
end}
local function _hidePW()
local R=roomList:getSel()
@@ -38,20 +51,23 @@ end
local passwordBox=WIDGET.newInputBox{name='password',x=350,y=505,w=500,h=50,secret=true,hideF=_hidePW,limit=64}
--[[roomList[n]={
rid="qwerty",
roomInfo={
name="MrZ's room",
type="classic",
version=1409,
state='Standby',
roomId="qwerty",
count={
Gamer=0,
Spectator=1,
},
info={
name="MrZ's room",
description="123123123",
type="normal",
version='ver A-7',
},
private=false,
start=false,
count=4,
capacity=5,
}]]
local function _fetchRoom()
fetchTimer=10
NET.fetchRoom()
NET.room_fetch()
end
local scene={}
@@ -61,26 +77,27 @@ function scene.sceneInit()
end
function scene.keyDown(key)
if NET.getlock('enterRoom')then return true end
if TASK.getLock('enterRoom') then return true end
if key=='r' then
if fetchTimer<=7 then
_fetchRoom()
end
elseif roomList:getLen()>0 and (key=='join' or key=='return' and love.keyboard.isDown('lctrl','rctrl')) then
local R=roomList:getSel()
if NET.getlock('fetchRoom')or not R then return end
if R.roomInfo.version==VERSION.room then
NET.enterRoom(R,passwordBox.value)
if R and not TASK.getLock('fetchRoom') then
if R.info.version==VERSION.room then
NET.room_enter(R.roomId,passwordBox.value)
else
MES.new('error',text.versionNotMatch)
end
end
else
return true
end
end
function scene.update(dt)
if not NET.getlock('fetchRoom')and _hidePW()then
if not TASK.getLock('fetchRoom') and _hidePW() then
fetchTimer=fetchTimer-dt
if fetchTimer<=0 then
_fetchRoom()
@@ -93,14 +110,6 @@ function scene.draw()
gc_setColor(1,1,1,.12)
gc_arc('fill','pie',250,630,40,-1.5708,-1.5708-.6283*fetchTimer)
--Joining mark
if NET.getlock('enterRoom')then
gc.setColor(COLOR.Z)
gc.setLineWidth(15)
local t=TIME()*6.26%6.2832
gc.arc('line','open',640,360,80,t,t+4.26)
end
-- Room list
local R=roomList:getSel()
if R then
@@ -109,18 +118,18 @@ function scene.draw()
gc_setLineWidth(3)
gc_rectangle('line',0,0,385,335)
setFont(25)
gc_print(R.roomInfo.type,10,25)
gc_print(R.info.type,10,25)
gc_setColor(1,1,.7)
gc_printf(R.roomInfo.name,10,0,365)
gc_printf(R.info.name,10,0,365)
setFont(20)
gc_setColor(COLOR.lH)
gc_printf(R.roomInfo.description or"[No description]",10,55,365)
gc_printf(R.info.description or "[No description]",10,55,365)
if R.start then
gc_setColor(COLOR.lA)
gc_print(text.started,10,300)
end
gc_setColor(COLOR.lN)
gc_printf(R.roomInfo.version,10,300,365,'right')
gc_printf(R.info.version,10,300,365,'right')
gc_translate(-870,-220)
end
@@ -135,11 +144,11 @@ scene.widgetList={
roomList,
passwordBox,
WIDGET.newKey{name='setting', x=1200,y=160,w=90,h=90,font=60,fText=CHAR.icon.settings,code=goScene'setting_game'},
WIDGET.newText{name='refreshing',x=450,y=240,font=45,hideF=function()return not NET.getlock('fetchRoom')end},
WIDGET.newText{name='noRoom', x=450,y=245,font=40,hideF=function()return roomList:getLen()>0 or NET.getlock('fetchRoom')end},
WIDGET.newText{name='refreshing',x=450,y=240,font=45,hideF=function() return not TASK.getLock('fetchRoom') end},
WIDGET.newText{name='noRoom', x=450,y=245,font=40,hideF=function() return roomList:getLen()>0 or TASK.getLock('fetchRoom') end},
WIDGET.newKey{name='refresh', x=250,y=630,w=140,h=120,code=_fetchRoom,hideF=function() return fetchTimer>7 end},
WIDGET.newKey{name='new', x=510,y=630,w=260,h=120,code=goScene'net_newRoom'},
WIDGET.newKey{name='join', x=780,y=630,w=140,h=120,code=pressKey'join',hideF=function()return roomList:getLen()==0 or NET.getlock('enterRoom')end},
WIDGET.newKey{name='new', x=510,y=630,w=260,h=120,code=goScene('net_newRoom','swipeL')},
WIDGET.newKey{name='join', x=780,y=630,w=140,h=120,code=pressKey'join',hideF=function() return roomList:getLen()==0 or TASK.getLock('enterRoom') end},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=pressKey'escape'},
}

View File

@@ -123,8 +123,8 @@ end
function scene.keyDown(key,isRep)
if isRep then return true end
if key=='q' then
SCN.back()
GAME.playing=false
SCN.back()
elseif key=='escape' then
SCN.swapTo(GAME.result and 'game' or 'depause','none')
elseif key=='s' then

View File

@@ -1,34 +0,0 @@
local scene={}
local function _register()
local username= WIDGET.active.username:getText()
local email= WIDGET.active.email:getText()
local password= WIDGET.active.password:getText()
local password2=WIDGET.active.password2:getText()
if #username==0 then
MES.new('error',text.noUsername)return
elseif not STRING.simpEmailCheck(email)then
MES.new('error',text.wrongEmail)return
elseif #password==0 or #password2==0 then
MES.new('error',text.noPassword)return
elseif password~=password2 then
MES.new('error',text.diffPassword)return
end
NET.register(username,email,password)
end
scene.widgetList={
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
WIDGET.newButton{name='login', x=1140,y=100,w=170,h=80,color='lY',code=function()SCN.swapTo('login','swipeL')end},
WIDGET.newInputBox{name='username', x=380, y=200,w=500,h=60,regex="[0-9A-Za-z_]",limit=64},
WIDGET.newInputBox{name='email', x=380, y=300,w=626,h=60,limit=128},
WIDGET.newInputBox{name='password', x=380, y=400,w=626,h=60,secret=true,regex="[ -~]",limit=64},
WIDGET.newInputBox{name='password2',x=380, y=500,w=626,h=60,secret=true,regex="[ -~]",limit=64},
WIDGET.newKey{name='register', x=640, y=640,w=300,h=80,font=40,code=_register,hideF=function()return NET.getlock('register')end},
WIDGET.newText{name='registering', x=640, y=605,font=50,hideF=function()return not NET.getlock('register')end},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -0,0 +1,44 @@
local scene={}
local function _setPW()
local code=scene.widgetList.code:getText():upper()
local password= scene.widgetList.password:getText()
local password2=scene.widgetList.password2:getText()
if #code~=8 then
MES.new('error',text.wrongCode)
elseif #password==0 or #password2==0 then
MES.new('error',text.noPassword)
elseif password~=password2 then
MES.new('error',text.diffPassword)
else
NET.setPW(code,password)
end
end
function scene.keyDown(key,rep)
if key=='escape' and not rep then
SCN.back()
elseif key=='return' then
if #scene.widgetList.code:getText()==0 then
_setPW()
else
NET.getCode(USER.email)
end
else
return true
end
end
scene.widgetList={
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
WIDGET.newKey{name='send', x=640, y=300,w=300,h=80,font=40,code=function() NET.getCode(USER.email) end},
WIDGET.newInputBox{name='code', x=380, y=170,w=626,h=60,limit=8},
WIDGET.newInputBox{name='password', x=380, y=370,w=626,h=60,secret=true,regex="[ -~]",limit=64},
WIDGET.newInputBox{name='password2',x=380, y=470,w=626,h=60,secret=true,regex="[ -~]",limit=64},
WIDGET.newKey{name='setPW', x=640, y=600,w=350,h=80,font=40,code=_setPW},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=pressKey'escape'},
}
return scene

View File

@@ -48,7 +48,6 @@ scene.widgetList={
WIDGET.newSwitch{name='sysCursor',x=1060, y=400, lim=580, disp=SETval('sysCursor'),code=function() SETTING.sysCursor=not SETTING.sysCursor applySettings() end},
WIDGET.newSwitch{name='autoPause',x=1060, y=470, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
WIDGET.newSwitch{name='autoSave', x=1060, y=540, lim=580, disp=SETval('autoSave'), code=SETrev('autoSave')},
WIDGET.newSwitch{name='autoLogin',x=960, y=610, lim=480, disp=SETval('autoLogin'),code=SETrev('autoLogin')},
WIDGET.newSwitch{name='simpMode', x=960, y=670, lim=480, disp=SETval('simpMode'),
code=function()
SETTING.simpMode=not SETTING.simpMode

View File

@@ -12,8 +12,8 @@ function scene.sceneInit()
last1,last2=0,0
sfxPack=SETTING.sfxPack
vocPack=SETTING.vocPack
WIDGET.active.sfxPack:reset()
WIDGET.active.vocPack:reset()
scene.widgetList.sfxPack:reset()
scene.widgetList.vocPack:reset()
BG.set()
end
function scene.sceneBack()

View File

@@ -115,9 +115,9 @@ scene.widgetList={
WIDGET.newButton{name='path',x=820,y=540,w=250,h=80,font=25,
code=function()
if SYSTEM=="Windows" or SYSTEM=="Linux" then
love.system.openURL(SAVEDIR)
love.system.openURL(love.filesystem.getSaveDirectory())
else
MES.new('info',SAVEDIR)
MES.new('info',love.filesystem.getSaveDirectory())
end
end
},

View File

@@ -52,25 +52,37 @@ end})
local USERS={}
--[[userdata={
username="MrZ",
motto="Techmino 好玩",
id=26,
permission="Admin",
region=0,
avatar_hash=XXX,
avatar_frame=0,
}]]
function USERS.updateUserData(data)
local uid=data.uid
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"..uid..".dat",JSON.encode{
username=data.username,
motto=data.motto,
hash=data.hash or db[uid].hash,
hash=db[uid].hash,
})
if data.avatar then
fs.write("cache/"..data.hash,love.data.decode('string','base64',data.avatar:sub(data.avatar:find(",")+1)))
db_img[uid]=_loadAvatar("cache/"..data.hash)
db[uid].hash=type(data.hash)=='string'and #data.hash>0 and data.hash
end
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[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.getUsername(uid) return db[uid].username or "" end
function USERS.getMotto(uid) return db[uid].motto or "" end
function USERS.getAvatar(uid)
if uid then
if not db[uid].new then