Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
878ec658e6 | ||
|
|
5984a056de | ||
|
|
d90bc0f501 | ||
|
|
7c80facd4a | ||
|
|
f4ae036800 |
+43
-34
@@ -13,16 +13,18 @@ on:
|
|||||||
- main
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-libuv:
|
build-libuv-linux:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
LIBUV_REF: 'v1.44.2'
|
CC: "clang-14"
|
||||||
CC: "clang-10"
|
CXX: "clang++-14"
|
||||||
CXX: "clang++-10"
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout repository with submodules
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
shell: bash
|
|
||||||
if: startsWith(runner.os, 'Linux')
|
|
||||||
run: |
|
run: |
|
||||||
sudo dpkg --add-architecture i386
|
sudo dpkg --add-architecture i386
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -31,42 +33,49 @@ jobs:
|
|||||||
libc6-dev libc6-dev-i386 linux-libc-dev \
|
libc6-dev libc6-dev-i386 linux-libc-dev \
|
||||||
linux-libc-dev:i386 lib32z1-dev ${{ env.CC }}
|
linux-libc-dev:i386 lib32z1-dev ${{ env.CC }}
|
||||||
|
|
||||||
- name: Select compiler
|
- name: Build and install libuv (Linux x86)
|
||||||
shell: bash
|
|
||||||
if: startsWith(runner.os, 'Linux')
|
|
||||||
run: |
|
|
||||||
echo "CC=${{ env.CC }}" >> $GITHUB_ENV
|
|
||||||
echo "CXX=${{ env.CXX }}" >> $GITHUB_ENV
|
|
||||||
${{ env.CC }} --version
|
|
||||||
${{ env.CXX }} --version
|
|
||||||
|
|
||||||
- name: Checkout libuv
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: libuv/libuv
|
|
||||||
ref: ${{ env.LIBUV_REF }}
|
|
||||||
path: libuv
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Build libuv
|
|
||||||
working-directory: libuv
|
working-directory: libuv
|
||||||
run: |
|
run: |
|
||||||
bash autogen.sh
|
bash autogen.sh
|
||||||
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" --disable-shared --enable-static
|
./configure --prefix="$(pwd)/dist" --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" --disable-shared --enable-static
|
||||||
make -j 8
|
make -j8
|
||||||
|
make install
|
||||||
|
|
||||||
- name: Upload libuv
|
- name: Upload libuv Linux Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: libuv
|
name: libuv-linux
|
||||||
include-hidden-files: true
|
path: libuv/dist
|
||||||
path: libuv
|
retention-days: 1
|
||||||
if-no-files-found: error
|
|
||||||
|
build-libuv-windows:
|
||||||
|
runs-on: windows-2022
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository with submodules
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Build and install libuv (Windows x86)
|
||||||
|
shell: cmd
|
||||||
|
working-directory: libuv
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -A Win32 -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>" -DCMAKE_INSTALL_PREFIX=..\dist
|
||||||
|
cmake --build . --config Release --target install
|
||||||
|
|
||||||
|
- name: Upload libuv Windows Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: libuv-windows
|
||||||
|
path: libuv/dist
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
build-release-extension:
|
build-release-extension:
|
||||||
uses: srcdslab/ci-workflows/.github/workflows/shared_build_release_am_extension.yml@v1
|
uses: srcdslab/ci-workflows/.github/workflows/shared_build_release_am_extension.yml@v1
|
||||||
needs: build-libuv
|
needs: [build-libuv-linux, build-libuv-windows]
|
||||||
with:
|
with:
|
||||||
sdks: "sdk2013"
|
sdks: "sdk2013"
|
||||||
artifact-path: "."
|
artifact-path: "libuv/dist"
|
||||||
|
submodules: "recursive"
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
[submodule "sm-ext-common"]
|
[submodule "sm-ext-common"]
|
||||||
path = sm-ext-common
|
path = sm-ext-common
|
||||||
url = https://github.com/srcdslab/sm-ext-common
|
url = https://github.com/srcdslab/sm-ext-common
|
||||||
|
[submodule "libuv"]
|
||||||
|
path = libuv
|
||||||
|
url = https://github.com/libuv/libuv.git
|
||||||
|
|||||||
Submodule
+1
Submodule libuv added at 9d51562c10
@@ -28,6 +28,8 @@ methodmap AsyncSocket < Handle {
|
|||||||
public native bool SetErrorCallback(AsyncSocketErrorCallback callback);
|
public native bool SetErrorCallback(AsyncSocketErrorCallback callback);
|
||||||
|
|
||||||
public native bool SetDataCallback(AsyncSocketDataCallback callback);
|
public native bool SetDataCallback(AsyncSocketDataCallback callback);
|
||||||
|
|
||||||
|
public native void GetClientIP(char[] buffer, int length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,5 +61,6 @@ public __ext_AsyncSocket_SetNTVOptional()
|
|||||||
MarkNativeAsOptional("AsyncSocket.SetConnectCallback");
|
MarkNativeAsOptional("AsyncSocket.SetConnectCallback");
|
||||||
MarkNativeAsOptional("AsyncSocket.SetErrorCallback");
|
MarkNativeAsOptional("AsyncSocket.SetErrorCallback");
|
||||||
MarkNativeAsOptional("AsyncSocket.SetDataCallback");
|
MarkNativeAsOptional("AsyncSocket.SetDataCallback");
|
||||||
|
MarkNativeAsOptional("AsyncSocket.GetClientIP");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
1.0.1
|
1.1.0
|
||||||
|
|||||||
+66
-25
@@ -1,41 +1,82 @@
|
|||||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
projectName = 'AsyncSocket'
|
projectName = 'AsyncSocket'
|
||||||
|
|
||||||
project = builder.LibraryProject(projectName)
|
project = builder.LibraryProject(projectName)
|
||||||
project.sources += [
|
project.sources += [
|
||||||
os.path.join(Extension.ext_root, 'src', 'extension.cpp'),
|
os.path.join(Extension.ext_root, 'src', 'extension.cpp'),
|
||||||
os.path.join(Extension.ext_root, 'src', 'context.cpp'),
|
os.path.join(Extension.ext_root, 'src', 'context.cpp'),
|
||||||
os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp')
|
os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Include header path directly from submodule
|
||||||
|
libuv_inc = os.path.join(Extension.ext_root, 'libuv', 'include')
|
||||||
|
libuv_root = os.path.join(Extension.ext_root, 'libuv')
|
||||||
|
|
||||||
for sdk_name in Extension.sdks:
|
for sdk_name in Extension.sdks:
|
||||||
sdk = Extension.sdks[sdk_name]
|
sdk = Extension.sdks[sdk_name]
|
||||||
if sdk['name'] in ['mock']:
|
if sdk['name'] in ['mock']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for cxx in builder.targets:
|
for cxx in builder.targets:
|
||||||
if not cxx.target.arch in sdk['platforms'][cxx.target.platform]:
|
if not cxx.target.arch in sdk['platforms'][cxx.target.platform]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
binary = Extension.HL2ExtConfig(project, builder, cxx, projectName + '.ext', sdk)
|
binary = Extension.HL2ExtConfig(
|
||||||
|
project, builder, cxx, projectName + '.ext', sdk
|
||||||
|
)
|
||||||
|
|
||||||
if cxx.target.platform == 'windows':
|
# Include uv.h path
|
||||||
binary.compiler.linkflags += ['ws2_32.lib']
|
binary.compiler.cxxincludes += [libuv_inc]
|
||||||
|
|
||||||
libuv_root = os.path.join(Extension.ext_root, 'libuv')
|
# Platform-specific linking
|
||||||
binary.compiler.cxxincludes += [
|
if cxx.target.platform == 'windows':
|
||||||
os.path.join(libuv_root, 'include'),
|
binary.compiler.linkflags += [
|
||||||
]
|
'ws2_32.lib',
|
||||||
|
'iphlpapi.lib',
|
||||||
|
'userenv.lib',
|
||||||
|
'dbghelp.lib',
|
||||||
|
'synchronization.lib', # Fixes WaitOnAddress / WakeByAddressSingle
|
||||||
|
]
|
||||||
|
|
||||||
# TODO: add proper linux support for x64
|
# Candidates where actions/download-artifact might unpack libuv.lib
|
||||||
if cxx.target.arch in ['x86'] and cxx.target.platform in ['linux']:
|
win_candidates = [
|
||||||
binary.compiler.linkflags += [
|
os.path.join(libuv_root, 'dist', 'lib', 'libuv.lib'),
|
||||||
os.path.join(libuv_root, '.libs', 'libuv.a'),
|
os.path.join(libuv_root, 'dist', 'libuv-windows', 'lib', 'libuv.lib'),
|
||||||
]
|
os.path.join(libuv_root, 'dist', 'Release', 'libuv.lib'),
|
||||||
# TODO: add proper windows support for libuv
|
os.path.join(Extension.ext_root, 'libuv.lib'),
|
||||||
if cxx.target.platform in ['windows']:
|
]
|
||||||
binary.compiler.linkflags += ['/FORCE:UNRESOLVED']
|
|
||||||
|
found_win_lib = None
|
||||||
|
for cand in win_candidates:
|
||||||
|
if os.path.exists(cand):
|
||||||
|
found_win_lib = cand
|
||||||
|
break
|
||||||
|
|
||||||
|
if found_win_lib:
|
||||||
|
binary.compiler.linkflags += [found_win_lib]
|
||||||
|
else:
|
||||||
|
binary.compiler.linkflags += ['libuv.lib']
|
||||||
|
|
||||||
|
elif cxx.target.platform == 'linux':
|
||||||
|
if cxx.target.arch == 'x86':
|
||||||
|
# Candidates where actions/download-artifact might unpack libuv.a
|
||||||
|
linux_candidates = [
|
||||||
|
os.path.join(libuv_root, 'dist', 'lib', 'libuv.a'),
|
||||||
|
os.path.join(libuv_root, 'dist', 'libuv-linux', 'lib', 'libuv.a'),
|
||||||
|
os.path.join(libuv_root, 'dist', '.libs', 'libuv.a'),
|
||||||
|
os.path.join(Extension.ext_root, 'libuv.a'),
|
||||||
|
]
|
||||||
|
|
||||||
|
found_linux_lib = None
|
||||||
|
for cand in linux_candidates:
|
||||||
|
if os.path.exists(cand):
|
||||||
|
found_linux_lib = cand
|
||||||
|
break
|
||||||
|
|
||||||
|
if found_linux_lib:
|
||||||
|
binary.compiler.linkflags += [found_linux_lib]
|
||||||
|
else:
|
||||||
|
binary.compiler.linkflags += ['-luv']
|
||||||
|
|
||||||
Extension.extensions += builder.Add(project)
|
Extension.extensions += builder.Add(project)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ CAsyncSocketContext::CAsyncSocketContext(IPluginContext *pContext)
|
|||||||
m_pHost = NULL;
|
m_pHost = NULL;
|
||||||
m_Port = -1;
|
m_Port = -1;
|
||||||
|
|
||||||
|
m_pClientIP = NULL;
|
||||||
|
|
||||||
m_Deleted = false;
|
m_Deleted = false;
|
||||||
m_PendingCallback = false;
|
m_PendingCallback = false;
|
||||||
m_Pending = false;
|
m_Pending = false;
|
||||||
@@ -26,6 +28,9 @@ CAsyncSocketContext::~CAsyncSocketContext()
|
|||||||
if(m_pHost)
|
if(m_pHost)
|
||||||
free(m_pHost);
|
free(m_pHost);
|
||||||
|
|
||||||
|
if(m_pClientIP)
|
||||||
|
free(m_pClientIP);
|
||||||
|
|
||||||
if(m_pConnectCallback)
|
if(m_pConnectCallback)
|
||||||
forwards->ReleaseForward(m_pConnectCallback);
|
forwards->ReleaseForward(m_pConnectCallback);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ public:
|
|||||||
char *m_pHost;
|
char *m_pHost;
|
||||||
int m_Port;
|
int m_Port;
|
||||||
|
|
||||||
|
char *m_pClientIP;
|
||||||
|
|
||||||
IChangeableForward *m_pConnectCallback;
|
IChangeableForward *m_pConnectCallback;
|
||||||
IChangeableForward *m_pErrorCallback;
|
IChangeableForward *m_pErrorCallback;
|
||||||
IChangeableForward *m_pDataCallback;
|
IChangeableForward *m_pDataCallback;
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
* @brief Implement extension code here.
|
* @brief Implement extension code here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MAX_IP_BUFFER_LENGTH 64
|
||||||
|
|
||||||
moodycamel::ReaderWriterQueue<CSocketConnect *> g_ConnectQueue;
|
moodycamel::ReaderWriterQueue<CSocketConnect *> g_ConnectQueue;
|
||||||
moodycamel::ReaderWriterQueue<CSocketError *> g_ErrorQueue;
|
moodycamel::ReaderWriterQueue<CSocketError *> g_ErrorQueue;
|
||||||
moodycamel::ReaderWriterQueue<CSocketData *> g_DataQueue;
|
moodycamel::ReaderWriterQueue<CSocketData *> g_DataQueue;
|
||||||
@@ -105,6 +107,19 @@ void OnGameFrame(bool simulating)
|
|||||||
pSocketContext->m_pStream = pConnect->pClientSocket;
|
pSocketContext->m_pStream = pConnect->pClientSocket;
|
||||||
pSocketContext->m_pStream->data = pSocketContext;
|
pSocketContext->m_pStream->data = pSocketContext;
|
||||||
|
|
||||||
|
if (pConnect->pClientIP)
|
||||||
|
{
|
||||||
|
pSocketContext->m_pClientIP = pConnect->pClientIP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pSocketContext->m_pClientIP = (char *)malloc(MAX_IP_BUFFER_LENGTH);
|
||||||
|
if (pSocketContext->m_pClientIP)
|
||||||
|
{
|
||||||
|
pSocketContext->m_pClientIP[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pConnect->pSocketContext->OnConnect(pSocketContext);
|
pConnect->pSocketContext->OnConnect(pSocketContext);
|
||||||
|
|
||||||
if(!pSocketContext->m_Deleted)
|
if(!pSocketContext->m_Deleted)
|
||||||
@@ -119,6 +134,10 @@ void OnGameFrame(bool simulating)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (pConnect->pClientIP)
|
||||||
|
{
|
||||||
|
pConnect->pSocketContext->m_pClientIP = pConnect->pClientIP;
|
||||||
|
}
|
||||||
pConnect->pSocketContext->Connected();
|
pConnect->pSocketContext->Connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +219,12 @@ void UV_DeleteAsyncContext(uv_async_t *pHandle)
|
|||||||
pSocketContext->m_pSocket = NULL;
|
pSocketContext->m_pSocket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSocketContext->m_pClientIP)
|
||||||
|
{
|
||||||
|
free(pSocketContext->m_pClientIP);
|
||||||
|
pSocketContext->m_pClientIP = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
delete pSocketContext;
|
delete pSocketContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +305,7 @@ void UV_OnConnect(uv_connect_t *req, int status)
|
|||||||
CSocketConnect *pConnect = (CSocketConnect *)malloc(sizeof(CSocketConnect));
|
CSocketConnect *pConnect = (CSocketConnect *)malloc(sizeof(CSocketConnect));
|
||||||
pConnect->pSocketContext = pSocketContext;
|
pConnect->pSocketContext = pSocketContext;
|
||||||
pConnect->pClientSocket = pSocketContext->m_pStream;
|
pConnect->pClientSocket = pSocketContext->m_pStream;
|
||||||
|
pConnect->pClientIP = NULL;
|
||||||
g_ConnectQueue.enqueue(pConnect);
|
g_ConnectQueue.enqueue(pConnect);
|
||||||
|
|
||||||
uv_read_start(pSocketContext->m_pStream, UV_AllocBuffer, UV_OnRead);
|
uv_read_start(pSocketContext->m_pStream, UV_AllocBuffer, UV_OnRead);
|
||||||
@@ -324,6 +350,26 @@ void UV_OnNewConnection(uv_stream_t *server, int status)
|
|||||||
CSocketConnect *pConnect = (CSocketConnect *)malloc(sizeof(CSocketConnect));
|
CSocketConnect *pConnect = (CSocketConnect *)malloc(sizeof(CSocketConnect));
|
||||||
pConnect->pSocketContext = pSocketContext;
|
pConnect->pSocketContext = pSocketContext;
|
||||||
pConnect->pClientSocket = (uv_stream_t *)pClientSocket;
|
pConnect->pClientSocket = (uv_stream_t *)pClientSocket;
|
||||||
|
|
||||||
|
pConnect->pClientIP = (char *)malloc(MAX_IP_BUFFER_LENGTH);
|
||||||
|
if (pConnect->pClientIP)
|
||||||
|
{
|
||||||
|
pConnect->pClientIP[0] = '\0';
|
||||||
|
struct sockaddr_storage name;
|
||||||
|
int namelen = sizeof(name);
|
||||||
|
if (uv_tcp_getpeername(pClientSocket, (struct sockaddr *)&name, &namelen) == 0)
|
||||||
|
{
|
||||||
|
if (name.ss_family == AF_INET)
|
||||||
|
{
|
||||||
|
uv_ip4_name((const struct sockaddr_in *)&name, pConnect->pClientIP, MAX_IP_BUFFER_LENGTH);
|
||||||
|
}
|
||||||
|
else if (name.ss_family == AF_INET6)
|
||||||
|
{
|
||||||
|
uv_ip6_name((const struct sockaddr_in6 *)&name, pConnect->pClientIP, MAX_IP_BUFFER_LENGTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_ConnectQueue.enqueue(pConnect);
|
g_ConnectQueue.enqueue(pConnect);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -599,6 +645,21 @@ cell_t Native_AsyncSocket_SetDataCallback(IPluginContext *pContext, const cell_t
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell_t Native_AsyncSocket_GetClientIP(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CAsyncSocketContext *pSocketContext = g_AsyncSocket.GetSocketInstanceByHandle(params[1]);
|
||||||
|
|
||||||
|
if (pSocketContext == NULL)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid socket handle");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ip = (pSocketContext->m_pClientIP != NULL) ? pSocketContext->m_pClientIP : "";
|
||||||
|
pContext->StringToLocal(params[2], params[3], ip);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Sourcemod Plugin Events
|
// Sourcemod Plugin Events
|
||||||
bool AsyncSocket::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
bool AsyncSocket::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||||
{
|
{
|
||||||
@@ -656,5 +717,6 @@ const sp_nativeinfo_t AsyncSocketNatives[] = {
|
|||||||
{"AsyncSocket.SetConnectCallback", Native_AsyncSocket_SetConnectCallback},
|
{"AsyncSocket.SetConnectCallback", Native_AsyncSocket_SetConnectCallback},
|
||||||
{"AsyncSocket.SetErrorCallback", Native_AsyncSocket_SetErrorCallback},
|
{"AsyncSocket.SetErrorCallback", Native_AsyncSocket_SetErrorCallback},
|
||||||
{"AsyncSocket.SetDataCallback", Native_AsyncSocket_SetDataCallback},
|
{"AsyncSocket.SetDataCallback", Native_AsyncSocket_SetDataCallback},
|
||||||
|
{"AsyncSocket.GetClientIP", Native_AsyncSocket_GetClientIP},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ struct CSocketConnect
|
|||||||
{
|
{
|
||||||
CAsyncSocketContext *pSocketContext;
|
CAsyncSocketContext *pSocketContext;
|
||||||
uv_stream_t *pClientSocket;
|
uv_stream_t *pClientSocket;
|
||||||
|
char *pClientIP;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CSocketData
|
struct CSocketData
|
||||||
|
|||||||
Reference in New Issue
Block a user