Skip to content

Repentogon socket #517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@
[submodule "libs/imgui"]
path = libs/imgui
url = https://github.com/TeamREPENTOGON/imgui
[submodule "libs/luasocket"]
path = libs/luasocket
url = https://github.com/lunarmodules/luasocket.git
54 changes: 53 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ include_directories(${CMAKE_SOURCE_DIR}/include "${CMAKE_SOURCE_DIR}/libs/lua"
"${CMAKE_SOURCE_DIR}/libs/LuaBridge/Source/LuaBridge"
"${CMAKE_SOURCE_DIR}/libzhl" "${CMAKE_SOURCE_DIR}/libs/imgui"
"${CMAKE_SOURCE_DIR}/libs/imgui/misc/freetype" "${CMAKE_SOURCE_DIR}/libs/imgui/backends"
"${CMAKE_SOURCE_DIR}/libs/NaturalSort" "${CMAKE_SOURCE_DIR}/libs/glad/include" "${CMAKE_SOURCE_DIR}/libs/mINI/src/mini")
"${CMAKE_SOURCE_DIR}/libs/NaturalSort" "${CMAKE_SOURCE_DIR}/libs/glad/include" "${CMAKE_SOURCE_DIR}/libs/mINI/src/mini"
"${CMAKE_SOURCE_DIR}/libs/luasocket")

# Zydis
option(ZYDIS_BUILD_TOOLS "" OFF)
Expand Down Expand Up @@ -77,6 +78,55 @@ list(REMOVE_ITEM LUA_SRC "${CMAKE_SOURCE_DIR}/libs/lua/onelua.c")
add_compile_definitions(LUA_BUILD_AS_DLL)
add_library(Lua5.4 SHARED ${LUA_SRC})

# LuaSocket
set(LUASOCKET_SRC
${CMAKE_SOURCE_DIR}/libs/luasocket/src/luasocket.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/timeout.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/buffer.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/io.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/auxiliar.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/compat.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/options.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/inet.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/except.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/select.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/tcp.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/udp.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/mime.c
${CMAKE_SOURCE_DIR}/libs/luasocket/src/wsocket.c
)

set(LUASOCKET_HEADERS
${CMAKE_SOURCE_DIR}/libs/luasocket/src/luasocket.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/timeout.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/buffer.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/io.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/auxiliar.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/compat.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/options.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/inet.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/except.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/select.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/tcp.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/udp.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/mime.h
${CMAKE_SOURCE_DIR}/libs/luasocket/src/wsocket.h
)
execute_process(
COMMAND ${GIT_EXECUTABLE} apply ${CMAKE_SOURCE_DIR}/libs/luasocket_patch.diff
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/libs/luasocket
RESULT_VARIABLE result
)

if(result)
message(FATAL_ERROR "Failed to apply luasocket_patch.diff: ${result}")
endif()

add_compile_definitions(_WIN32)
add_library(LuaSocket SHARED ${LUASOCKET_SRC} ${LUASOCKET_HEADERS})
target_link_libraries(LuaSocket ws2_32 Lua5.4)
# target_include_directories(LuaSocket PUBLIC ${CMAKE_SOURCE_DIR}/libs/luasocket/src)

# IsaacRepentance.h/.cpp
FILE(GLOB ZHL_FILES ${CMAKE_SOURCE_DIR}/libzhl/functions/*.zhl)
LIST(APPEND ZHL_FILES ${CMAKE_SOURCE_DIR}/libzhl/functions/ExtraTypes)
Expand Down Expand Up @@ -207,6 +257,7 @@ target_compile_options(zhlDelirium PUBLIC "/MD")

add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/repentogon/resources" "$<TARGET_FILE_DIR:zhlREPENTOGON>/resources")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/repentogon/resources-repentogon" "$<TARGET_FILE_DIR:zhlREPENTOGON>/resources-repentogon")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE_DIR:dsound>/LuaSocket.dll" "$<TARGET_FILE_DIR:zhlREPENTOGON>/resources/scripts/repentogon_socket/core.dll")
# add_custom_command(TARGET zhlDelirium POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/delirium/resources-delirium" "$<TARGET_FILE_DIR:zhlDelirium>/resources-delirium")

if(NOT ISAAC_DIRECTORY STREQUAL "")
Expand All @@ -218,6 +269,7 @@ if(NOT ISAAC_DIRECTORY STREQUAL "")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE_DIR:zhlREPENTOGON>/zhlREPENTOGON.dll" "${ISAAC_DIRECTORY}")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/repentogon/resources" "${ISAAC_DIRECTORY}/resources")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/repentogon/resources-repentogon" "${ISAAC_DIRECTORY}/resources-repentogon")
add_custom_command(TARGET zhlREPENTOGON POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE_DIR:dsound>/LuaSocket.dll" "${ISAAC_DIRECTORY}/resources/scripts/repentogon_socket/core.dll")
add_custom_command(TARGET zhlDelirium POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE_DIR:zhlDelirium>/zhlDelirium.dll" "${ISAAC_DIRECTORY}")
# add_custom_command(TARGET zhlDelirium POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/delirium/resources-delirium" "${ISAAC_DIRECTORY}/resources-delirium")
endif()
Expand Down
1 change: 1 addition & 0 deletions libs/luasocket
Submodule luasocket added at 1fad16
13 changes: 13 additions & 0 deletions libs/luasocket_patch.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/src/luasocket.c b/src/luasocket.c
index 0fd99f7..683fa08 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -96,7 +96,7 @@ static int base_open(lua_State *L) {
/*-------------------------------------------------------------------------*\
* Initializes all library modules.
\*-------------------------------------------------------------------------*/
-LUASOCKET_API int luaopen_socket_core(lua_State *L) {
+LUASOCKET_API int luaopen_repentogon_socket_core(lua_State *L) {
int i;
base_open(L);
for (i = 0; mod[i].name; i++) mod[i].func(L);
4 changes: 4 additions & 0 deletions repentogon/resources/scripts/main_ex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ end
local oldrequire = require

function require(modname)
if modname == "socket.core" then
return oldrequire("repentogon_socket.core")
end

local ret = oldrequire(modname)
return ret
end
Expand Down
281 changes: 281 additions & 0 deletions repentogon/resources/scripts/repentogon_socket/ftp.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
-----------------------------------------------------------------------------
-- FTP support for the Lua language
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local table = require("table")
local string = require("string")
local math = require("math")
local socket = require("socket")
local url = require("socket.url")
local tp = require("socket.tp")
local ltn12 = require("ltn12")
module("socket.ftp")

-----------------------------------------------------------------------------
-- Program constants
-----------------------------------------------------------------------------
-- timeout in seconds before the program gives up on a connection
TIMEOUT = 60
-- default port for ftp service
PORT = 21
-- this is the default anonymous password. used when no password is
-- provided in url. should be changed to your e-mail.
USER = "ftp"
PASSWORD = "[email protected]"

-----------------------------------------------------------------------------
-- Low level FTP API
-----------------------------------------------------------------------------
local metat = { __index = {} }

function open(server, port, create)
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create))
local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end)
return f
end

function metat.__index:portconnect()
self.try(self.server:settimeout(TIMEOUT))
self.data = self.try(self.server:accept())
self.try(self.data:settimeout(TIMEOUT))
end

function metat.__index:pasvconnect()
self.data = self.try(socket.tcp())
self.try(self.data:settimeout(TIMEOUT))
self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
end

function metat.__index:login(user, password)
self.try(self.tp:command("user", user or USER))
local code, reply = self.try(self.tp:check{"2..", 331})
if code == 331 then
self.try(self.tp:command("pass", password or PASSWORD))
self.try(self.tp:check("2.."))
end
return 1
end

function metat.__index:pasv()
self.try(self.tp:command("pasv"))
local code, reply = self.try(self.tp:check("2.."))
local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
self.try(a and b and c and d and p1 and p2, reply)
self.pasvt = {
ip = string.format("%d.%d.%d.%d", a, b, c, d),
port = p1*256 + p2
}
if self.server then
self.server:close()
self.server = nil
end
return self.pasvt.ip, self.pasvt.port
end

function metat.__index:port(ip, port)
self.pasvt = nil
if not ip then
ip, port = self.try(self.tp:getcontrol():getsockname())
self.server = self.try(socket.bind(ip, 0))
ip, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(TIMEOUT))
end
local pl = math.mod(port, 256)
local ph = (port - pl)/256
local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",")
self.try(self.tp:command("port", arg))
self.try(self.tp:check("2.."))
return 1
end

function metat.__index:send(sendt)
self.try(self.pasvt or self.server, "need port or pasv first")
-- if there is a pasvt table, we already sent a PASV command
-- we just get the data connection into self.data
if self.pasvt then self:pasvconnect() end
-- get the transfer argument and command
local argument = sendt.argument or
url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = sendt.command or "stor"
-- send the transfer command and check the reply
self.try(self.tp:command(command, argument))
local code, reply = self.try(self.tp:check{"2..", "1.."})
-- if there is not a a pasvt table, then there is a server
-- and we already sent a PORT command
if not self.pasvt then self:portconnect() end
-- get the sink, source and step for the transfer
local step = sendt.step or ltn12.pump.step
local readt = {self.tp.c}
local checkstep = function(src, snk)
-- check status in control connection while downloading
local readyt = socket.select(readt, nil, 0)
if readyt[tp] then code = self.try(self.tp:check("2..")) end
return step(src, snk)
end
local sink = socket.sink("close-when-done", self.data)
-- transfer all data and check error
self.try(ltn12.pump.all(sendt.source, sink, checkstep))
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
-- done with data connection
self.data:close()
-- find out how many bytes were sent
local sent = socket.skip(1, self.data:getstats())
self.data = nil
return sent
end

function metat.__index:receive(recvt)
self.try(self.pasvt or self.server, "need port or pasv first")
if self.pasvt then self:pasvconnect() end
local argument = recvt.argument or
url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = recvt.command or "retr"
self.try(self.tp:command(command, argument))
local code = self.try(self.tp:check{"1..", "2.."})
if not self.pasvt then self:portconnect() end
local source = socket.source("until-closed", self.data)
local step = recvt.step or ltn12.pump.step
self.try(ltn12.pump.all(source, recvt.sink, step))
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
self.data:close()
self.data = nil
return 1
end

function metat.__index:cwd(dir)
self.try(self.tp:command("cwd", dir))
self.try(self.tp:check(250))
return 1
end

function metat.__index:type(type)
self.try(self.tp:command("type", type))
self.try(self.tp:check(200))
return 1
end

function metat.__index:greet()
local code = self.try(self.tp:check{"1..", "2.."})
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
return 1
end

function metat.__index:quit()
self.try(self.tp:command("quit"))
self.try(self.tp:check("2.."))
return 1
end

function metat.__index:close()
if self.data then self.data:close() end
if self.server then self.server:close() end
return self.tp:close()
end

-----------------------------------------------------------------------------
-- High level FTP API
-----------------------------------------------------------------------------
local function override(t)
if t.url then
local u = url.parse(t.url)
for i,v in base.pairs(t) do
u[i] = v
end
return u
else return t end
end

local function tput(putt)
putt = override(putt)
socket.try(putt.host, "missing hostname")
local f = open(putt.host, putt.port, putt.create)
f:greet()
f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end
f:pasv()
local sent = f:send(putt)
f:quit()
f:close()
return sent
end

local default = {
path = "/",
scheme = "ftp"
}

local function parse(u)
local t = socket.try(url.parse(u, default))
socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
socket.try(t.host, "missing hostname")
local pat = "^type=(.)$"
if t.params then
t.type = socket.skip(2, string.find(t.params, pat))
socket.try(t.type == "a" or t.type == "i",
"invalid type '" .. t.type .. "'")
end
return t
end

local function sput(u, body)
local putt = parse(u)
putt.source = ltn12.source.string(body)
return tput(putt)
end

put = socket.protect(function(putt, body)
if base.type(putt) == "string" then return sput(putt, body)
else return tput(putt) end
end)

local function tget(gett)
gett = override(gett)
socket.try(gett.host, "missing hostname")
local f = open(gett.host, gett.port, gett.create)
f:greet()
f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end
f:pasv()
f:receive(gett)
f:quit()
return f:close()
end

local function sget(u)
local gett = parse(u)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)
return table.concat(t)
end

command = socket.protect(function(cmdt)
cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command")
local f = open(cmdt.host, cmdt.port, cmdt.create)
f:greet()
f:login(cmdt.user, cmdt.password)
f.try(f.tp:command(cmdt.command, cmdt.argument))
if cmdt.check then f.try(f.tp:check(cmdt.check)) end
f:quit()
return f:close()
end)

get = socket.protect(function(gett)
if base.type(gett) == "string" then return sget(gett)
else return tget(gett) end
end)

Loading