添加discordRPC支持
This commit is contained in:
BIN
.github/build/extraLibs/Windows_x64/discord-rpc.dll
vendored
Normal file
BIN
.github/build/extraLibs/Windows_x64/discord-rpc.dll
vendored
Normal file
Binary file not shown.
BIN
.github/build/extraLibs/Windows_x86/discord-rpc.dll
vendored
Normal file
BIN
.github/build/extraLibs/Windows_x86/discord-rpc.dll
vendored
Normal file
Binary file not shown.
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@@ -495,8 +495,8 @@ jobs:
|
||||
icon-path: ./.github/build/windows/${{ env.BUILD_TYPE }}/icon.ico
|
||||
rc-path: ./.github/build/windows/${{ env.BUILD_TYPE }}/template.rc
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
extra-assets-x86: ./ColdClear/x86/CCloader.dll ./ColdClear/x86/cold_clear.dll
|
||||
extra-assets-x64: ./ColdClear/x64/CCloader.dll ./ColdClear/x64/cold_clear.dll
|
||||
extra-assets-x86: ./ColdClear/x86/CCloader.dll ./ColdClear/x86/cold_clear.dll ./.github/build/extraLibs/Windows_x64/discord-rpc.dll
|
||||
extra-assets-x64: ./ColdClear/x64/CCloader.dll ./ColdClear/x64/cold_clear.dll ./.github/build/extraLibs/Windows_x86/discord-rpc.dll
|
||||
product-name: ${{ steps.process-app-name.outputs.product-name }}
|
||||
app-id: ${{ secrets.WINDOWS_APP_ID }}
|
||||
project-website: https://www.studio26f.org/
|
||||
|
||||
4
main.lua
4
main.lua
@@ -597,6 +597,10 @@ WS.switchHost('www.studio26f.org','8081','/techmino/ws/v1')
|
||||
HTTP.setHost("www.studio26f.org:8081")
|
||||
HTTP.setThreadCount(1)
|
||||
|
||||
-- Discord RPC
|
||||
DiscordRPC=require'parts.discordRPC'
|
||||
DiscordRPC.update()
|
||||
|
||||
table.insert(_LOADTIMELIST_,("Load Resources: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i]) end
|
||||
|
||||
410
parts/discordRPC.lua
Normal file
410
parts/discordRPC.lua
Normal file
@@ -0,0 +1,410 @@
|
||||
local ffi=require"ffi"
|
||||
|
||||
|
||||
-- Get the host os to load correct lib
|
||||
local osname=love.system.getOS()
|
||||
local discordRPClib=nil
|
||||
|
||||
-- FFI requires the libraries really be files just sitting in the filesystem. It
|
||||
-- can't load libraries from a .love archive, nor a fused executable on Windows.
|
||||
-- Merely using love.filesystem.getSource() only works when running LOVE with
|
||||
-- the game unarchived from command line, like "love .".
|
||||
--
|
||||
-- The code here setting "source" will set the directory where the game was run
|
||||
-- from, so FFI can load discordRPC. We assume that the discordRPC library's
|
||||
-- libs directory is in the same directory as the .love archive; if it's
|
||||
-- missing, it just won't load.
|
||||
local source=love.filesystem.getSource()
|
||||
if string.sub(source, -5)==".love" or love.filesystem.isFused() then
|
||||
source=love.filesystem.getSourceBaseDirectory()
|
||||
end
|
||||
|
||||
if osname=="Linux" then
|
||||
discordRPClib=ffi.load(source.."/libs/discord-rpc.so")
|
||||
elseif osname=="OS X" then
|
||||
discordRPClib=ffi.load(source.."/libs/discord-rpc.dylib")
|
||||
elseif osname=="Windows" then
|
||||
-- I would strongly advise never touching this. It was not trivial to get correct. -nightmareci
|
||||
|
||||
ffi.cdef[[
|
||||
typedef uint32_t DWORD;
|
||||
typedef char CHAR;
|
||||
typedef CHAR *LPSTR;
|
||||
typedef const CHAR *LPCSTR;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef WCHAR *LPWSTR;
|
||||
typedef LPWSTR PWSTR;
|
||||
typedef const WCHAR *LPCWSTR;
|
||||
|
||||
static const DWORD CP_UTF8 = 65001;
|
||||
int32_t MultiByteToWideChar(
|
||||
DWORD CodePage,
|
||||
DWORD dwFlags,
|
||||
LPCSTR lpMultiByteStr,
|
||||
int32_t cbMultiByte,
|
||||
LPWSTR lpWideCharStr,
|
||||
int32_t cchWideChar
|
||||
);
|
||||
|
||||
int32_t WideCharToMultiByte(
|
||||
DWORD CodePage,
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpWideCharStr,
|
||||
int32_t cchWideChar,
|
||||
LPSTR lpMultiByteStr,
|
||||
int32_t cbMultiByte,
|
||||
void* lpDefaultChar,
|
||||
void* lpUsedDefaultChar
|
||||
);
|
||||
|
||||
DWORD GetShortPathNameW(
|
||||
LPCWSTR lpszLongPath,
|
||||
LPWSTR lpszShortPath,
|
||||
DWORD cchBuffer
|
||||
);
|
||||
]]
|
||||
|
||||
local originalWideSize=ffi.C.MultiByteToWideChar(ffi.C.CP_UTF8, 0, source, -1, nil, 0)
|
||||
local originalWide=ffi.new('WCHAR[?]', originalWideSize)
|
||||
ffi.C.MultiByteToWideChar(ffi.C.CP_UTF8, 0, source, -1, originalWide, originalWideSize)
|
||||
|
||||
local sourceSize=ffi.C.GetShortPathNameW(originalWide, nil, 0)
|
||||
local sourceWide=ffi.new('WCHAR[?]', sourceSize)
|
||||
ffi.C.GetShortPathNameW(originalWide, sourceWide, sourceSize)
|
||||
|
||||
local sourceChar=ffi.new('char[?]', sourceSize)
|
||||
ffi.C.WideCharToMultiByte(ffi.C.CP_UTF8, 0, sourceWide, sourceSize, sourceChar, sourceSize, nil, nil)
|
||||
|
||||
discordRPClib=ffi.load("discord-rpc.dll")
|
||||
-- source = ffi.string(sourceChar)
|
||||
-- if jit.arch == "x86" then
|
||||
-- discordRPClib = ffi.load(source.."/libs/discord-rpc_x86.dll")
|
||||
-- elseif jit.arch == "x64" then
|
||||
-- discordRPClib = ffi.load(source.."/libs/discord-rpc_x64.dll")
|
||||
-- end
|
||||
else
|
||||
-- Else it crashes later on
|
||||
error(string.format("Discord rpc not supported on platform (%s)", osname))
|
||||
end
|
||||
|
||||
|
||||
ffi.cdef[[
|
||||
typedef struct DiscordRichPresence {
|
||||
const char* state; /* max 128 bytes */
|
||||
const char* details; /* max 128 bytes */
|
||||
int64_t startTimestamp;
|
||||
int64_t endTimestamp;
|
||||
const char* largeImageKey; /* max 32 bytes */
|
||||
const char* largeImageText; /* max 128 bytes */
|
||||
const char* smallImageKey; /* max 32 bytes */
|
||||
const char* smallImageText; /* max 128 bytes */
|
||||
const char* partyId; /* max 128 bytes */
|
||||
int partySize;
|
||||
int partyMax;
|
||||
const char* matchSecret; /* max 128 bytes */
|
||||
const char* joinSecret; /* max 128 bytes */
|
||||
const char* spectateSecret; /* max 128 bytes */
|
||||
int8_t instance;
|
||||
} DiscordRichPresence;
|
||||
|
||||
typedef struct DiscordUser {
|
||||
const char* userId;
|
||||
const char* username;
|
||||
const char* discriminator;
|
||||
const char* avatar;
|
||||
} DiscordUser;
|
||||
|
||||
typedef void (*readyPtr)(const DiscordUser* request);
|
||||
typedef void (*disconnectedPtr)(int errorCode, const char* message);
|
||||
typedef void (*erroredPtr)(int errorCode, const char* message);
|
||||
typedef void (*joinGamePtr)(const char* joinSecret);
|
||||
typedef void (*spectateGamePtr)(const char* spectateSecret);
|
||||
typedef void (*joinRequestPtr)(const DiscordUser* request);
|
||||
|
||||
typedef struct DiscordEventHandlers {
|
||||
readyPtr ready;
|
||||
disconnectedPtr disconnected;
|
||||
erroredPtr errored;
|
||||
joinGamePtr joinGame;
|
||||
spectateGamePtr spectateGame;
|
||||
joinRequestPtr joinRequest;
|
||||
} DiscordEventHandlers;
|
||||
|
||||
void Discord_Initialize(const char* applicationId,
|
||||
DiscordEventHandlers* handlers,
|
||||
int autoRegister,
|
||||
const char* optionalSteamId);
|
||||
|
||||
void Discord_Shutdown(void);
|
||||
|
||||
void Discord_RunCallbacks(void);
|
||||
|
||||
void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||
|
||||
void Discord_ClearPresence(void);
|
||||
|
||||
void Discord_Respond(const char* userid, int reply);
|
||||
|
||||
void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
|
||||
]]
|
||||
|
||||
local RPC={} -- module table
|
||||
|
||||
-- proxy to detect garbage collection of the module
|
||||
RPC.gcDummy=newproxy(true)
|
||||
|
||||
local function unpackDiscordUser(request)
|
||||
return ffi.string(request.userId),ffi.string(request.username),
|
||||
ffi.string(request.discriminator),ffi.string(request.avatar)
|
||||
end
|
||||
|
||||
-- callback proxies
|
||||
-- note: callbacks are not JIT compiled (= SLOW), try to avoid doing performance critical tasks in them
|
||||
-- luajit.org/ext_ffi_semantics.html
|
||||
local ready_proxy=ffi.cast("readyPtr", function(request)
|
||||
if RPC.ready then
|
||||
RPC.ready(unpackDiscordUser(request))
|
||||
end
|
||||
end)
|
||||
|
||||
local disconnected_proxy=ffi.cast("disconnectedPtr", function(errorCode,message)
|
||||
if RPC.disconnected then
|
||||
RPC.disconnected(errorCode, ffi.string(message))
|
||||
end
|
||||
end)
|
||||
|
||||
local errored_proxy=ffi.cast("erroredPtr", function(errorCode,message)
|
||||
if RPC.errored then
|
||||
RPC.errored(errorCode, ffi.string(message))
|
||||
end
|
||||
end)
|
||||
|
||||
local joinGame_proxy=ffi.cast("joinGamePtr", function(joinSecret)
|
||||
if RPC.joinGame then
|
||||
RPC.joinGame(ffi.string(joinSecret))
|
||||
end
|
||||
end)
|
||||
|
||||
local spectateGame_proxy=ffi.cast("spectateGamePtr", function(spectateSecret)
|
||||
if RPC.spectateGame then
|
||||
RPC.spectateGame(ffi.string(spectateSecret))
|
||||
end
|
||||
end)
|
||||
|
||||
local joinRequest_proxy=ffi.cast("joinRequestPtr", function(request)
|
||||
if RPC.joinRequest then
|
||||
RPC.joinRequest(unpackDiscordUser(request))
|
||||
end
|
||||
end)
|
||||
|
||||
-- helpers
|
||||
local function checkArg(arg,argType,argName,func,maybeNil)
|
||||
assert(type(arg)==argType or (maybeNil and arg==nil),
|
||||
string.format("Argument \"%s\" to function \"%s\" has to be of type \"%s\"",
|
||||
argName, func, argType))
|
||||
end
|
||||
|
||||
local function checkStrArg(arg,maxLen,argName,func,maybeNil)
|
||||
if maxLen then
|
||||
assert(type(arg)=="string" and arg:len()<=maxLen or (maybeNil and arg==nil),
|
||||
string.format("Argument \"%s\" of function \"%s\" has to be of type string with maximum length %d",
|
||||
argName, func, maxLen))
|
||||
else
|
||||
checkArg(arg, "string", argName, func, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function checkIntArg(arg,maxBits,argName,func,maybeNil)
|
||||
maxBits=math.min(maxBits or 32, 52) -- lua number (double) can only store integers < 2^53
|
||||
local maxVal=2^(maxBits-1) -- assuming signed integers, which, for now, are the only ones in use
|
||||
assert(type(arg)=="number" and math.floor(arg)==arg
|
||||
and arg<maxVal and arg>=-maxVal
|
||||
or (maybeNil and arg==nil),
|
||||
string.format("Argument \"%s\" of function \"%s\" has to be a whole number <= %d",
|
||||
argName, func, maxVal))
|
||||
end
|
||||
|
||||
-- function wrappers
|
||||
function RPC.initialize(applicationId,autoRegister,optionalSteamId)
|
||||
local func="discordRPC.Initialize"
|
||||
checkStrArg(applicationId, nil, "applicationId", func)
|
||||
checkArg(autoRegister, "boolean", "autoRegister", func)
|
||||
if optionalSteamId~=nil then
|
||||
checkStrArg(optionalSteamId, nil, "optionalSteamId", func)
|
||||
end
|
||||
|
||||
local eventHandlers=ffi.new("struct DiscordEventHandlers")
|
||||
eventHandlers.ready=ready_proxy
|
||||
eventHandlers.disconnected=disconnected_proxy
|
||||
eventHandlers.errored=errored_proxy
|
||||
eventHandlers.joinGame=joinGame_proxy
|
||||
eventHandlers.spectateGame=spectateGame_proxy
|
||||
eventHandlers.joinRequest=joinRequest_proxy
|
||||
|
||||
discordRPClib.Discord_Initialize(applicationId, eventHandlers,
|
||||
autoRegister and 1 or 0, optionalSteamId)
|
||||
end
|
||||
|
||||
function RPC.shutdown()
|
||||
discordRPClib.Discord_Shutdown()
|
||||
end
|
||||
|
||||
function RPC.runCallbacks()
|
||||
discordRPClib.Discord_RunCallbacks()
|
||||
end
|
||||
-- http://luajit.org/ext_ffi_semantics.html#callback :
|
||||
-- It is not allowed, to let an FFI call into a C function (runCallbacks)
|
||||
-- get JIT-compiled, which in turn calls a callback, calling into Lua again (e.g. discordRPC.ready).
|
||||
-- Usually this attempt is caught by the interpreter first and the C function
|
||||
-- is blacklisted for compilation.
|
||||
-- solution:
|
||||
-- "Then you'll need to manually turn off JIT-compilation with jit.off() for
|
||||
-- the surrounding Lua function that invokes such a message polling function."
|
||||
jit.off(RPC.runCallbacks)
|
||||
|
||||
function RPC.updatePresence(presence)
|
||||
local func="discordRPC.updatePresence"
|
||||
checkArg(presence, "table", "presence", func)
|
||||
|
||||
-- -1 for string length because of 0-termination
|
||||
checkStrArg(presence.state, 127, "presence.state", func, true)
|
||||
checkStrArg(presence.details, 127, "presence.details", func, true)
|
||||
|
||||
checkIntArg(presence.startTimestamp, 64, "presence.startTimestamp", func, true)
|
||||
checkIntArg(presence.endTimestamp, 64, "presence.endTimestamp", func, true)
|
||||
|
||||
checkStrArg(presence.largeImageKey, 31, "presence.largeImageKey", func, true)
|
||||
checkStrArg(presence.largeImageText, 127, "presence.largeImageText", func, true)
|
||||
checkStrArg(presence.smallImageKey, 31, "presence.smallImageKey", func, true)
|
||||
checkStrArg(presence.smallImageText, 127, "presence.smallImageText", func, true)
|
||||
checkStrArg(presence.partyId, 127, "presence.partyId", func, true)
|
||||
|
||||
checkIntArg(presence.partySize, 32, "presence.partySize", func, true)
|
||||
checkIntArg(presence.partyMax, 32, "presence.partyMax", func, true)
|
||||
|
||||
checkStrArg(presence.matchSecret, 127, "presence.matchSecret", func, true)
|
||||
checkStrArg(presence.joinSecret, 127, "presence.joinSecret", func, true)
|
||||
checkStrArg(presence.spectateSecret, 127, "presence.spectateSecret", func, true)
|
||||
|
||||
checkIntArg(presence.instance, 8, "presence.instance", func, true)
|
||||
|
||||
local cpresence=ffi.new("struct DiscordRichPresence")
|
||||
cpresence.state=presence.state
|
||||
cpresence.details=presence.details
|
||||
cpresence.startTimestamp=presence.startTimestamp or 0
|
||||
cpresence.endTimestamp=presence.endTimestamp or 0
|
||||
cpresence.largeImageKey=presence.largeImageKey
|
||||
cpresence.largeImageText=presence.largeImageText
|
||||
cpresence.smallImageKey=presence.smallImageKey
|
||||
cpresence.smallImageText=presence.smallImageText
|
||||
cpresence.partyId=presence.partyId
|
||||
cpresence.partySize=presence.partySize or 0
|
||||
cpresence.partyMax=presence.partyMax or 0
|
||||
cpresence.matchSecret=presence.matchSecret
|
||||
cpresence.joinSecret=presence.joinSecret
|
||||
cpresence.spectateSecret=presence.spectateSecret
|
||||
cpresence.instance=presence.instance or 0
|
||||
|
||||
discordRPClib.Discord_UpdatePresence(cpresence)
|
||||
end
|
||||
|
||||
function RPC.clearPresence()
|
||||
discordRPClib.Discord_ClearPresence()
|
||||
end
|
||||
|
||||
local replyMap={
|
||||
no=0,
|
||||
yes=1,
|
||||
ignore=2,
|
||||
}
|
||||
|
||||
-- maybe let reply take ints too (0, 1, 2) and add constants to the module
|
||||
function RPC.respond(userId,reply)
|
||||
checkStrArg(userId, nil, "userId", "discordRPC.respond")
|
||||
assert(replyMap[reply], "Argument 'reply' to discordRPC.respond has to be one of \"yes\", \"no\" or \"ignore\"")
|
||||
discordRPClib.Discord_Respond(userId, replyMap[reply])
|
||||
end
|
||||
|
||||
-- garbage collection callback
|
||||
getmetatable(RPC.gcDummy).__gc=function()
|
||||
RPC.shutdown()
|
||||
ready_proxy:free()
|
||||
disconnected_proxy:free()
|
||||
errored_proxy:free()
|
||||
joinGame_proxy:free()
|
||||
spectateGame_proxy:free()
|
||||
joinRequest_proxy:free()
|
||||
end
|
||||
|
||||
local MyRPC={
|
||||
appId='1288557386700951554',
|
||||
RPC=RPC,
|
||||
presence={
|
||||
startTimestamp=os.time(),
|
||||
state="Loading...",
|
||||
details="",
|
||||
largeImageKey='',
|
||||
largeImageText="Techmino",
|
||||
smallImageKey='',
|
||||
smallImageText="",
|
||||
},
|
||||
}
|
||||
if RPC then
|
||||
function RPC.ready(userId,username,discriminator,avatar)
|
||||
print(string.format("Discord: ready (%s,%s,%s,%s)",userId,username,discriminator,avatar))
|
||||
end
|
||||
|
||||
function RPC.disconnected(errorCode,message)
|
||||
print(string.format("Discord: disconnected (%d: %s)",errorCode,message))
|
||||
end
|
||||
|
||||
function RPC.errored(errorCode,message)
|
||||
print(string.format("Discord: error (%d: %s)",errorCode,message))
|
||||
end
|
||||
|
||||
function RPC.joinGame(joinSecret)
|
||||
print(string.format("Discord: join (%s)",joinSecret))
|
||||
end
|
||||
|
||||
function RPC.spectateGame(spectateSecret)
|
||||
print(string.format("Discord: spectate (%s)",spectateSecret))
|
||||
end
|
||||
|
||||
function RPC.joinRequest(userId,username,discriminator,avatar)
|
||||
print(string.format("Discord: join request (%s,%s,%s,%s)",userId,username,discriminator,avatar))
|
||||
RPC.respond(userId,'yes')
|
||||
end
|
||||
|
||||
RPC.initialize(MyRPC.appId,true)
|
||||
else
|
||||
print("DiscordRPC loading error")
|
||||
print(RPC)
|
||||
end
|
||||
|
||||
---@class DiscordRPC.presence
|
||||
---@field startTimestamp? number
|
||||
---@field details? string
|
||||
---@field state? string
|
||||
---@field largeImageKey? string
|
||||
---@field largeImageText? string
|
||||
---@field smallImageKey? string
|
||||
---@field smallImageText? string
|
||||
|
||||
---@param state string
|
||||
---@param details string
|
||||
---@overload fun(new: DiscordRPC.presence)
|
||||
---@overload fun()
|
||||
function MyRPC.update(state,details)
|
||||
if state then
|
||||
for k,v in next,
|
||||
type(state)=='string'
|
||||
and {state=state,details=details}
|
||||
or state
|
||||
do
|
||||
MyRPC.presence[k]=v
|
||||
end
|
||||
end
|
||||
if RPC then RPC.updatePresence(MyRPC.presence) end
|
||||
end
|
||||
|
||||
return MyRPC
|
||||
@@ -29,6 +29,7 @@ function scene.enter()
|
||||
slide=true
|
||||
pathVis=true
|
||||
revKB=false
|
||||
DiscordRPC.update("Playing 15-Puzzle")
|
||||
end
|
||||
|
||||
local function moveU(x,y)
|
||||
|
||||
@@ -234,6 +234,7 @@ function scene.enter()
|
||||
tapControl=false
|
||||
startTime=0
|
||||
reset()
|
||||
DiscordRPC.update("Playing 2048")
|
||||
end
|
||||
|
||||
function scene.mouseDown(x,y,k)
|
||||
|
||||
@@ -40,6 +40,7 @@ function scene.enter()
|
||||
startTime=0
|
||||
time=0
|
||||
state=0
|
||||
DiscordRPC.update("Spamming keyboard")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -100,6 +100,7 @@ function scene.enter()
|
||||
restart()
|
||||
BGM.play('truth')
|
||||
BG.set('rainbow')
|
||||
DiscordRPC.update("Playing Ultimate Tic-Tac-Toe")
|
||||
end
|
||||
|
||||
function scene.mouseMove(x,y)
|
||||
|
||||
@@ -360,6 +360,7 @@ function scene.enter()
|
||||
drawing=false
|
||||
numScale=1
|
||||
BGM.play('truth')
|
||||
DiscordRPC.update("Playing Arithmetic")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -28,6 +28,7 @@ function scene.enter()
|
||||
BG.set('none')
|
||||
BGM.stop()
|
||||
reg,val,sym=false,"0",false
|
||||
DiscordRPC.update("Calculating something")
|
||||
end
|
||||
function scene.leave()
|
||||
BGM.play()
|
||||
|
||||
@@ -15,6 +15,7 @@ function scene.enter()
|
||||
ex,ey=626,260
|
||||
BG.set('matrix')
|
||||
BGM.play('hang out')
|
||||
DiscordRPC.update("Shooting cannon balls")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -1034,6 +1034,7 @@ userG.the_key=first_key
|
||||
function scene.enter()
|
||||
WIDGET.focus(inputBox)
|
||||
BG.set('none')
|
||||
DiscordRPC.update("Hacking the system")
|
||||
end
|
||||
|
||||
function scene.wheelMoved(_,y)
|
||||
|
||||
@@ -59,6 +59,7 @@ function scene.enter()
|
||||
gc.setLineJoin('bevel')
|
||||
BGM.play('push')
|
||||
BG.set('none')
|
||||
DiscordRPC.update("Playing Cubefield")
|
||||
end
|
||||
|
||||
function scene.touchDown(x)
|
||||
|
||||
@@ -38,6 +38,7 @@ function scene.enter()
|
||||
state='menu'
|
||||
BGM.play('hang out')
|
||||
BG.set('space')
|
||||
DiscordRPC.update("Playing Dropper")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -201,6 +201,7 @@ function scene.enter()
|
||||
reset()
|
||||
BG.set('fixColor',.26,.26,.26)
|
||||
BGM.play(bgm)
|
||||
DiscordRPC.update("Avoiding touching white tiles")
|
||||
end
|
||||
|
||||
local function touch(n)
|
||||
|
||||
@@ -249,6 +249,7 @@ function scene.enter()
|
||||
invis=false
|
||||
newGame()
|
||||
BGM.play('truth')
|
||||
DiscordRPC.update("Playing Link")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -109,6 +109,7 @@ function scene.enter()
|
||||
BG.set('fixColor',.26,.62,.26)
|
||||
_newGame()
|
||||
selected=false
|
||||
DiscordRPC.update("Playing Mahjong")
|
||||
end
|
||||
|
||||
function scene.mouseMove(x,y)
|
||||
|
||||
@@ -36,6 +36,7 @@ function scene.enter()
|
||||
input=''
|
||||
showNum='memoriZe'
|
||||
BGM.play('reason')
|
||||
DiscordRPC.update("Playing memoriZe")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -95,6 +95,7 @@ function scene.enter()
|
||||
generateVKey()
|
||||
_notHoldCS()
|
||||
_showVirtualKey(MOBILE)
|
||||
DiscordRPC.update("Playing music")
|
||||
end
|
||||
|
||||
function scene.leave()
|
||||
|
||||
@@ -40,6 +40,7 @@ function scene.enter()
|
||||
end
|
||||
BG.set('none')
|
||||
BGM.play('dream')
|
||||
DiscordRPC.update("Playing polyforge")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -35,6 +35,7 @@ function scene.enter()
|
||||
vy=0,
|
||||
y0=false,
|
||||
}
|
||||
DiscordRPC.update("Playing Pong")
|
||||
end
|
||||
|
||||
local function start()
|
||||
|
||||
@@ -18,6 +18,7 @@ end
|
||||
function scene.enter()
|
||||
reset()
|
||||
BG.set('none')
|
||||
DiscordRPC.update("Playing Reflect")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -25,6 +25,7 @@ function scene.enter()
|
||||
mistake=0
|
||||
state=0
|
||||
progress=0
|
||||
DiscordRPC.update("Playing Schulte Grid")
|
||||
end
|
||||
|
||||
local function newBoard()
|
||||
|
||||
@@ -15,6 +15,10 @@ end)
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
DiscordRPC.update("Playing a non-sense thing")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
if isRep then return end
|
||||
if key=='space' or key=='return' then
|
||||
|
||||
@@ -27,6 +27,7 @@ function scene.enter()
|
||||
state=0
|
||||
time1=STRING.time(0)
|
||||
time2=STRING.time(0)
|
||||
DiscordRPC.update("Timing something")
|
||||
end
|
||||
|
||||
function scene.mouseDown()
|
||||
|
||||
@@ -14,6 +14,7 @@ function scene.enter()
|
||||
keyTime={} for i=1,40 do keyTime[i]=-1e99 end
|
||||
BG.set('fixColor',.26,.26,.26)
|
||||
BGM.play('push')
|
||||
DiscordRPC.update("Spamming keyboard")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,isRep)
|
||||
|
||||
@@ -64,6 +64,7 @@ function scene.enter()
|
||||
invis=false
|
||||
nexts=true
|
||||
reset()
|
||||
DiscordRPC.update("Playing Get the Ten")
|
||||
end
|
||||
|
||||
local function merge()
|
||||
|
||||
@@ -267,6 +267,7 @@ local scene={}
|
||||
function scene.enter()
|
||||
player:reset()
|
||||
BGM.play('truth')
|
||||
DiscordRPC.update("Playing Triple Town")
|
||||
end
|
||||
|
||||
function scene.mouseClick(x,y)
|
||||
|
||||
@@ -163,6 +163,7 @@ function scene.enter()
|
||||
|
||||
if not MOBILE then WIDGET.focus(inputBox) end
|
||||
BG.set('rainbow')
|
||||
DiscordRPC.update("Learning Zictionary")
|
||||
end
|
||||
|
||||
function scene.wheelMoved(_,y)
|
||||
|
||||
@@ -13,6 +13,7 @@ function scene.enter()
|
||||
if SETTING then
|
||||
SFX.fplay('error',SETTING.voc*.8 or 0)
|
||||
end
|
||||
DiscordRPC.update("Struke by an error")
|
||||
end
|
||||
|
||||
function scene.draw()
|
||||
|
||||
@@ -222,6 +222,8 @@ function scene.enter()
|
||||
_updateStepButton()
|
||||
_updateRepButtons()
|
||||
_updateMenuButtons()
|
||||
|
||||
DiscordRPC.update("Playing "..GAME.curMode.name)
|
||||
end
|
||||
|
||||
scene.mouseDown=NULL
|
||||
|
||||
@@ -21,6 +21,9 @@ local curLang=1
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
DiscordRPC.update("Setting language")
|
||||
end
|
||||
function scene.leave()
|
||||
saveSettings()
|
||||
end
|
||||
|
||||
@@ -168,6 +168,10 @@ local function press(x,y)
|
||||
end
|
||||
end
|
||||
|
||||
function scene.enter()
|
||||
DiscordRPC.update("Playing Launchpad")
|
||||
end
|
||||
|
||||
function scene.touchDown(x,y)
|
||||
x,y=floor((x-pad.x)/80),floor((y-pad.y)/80)
|
||||
if x>=0 and x<=8 and y>=0 and y<=7 then
|
||||
|
||||
@@ -44,6 +44,8 @@ function scene.enter()
|
||||
GAME.setting={}
|
||||
PLY.newDemoPlayer(1)
|
||||
PLAYERS[1]:setPosition(520,140,.8)
|
||||
|
||||
DiscordRPC.update("In Main Menu")
|
||||
end
|
||||
|
||||
function scene.resize()
|
||||
|
||||
@@ -5,6 +5,7 @@ local tip=GC.newText(getFont(30),"")
|
||||
function scene.enter()
|
||||
tip:set(text.getTip())
|
||||
BG.set()
|
||||
DiscordRPC.update("In Simple Menu")
|
||||
end
|
||||
|
||||
function scene.draw()
|
||||
|
||||
@@ -44,6 +44,7 @@ function scene.enter()
|
||||
end
|
||||
end
|
||||
modUsed=usingMod()
|
||||
DiscordRPC.update("Picking mode")
|
||||
end
|
||||
|
||||
local function _getK()
|
||||
|
||||
@@ -26,6 +26,7 @@ if #bgmList==0 then bgmList={"[NO BGM]"} end
|
||||
function scene.enter()
|
||||
playing=BGM.getPlaying()[1]
|
||||
selected=TABLE.find(bgmList,playing) or 1
|
||||
DiscordRPC.update("Elevating the soul through music")
|
||||
end
|
||||
|
||||
function scene.wheelMoved(_,y)
|
||||
|
||||
@@ -5,6 +5,7 @@ local scene={}
|
||||
function scene.enter()
|
||||
BG.set('galaxy')
|
||||
BGM.play('exploration')
|
||||
DiscordRPC.update("Dreaming Techmino Galaxy coming out")
|
||||
end
|
||||
|
||||
function scene.draw()
|
||||
|
||||
@@ -72,6 +72,7 @@ function scene.enter()
|
||||
BG.set(GAME.prevBG)
|
||||
GAME.prevBG=false
|
||||
end
|
||||
DiscordRPC.update("Playing Multiplayer")
|
||||
end
|
||||
function scene.leave()
|
||||
TASK.unlock('netPlaying')
|
||||
|
||||
@@ -2,6 +2,7 @@ local scene={}
|
||||
|
||||
function scene.enter()
|
||||
BG.set()
|
||||
DiscordRPC.update("Ready to Click \"Rooms\"")
|
||||
end
|
||||
function scene.leave()
|
||||
NET.ws_close()
|
||||
|
||||
@@ -53,6 +53,7 @@ end
|
||||
function scene.enter()
|
||||
sure=0
|
||||
destroyPlayers()
|
||||
DiscordRPC.update("Creating new room...")
|
||||
end
|
||||
function scene.leave()
|
||||
BGM.play()
|
||||
|
||||
@@ -74,6 +74,7 @@ local scene={}
|
||||
function scene.enter()
|
||||
BG.set()
|
||||
_fetchRoom()
|
||||
DiscordRPC.update("Checking room list")
|
||||
end
|
||||
|
||||
function scene.keyDown(key)
|
||||
|
||||
@@ -15,6 +15,7 @@ function scene.enter()
|
||||
else
|
||||
scene.widgetList.texts:setTexts({"No data"})
|
||||
end
|
||||
DiscordRPC.update("Checking Latest News")
|
||||
end
|
||||
|
||||
function scene.wheelMoved(_,y)
|
||||
|
||||
@@ -77,6 +77,7 @@ function scene.enter()
|
||||
BG.set()
|
||||
listBox:setList(REPLAY)
|
||||
_updateButtonVisibility()
|
||||
DiscordRPC.update("Finding replay")
|
||||
end
|
||||
function scene.leave()
|
||||
if #mods>0 then
|
||||
|
||||
@@ -9,6 +9,7 @@ function scene.enter()
|
||||
das,arr=SETTING.das,SETTING.arr
|
||||
pos,dir,wait=0,1,30
|
||||
BG.set('bg1')
|
||||
DiscordRPC.update("Tweaking control settings")
|
||||
end
|
||||
|
||||
local trigFrame=0
|
||||
|
||||
@@ -4,6 +4,7 @@ local scene={}
|
||||
|
||||
function scene.enter()
|
||||
BG.set()
|
||||
DiscordRPC.update("Tweaking Settings")
|
||||
end
|
||||
function scene.leave()
|
||||
saveSettings()
|
||||
|
||||
@@ -102,6 +102,7 @@ function scene.enter()
|
||||
selected=false
|
||||
_freshKeyList()
|
||||
BG.set('none')
|
||||
DiscordRPC.update("Binding keys")
|
||||
end
|
||||
function scene.leave()
|
||||
saveFile(KEY_MAP,'conf/key')
|
||||
|
||||
@@ -15,6 +15,7 @@ function scene.enter()
|
||||
scene.widgetList.sfxPack:reset()
|
||||
scene.widgetList.vocPack:reset()
|
||||
BG.set()
|
||||
DiscordRPC.update("Tweaking Settings")
|
||||
end
|
||||
function scene.leave()
|
||||
saveSettings()
|
||||
|
||||
@@ -2,6 +2,9 @@ local gc=love.graphics
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
DiscordRPC.update("Tweaking Settings")
|
||||
end
|
||||
function scene.leave()
|
||||
saveSettings()
|
||||
end
|
||||
|
||||
@@ -17,6 +17,7 @@ function scene.enter()
|
||||
BG.set()
|
||||
names={}
|
||||
counter=26
|
||||
DiscordRPC.update("Knowing Staffs")
|
||||
end
|
||||
|
||||
function scene.mouseDown(x,y)
|
||||
|
||||
@@ -37,6 +37,7 @@ function scene.enter()
|
||||
for i=1,11 do
|
||||
item[i]=text.stat[i].."\t"..item[i]
|
||||
end
|
||||
DiscordRPC.update("Admiring Oneself")
|
||||
end
|
||||
|
||||
function scene.mouseDown(x,y)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
DiscordRPC.update("Sponsoring a Great Cause")
|
||||
end
|
||||
|
||||
function scene.draw()
|
||||
-- QR Code frame
|
||||
GC.setLineWidth(2)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
新增:
|
||||
新的IRS系统和一个IRS参数设置(By Electra)
|
||||
新的事件系统,允许自由定义事件和参数数量,让更多的模式创意成为可能 (By Electra & MrZ)
|
||||
DiscordRPC支持
|
||||
主菜单添加公告页面
|
||||
尝试重启联网
|
||||
修复:
|
||||
|
||||
Reference in New Issue
Block a user