feat(api): add GetClientIP to track connected clients (#4)

This commit is contained in:
Dolly
2026-08-01 08:43:02 +02:00
committed by GitHub
parent d90bc0f501
commit 5984a056de
5 changed files with 73 additions and 0 deletions
@@ -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
+5
View File
@@ -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);
+2
View File
@@ -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;
+62
View File
@@ -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}
}; };
+1
View File
@@ -58,6 +58,7 @@ struct CSocketConnect
{ {
CAsyncSocketContext *pSocketContext; CAsyncSocketContext *pSocketContext;
uv_stream_t *pClientSocket; uv_stream_t *pClientSocket;
char *pClientIP;
}; };
struct CSocketData struct CSocketData