Skip to content

Commit 7cd899a

Browse files
committed
Version 0.5.1
* Fix missing locale strings + Ingame menu hotkey changing
1 parent 69d8d43 commit 7cd899a

36 files changed

+421
-214
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
.vscode/settings.json
2-
src/thirdparty/ScriptHookRDR2/
3-
src/thirdparty/ScriptHookV/
2+
src/thirdparty/ScriptHook*/
43
src/thirdparty/LuaJIT/
54
objs/

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Lua scripting mod for RDR2/GTAV [![Build Status](https://github.com/igor725/RedLua/actions/workflows/release.yml/badge.svg)](https://github.com/igor725/RedLua/actions/workflows/release.yml)
22

3-
RedLua is a AB ScriptHook library that simplifies the game modding process.
3+
RedLua is a AB's ScriptHook library that simplifies the game modding process.
44

55
## Installation
66

@@ -165,7 +165,7 @@ misc.iskeyjustup(VK_*, exclusive = false)
165165
misc.resetkey(VK_*)
166166

167167
-- Get game version
168-
misc.gamever() -- Returns: number (e.g. 1436.31) and string ("rdr3" or "gta5")
168+
misc.gamever() -- Returns: number (getGameVersion() result) and string ("rdr3" or "gta5")
169169

170170
-- Get RedLua version
171171
misc.libver() -- Returns: integer, e.g. 010, 020, etc.
@@ -181,6 +181,18 @@ menu.set {...} -- Returns: nothing. Note that this function is NOT safe, it may
181181
-- Remove menu section for the script
182182
-- Note that the menu will only be removed after 1 or more (depends on the number of submenus) full garbage collection steps!
183183
menu.remove() -- Returns: nothing
184+
185+
--[[
186+
Library: lang
187+
]]
188+
189+
-- Add locale strings
190+
-- Example script: examples/ScriptMenu.lua
191+
lang.install {...} -- Returns: nothing
192+
193+
-- Get localized string for the current language
194+
lang.get(code) -- Returns: string
195+
184196
```
185197

186198
## Contribution

build.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ IF "%1"=="standalone" SET RL_STANDALONE=1
1313
IF "%1"=="" GOTO argdone
1414
SHIFT
1515
GOTO argparse
16+
1617
:argdone
1718
SET RL_LUAJIT_SOURCE_DIR=.\src\thirdparty\LuaJIT\src
1819
IF NOT EXIST "%RL_LUAJIT_SOURCE_DIR%\lua51.lib" (
-56 KB
Binary file not shown.

examples/RCE.lua/Libs/svhttp.lua

Lines changed: 181 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,63 @@
1-
local socket = require('socket.core')
1+
local ffi = require'ffi'
2+
local C = ffi.C
3+
ffi.cdef[[
4+
void *malloc(size_t);
5+
void *realloc(void *, size_t);
6+
void free(void *);
7+
8+
void Sleep(unsigned long);
9+
10+
struct WSADATA {
11+
short wLoVer, wHiVer;
12+
unsigned short iMaxSock;
13+
long dont_care[128];
14+
};
15+
16+
int WSAStartup(short, struct WSADATA *);
17+
void WSACleanup();
18+
unsigned long WSAGetLastError();
19+
20+
struct sockaddr {
21+
unsigned short sa_family;
22+
char sa_data[14];
23+
};
24+
25+
struct in_addr {
26+
unsigned long s_addr;
27+
};
28+
29+
struct sockaddr_in {
30+
short sin_family;
31+
unsigned short sin_port;
32+
struct in_addr sin_addr;
33+
char sin_zero[8];
34+
};
35+
36+
unsigned short htons(unsigned short);
37+
unsigned long htonl(unsigned long);
38+
int inet_pton(int, const char *, void *);
39+
40+
int socket(int, int, int);
41+
int bind(int, const struct sockaddr *, int);
42+
int listen(int, int);
43+
int accept(int);
44+
int recv(int, char *, int, int);
45+
int send(int, const char *, int, int);
46+
int setsockopt(int, int, int, const void *, int);
47+
int ioctlsocket(int, long, unsigned long *);
48+
void closesocket(int);
49+
50+
struct sockbuf {
51+
unsigned int size, pos;
52+
char *ptr;
53+
};
54+
]]
55+
local lib = ffi.load'ws2_32'
56+
local wdata = ffi.new('struct WSADATA')
57+
if lib.WSAStartup(0x0202, wdata) ~= 0 then
58+
error('WSAStartup failed')
59+
end
60+
261
local httpcodes = require('httpcodes')
362
local no_body = {
463
['GET'] = true, ['DELETE'] = true,
@@ -52,21 +111,131 @@ local _M = {
52111
}
53112
_M.__index = _M
54113

55-
local function sassert(fd, ret, err)
56-
if not ret then
57-
fd:close()
114+
local function ensure(buf, need)
115+
if buf.size - buf.pos < need then
116+
local newsz = buf.size + need + 256
117+
buf.ptr = C.realloc(buf.ptr, newsz)
118+
assert(buf.ptr ~= nil, 'realloc() failed')
119+
buf.size = newsz
120+
end
121+
end
122+
123+
local sock_meta = {
124+
init = function(self, fd)
125+
self.fd = fd
126+
local val = ffi.new('long[1]', 0)
127+
if lib.setsockopt(fd, 0xffff, 0x0004, val, 4) ~= 0 then -- REUSEADDR
128+
error('setsockopt failed')
129+
end
130+
val[0] = 1
131+
if lib.ioctlsocket(fd, -2147195266, val) ~= 0 then -- FIONBIO
132+
print(lib.WSAGetLastError())
133+
error('ioctlsocket failed')
134+
end
135+
end,
136+
bind = function(self, addr)
137+
if lib.bind(self.fd, ffi.cast('const struct sockaddr *', addr), ffi.sizeof(addr)) ~= 0 then
138+
print(lib.WSAGetLastError())
139+
error('bind() failed')
140+
end
141+
if lib.listen(self.fd, 128) ~= 0 then
142+
print(lib.WSAGetLastError())
143+
error('listen() failed')
144+
end
145+
end,
146+
receive = function(self, t)
147+
if self._sockbuf == nil then
148+
self._sockbuf = ffi.new('struct sockbuf', {
149+
32, 0, C.malloc(32)
150+
})
151+
end
152+
153+
if t == '*l' then
154+
local len
155+
repeat
156+
ensure(self._sockbuf, 1)
157+
len = lib.recv(self.fd, self._sockbuf.ptr + self._sockbuf.pos, 1, 0)
158+
if len > 0 then
159+
local ch = self._sockbuf.ptr[self._sockbuf.pos]
160+
if ch == 10 then
161+
local e = self._sockbuf.pos
162+
self._sockbuf.pos = 0
163+
return ffi.string(self._sockbuf.ptr, e)
164+
elseif ch ~= 13 then
165+
self._sockbuf.pos = self._sockbuf.pos + 1
166+
end
167+
end
168+
until len == -1 or len == 0
169+
170+
return nil, 'timeout'
171+
elseif t == '*a' then
172+
ensure(self._sockbuf, 128)
173+
local ret
174+
repeat
175+
ret = lib.recv(self.fd, self._sockbuf.ptr + self._sockbuf.pos, 128, 0)
176+
if ret > 0 then self._sockbuf.pos = self._sockbuf.pos + ret end
177+
until ret == -1 or ret == 0
178+
179+
return self._sockbuf.pos
180+
elseif type(t) == 'number' then
181+
ensure(self._sockbuf, t)
182+
local len = lib.recv(self.fd, self._sockbuf.ptr, t, 0)
183+
return ffi.string(self._sockbuf.ptr, len)
184+
end
185+
186+
return nil, 'fuck'
187+
end,
188+
send = function(self, data, from)
189+
from = from or 0
190+
local bs = #data - from
191+
local sent = from
192+
if bs > 0 then
193+
data = ffi.cast('char *', data) + from
194+
local ret = lib.send(self.fd, data, bs, 0)
195+
if ret < 0 then return 0, 'timeout', from end
196+
from = from + ret
197+
bs = bs - ret
198+
end
199+
200+
local err
201+
if bs ~= 0 then
202+
err = 'timeout'
203+
else
204+
from = nil
205+
end
206+
207+
return sent, err, from
208+
end,
209+
close = function(self)
210+
lib.closesocket(self.fd)
211+
if self._sockbuf then
212+
C.free(self._sockbuf.ptr)
213+
self._sockbuf.ptr = nil
214+
end
58215
end
59-
assert(ret, err)
216+
}
217+
sock_meta.__index = sock_meta
218+
sock_meta.accept = function(self)
219+
local cfd = lib.accept(self.fd)
220+
if cfd == -1 then return nil, true end
221+
local cl = setmetatable({}, sock_meta)
222+
cl:init(cfd)
223+
return cl
60224
end
61225

62226
local function binder(ip, port)
63227
if ip == '*' then ip = '0.0.0.0' end
64-
local fd = assert(socket.tcp())
65-
fd:setoption('reuseaddr', true)
66-
sassert(fd, fd:bind(ip, port))
67-
sassert(fd, fd:listen())
68-
fd:settimeout(0)
69-
return fd
228+
local addr = ffi.new('struct sockaddr_in', {
229+
sin_family = 2, -- AF_INET
230+
sin_port = lib.htons(port),
231+
})
232+
if lib.inet_pton(addr.sin_family, ip, addr.sin_addr) ~= 1 then
233+
error('Invalid IP specified')
234+
end
235+
local sock = setmetatable({}, sock_meta)
236+
sock:init(lib.socket(addr.sin_family, 1, 6))
237+
sock:bind(addr)
238+
return sock
70239
end
71240

72241
local function waitForLine(cl)
@@ -295,7 +464,6 @@ function _M:doStep()
295464

296465
break
297466
end
298-
client:settimeout(0)
299467
self.clients[client] = coroutine.create(self.clientHandler)
300468
end
301469

@@ -322,7 +490,7 @@ end
322490

323491
function _M:startLoop()
324492
while self:doStep() do
325-
socket.sleep(0.01)
493+
C.Sleep(10)
326494
end
327495
end
328496

examples/RCE.lua/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ As soon as RCE loads, it starts the web server on [0.0.0.0:1337](https://127.0.0
1010

1111
## Credits
1212

13-
This mod uses thirdparty libraries such as [luasocket](https://luarocks.org/modules/lunarmodules/luasocket), [mimetypes](https://luarocks.org/modules/luarocks/mimetypes), [Ace Editor](https://ace.c9.io/) and [Toastify](https://github.com/apvarun/toastify-js)
13+
This mod uses some thirdparty libraries such as [mimetypes](https://luarocks.org/modules/luarocks/mimetypes), [Ace Editor](https://ace.c9.io/) and [Toastify](https://github.com/apvarun/toastify-js)

examples/RCE.lua/main.lua

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,4 +276,13 @@ end
276276

277277
t.OnReload = t.OnStop
278278

279-
return t
279+
if ... then
280+
return t
281+
else
282+
package.path = '.\\Libs\\?.lua'
283+
package.cpath = '.\\Libs\\C\\?.dll'
284+
t.OnLoad()
285+
while not _STOP do
286+
t.OnTick()
287+
end
288+
end

misc/Langs/en.lng

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ core.main.setts=Settings
88
core.main.about=About RedLua
99

1010
# Settings
11+
core.setts.hotkey=Change menu hotkey
1112
core.setts.autorun=Autorun feature enabled
1213
core.setts.updater=Check for updates at startup
1314
core.setts.chkupd=Check for updates
@@ -18,12 +19,16 @@ core.setts.toggall=Toggle all scripts
1819
core.setts.relall=Reload all scripts
1920
core.setts.unlall=Unload all scripts
2021

22+
core.setts.nfy.hksc=Menu hotkey changed to %s
23+
core.setts.nfy.hkfl=Unknown keyname specified %s
24+
core.setts.nfy.hkin=Unknown keycode specified %d
2125
core.setts.nfy.srlsc=Script list has been successfully updated
2226
core.setts.nfy.srlfl=Failed to update script list
2327
core.setts.nfy.nrlsc=NativeDB reloaded successfully!
2428
core.setts.nfy.nrlfl=Failed to reload NativeDB, error code: %d
2529
core.setts.nfy.runall=All scripts have been resumed
2630
core.setts.nfy.stpall=All scripts have been suspended
31+
core.setts.nfy.relall=All scripts have been reloaded
2732
core.setts.nfy.unlall=All scripts have been unloaded
2833

2934
# Scripts list

misc/Langs/ru.lng

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ core.main.setts=Настройки
88
core.main.about=О RedLua
99

1010
# Настройки
11+
core.setts.hotkey=Изменить бинд меню
1112
core.setts.autorun=Автозагрузка скриптов
1213
core.setts.updater=Автообновление библиотеки
1314
core.setts.chkupd=Проверить обновления
@@ -18,12 +19,16 @@ core.setts.toggall=Вкл/выкл все скрипты
1819
core.setts.relall=Перезагрузить все скрипты
1920
core.setts.unlall=Выгрузить все скрипты
2021

22+
core.setts.nfy.hksc=Бинд меню изменён на %s
23+
core.setts.nfy.hkfl=Неизвестная кнопка %s
24+
core.setts.nfy.hkin=Введён недопустимый код кнопки %d
2125
core.setts.nfy.srlsc=Список скриптов успешно обновлён
2226
core.setts.nfy.srlfl=Не удалось обновить список скриптов
2327
core.setts.nfy.nrlsc=NativeDB успешно перезагружена
2428
core.setts.nfy.nrlfl=Не удалось перезагрузить NativeDB: %d
2529
core.setts.nfy.runall=Выполнение всех скриптов возобновлено
2630
core.setts.nfy.stpall=Выполнение всех скриптов приостановлено
31+
core.setts.nfy.relall=Все скрпиты перезагружены
2732
core.setts.nfy.unlall=Все скрпиты выгружены
2833

2934
# Список скриптов
@@ -48,6 +53,7 @@ core.script.nfy.unlsc=Скрипт выгружен успешно
4853
# Проверка обновлений
4954
core.chkupd.rl=Обновить RedLua
5055
core.chkupd.ndb=Обновить NativeDB
56+
core.chkupd.nfy.noup=Обновления не найдены
5157
core.chkupd.nfy.upfl=Поризошла ошибка при обновлении: %d
5258
core.updalert.nfn=Новая версия %s
5359
core.updalert.btn=Открыть страницу загрузки

misc/ScriptHook.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ if (Test-Path -PathType Container $SHOOK_DIR) {
3535
$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
3636
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList "&Yes", "ScriptHook$($VARIANT) will be redownloaded"))
3737
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList "&No", "This script will close"))
38-
switch($Host.UI.PromptForChoice($title, $text, $choices, 1)) {
38+
switch ($Host.UI.PromptForChoice($title, $text, $choices, 1)) {
3939
0 {
4040
Remove-Item -Recurse -Force $SHOOK_DIR
4141
}

0 commit comments

Comments
 (0)