Skip to content

Commit 3086182

Browse files
refactor(discord): prefer LuaJIT if available
1 parent 48e4142 commit 3086182

File tree

3 files changed

+76
-16
lines changed

3 files changed

+76
-16
lines changed

.luacheckrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-- luacheck: ignore 131
22

3-
std = 'lua52c'
3+
std = 'luajit'
44

55
read_globals = {'mp'}
66

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
My collection of cross-platform scripts for [mpv][mpv].
66

77
Feel free to edit and adapt them however you like
8-
and if you think your changes should be merged,
9-
don't hesitate to submit a pull request.
8+
<br>and if you think your changes should be merged,
9+
<br>don't hesitate to submit a pull request.
1010

1111
### [open-dialog](open-dialog)
1212

@@ -32,11 +32,16 @@ Screenshot the full window and copy it to the clipboard.
3232

3333
### [discord.lua](discord.lua)
3434

35-
A Discord RPC script that does not require LuaJIT.
36-
<br>It can be used out of the box on Windows.
37-
<br>On Linux and MacOS it depends on [luasocket][].
35+
Discord rich presence in a single script.
3836
<br>Default key binding: `D`
3937

38+
| | Windows | Linux | MacOS |
39+
|:------------:|:---------:|:-------:|:-------:|
40+
| **LuaJIT** ||||
41+
| **Lua** ||||
42+
43+
∗ Requires [LuaSocket](https://w3.impa.br/~diego/software/luasocket/)
44+
4045
### [misc.lua](misc.lua)
4146

4247
Miscellaneous simple functions.
@@ -47,4 +52,3 @@ Show the current time (`HH:MM`) on the OSD.
4752
<br>Default key binding: `Ctrl+t`
4853

4954
[mpv]: https://github.com/mpv-player/mpv
50-
[luasocket]: http://w3.impa.br/~diego/software/luasocket/home.html

discord.lua

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,46 @@ RPC = {
3939

4040
if RPC.unix then
4141
local temp = os.getenv('XDG_RUNTIME_DIR')
42-
or os.getenv('TMPDIR')
43-
or os.getenv('TMP')
44-
or os.getenv('TEMP')
45-
or '/tmp'
42+
or os.getenv('TMPDIR')
43+
or os.getenv('TMP')
44+
or os.getenv('TEMP')
45+
or '/tmp'
4646
RPC.path = temp..'/discord-ipc-0'
47+
if type(jit) == 'table' then
48+
msg.verbose('using', jit.version)
49+
ffi = require('ffi')
50+
ffi.cdef[[
51+
struct sockaddr {
52+
unsigned short int sa_family;
53+
char sa_data[14];
54+
};
55+
struct sockaddr_un {
56+
unsigned short int sun_family;
57+
char sun_path[108];
58+
};
59+
int socket(int domain, int type, int protocol);
60+
int connect(int fd, const struct sockaddr *addr, unsigned int len);
61+
int recv(int fd, void *buf, unsigned int len, int flags);
62+
int send(int fd, const void *buf, unsigned int n, int flags);
63+
int close(int fd);
64+
char *strerror(int errnum);
65+
]]
66+
function _strerror()
67+
return ffi.string(ffi.C.strerror(ffi.errno()))
68+
end
69+
function _connect(fd, addr)
70+
local cast = ffi.cast('const struct sockaddr *', addr)
71+
return ffi.C.connect(fd, cast, ffi.sizeof(addr[0]))
72+
end
73+
function _recv(fd, len)
74+
local buff = ffi.new('unsigned char[?]', len)
75+
local status = ffi.C.recv(fd, buff, len, 0) ~= -1
76+
return status, status and ffi.string(buff, len) or _strerror()
77+
end
78+
else
79+
local socket = assert(require 'socket')
80+
msg.verbose('using', socket._VERSION)
81+
end
4782
else
4883
RPC.path = [[\\?\pipe\discord-ipc-0]]
4984
end
@@ -102,8 +137,19 @@ end
102137

103138
function RPC:connect()
104139
local status, data
105-
if self.unix then
106-
self.socket = assert(require 'socket.unix' ())
140+
if ffi then
141+
local addr = ffi.new('struct sockaddr_un[1]', {{
142+
sun_family = 1, -- AF_UNIX
143+
sun_path = self.path
144+
}})
145+
self.socket = ffi.C.socket(1, 1, 0) -- AF_UNIX, SOCK_STREAM
146+
if self.socket ~= -1 then
147+
status = _connect(self.socket, addr)
148+
if status ~= -1 then return true end
149+
end
150+
data = _strerror()
151+
elseif self.unix then
152+
self.socket = require 'socket.unix' ()
107153
status, data = pcall(function()
108154
assert(self.socket:connect(self.path))
109155
end)
@@ -125,7 +171,9 @@ function RPC:recv(len)
125171
assert(self:connect(), 'failed to connect')
126172
end
127173
local status, data
128-
if self.unix then
174+
if ffi then
175+
status, data = _recv(self.socket, len)
176+
elseif self.unix then
129177
status, data = pcall(function()
130178
return assert(self.socket:receive(len))
131179
end)
@@ -149,7 +197,10 @@ function RPC:send(op, body)
149197
end
150198
local data = self.pack(op, body)
151199
msg.debug('sending', data:tohex())
152-
if self.unix then
200+
if ffi then
201+
local status = ffi.C.send(self.socket, data, #data, 0)
202+
assert(status ~= -1, _strerror())
203+
elseif self.unix then
153204
assert(self.socket:send(data))
154205
else
155206
assert(self.socket:write(data))
@@ -203,7 +254,12 @@ end
203254
function RPC:disconnect()
204255
if self.socket then
205256
self:send(OP.CLOSE, '')
206-
self.socket:close()
257+
if ffi then
258+
local status = ffi.C.close(self.socket)
259+
assert(status ~= -1, _strerror())
260+
else
261+
self.socket:close()
262+
end
207263
self.socket = nil
208264
end
209265
end

0 commit comments

Comments
 (0)