Skip to content
Merged
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
16 changes: 16 additions & 0 deletions scripting/include/websocket/ws.inc
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,22 @@ methodmap WebSocketServer < Handle
*/
public native bool SendMessageToClient(const char[] clientId, const char[] message);

/**
* Forcibly disconnect client from websocket
*
* @param clientId client id
*/
public native bool DisconnectClient(const char[] clientId);

/**
* Get handles for all connected clients
*
* @param buffer Array to store client handles
* @param maxSize Maximum size of the array
* @return Number of handles stored
*/
public native int GetClients(WebSocket[] buffer, int maxSize);

/**
* Start the WebSocket server
*/
Expand Down
2 changes: 1 addition & 1 deletion src/smsdk_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define SMEXT_CONF_NAME "SourceMod WebSocket Extension"
#define SMEXT_CONF_DESCRIPTION "Provide JSON and WebSocket Native"
#define SMEXT_CONF_VERSION "1.0.3"
#define SMEXT_CONF_VERSION "1.0.4"
#define SMEXT_CONF_AUTHOR "ProjectSky"
#define SMEXT_CONF_URL "https://github.com/ProjectSky/sm-ext-websocket"
#define SMEXT_CONF_LOGTAG "websocket"
Expand Down
56 changes: 54 additions & 2 deletions src/ws_natives_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,21 @@ static cell_t ws_SendMessageToClient(IPluginContext *pContext, const cell_t *par
return pWebsocketServer->sendToClient(clientId, msg);
}

static cell_t ws_DisconnectClient(IPluginContext *pContext, const cell_t *params)
{
WebSocketServer* pWebsocketServer = GetWsServerPointer(pContext, params[1]);

if (!pWebsocketServer)
{
return 0;
}

char *clientId;
pContext->LocalToString(params[2], &clientId);

return pWebsocketServer->disconnectClient(clientId);
}

static cell_t ws_BroadcastMessage(IPluginContext *pContext, const cell_t *params)
{
WebSocketServer* pWebsocketServer = GetWsServerPointer(pContext, params[1]);
Expand Down Expand Up @@ -250,8 +265,44 @@ static cell_t ws_IsDeflateEnabled(IPluginContext *pContext, const cell_t *params

static cell_t ws_GetClients(IPluginContext *pContext, const cell_t *params)
{
// TODO: Implement
return 1;
WebSocketServer *pWebsocketServer = GetWsServerPointer(pContext, params[1]);

if (!pWebsocketServer)
{
return 0;
}

cell_t *outputArray;
pContext->LocalToPhysAddr(params[2], &outputArray);
cell_t maxSize = params[3];

auto clients = pWebsocketServer->m_webSocketServer.getClients();
size_t count = 0;

HandleSecurity sec(nullptr, myself->GetIdentity());

for (const auto &client : clients)
{
if (count >= maxSize)
break;

WebSocketClient *pClient = new WebSocketClient(client.first.get());
HandleError err;
Handle_t handle = handlesys->CreateHandleEx(g_htWsClient, pClient, &sec, nullptr, &err);

if (handle != BAD_HANDLE)
{
pClient->m_websocket_handle = handle;
pClient->m_keepConnecting = true;
outputArray[count++] = handle;
}
else
{
delete pClient;
}
}

return count;
}

const sp_nativeinfo_t ws_natives_server[] =
Expand All @@ -265,6 +316,7 @@ const sp_nativeinfo_t ws_natives_server[] =
{"WebSocketServer.Stop", ws_Stop},
{"WebSocketServer.BroadcastMessage", ws_BroadcastMessage},
{"WebSocketServer.SendMessageToClient", ws_SendMessageToClient},
{"WebSocketServer.DisconnectClient", ws_DisconnectClient},
{"WebSocketServer.ClientsCount.get", ws_GetClientsCount},
{"WebSocketServer.EnablePong.get", ws_SetOrGetPongEnable},
{"WebSocketServer.EnablePong.set", ws_SetOrGetPongEnable},
Expand Down
13 changes: 13 additions & 0 deletions src/ws_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,17 @@ bool WebSocketServer::sendToClient(const std::string& clientId, const std::strin
}
}
return false;
}

bool WebSocketServer::disconnectClient(const std::string& clientId) {
auto clients = m_webSocketServer.getClients();

for (const auto& client : clients)
{
if (client.second == clientId) {
client.first->stop();
return true;
}
}
return false;
}
1 change: 1 addition & 0 deletions src/ws_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class WebSocketServer
void OnError(ix::WebSocketErrorInfo errorInfo, std::shared_ptr<ix::ConnectionState> connectionState);
void broadcastMessage(const std::string& message);
bool sendToClient(const std::string& clientId, const std::string& message);
bool disconnectClient(const std::string& clientId);

ix::WebSocketServer m_webSocketServer;
Handle_t m_webSocketServer_handle = BAD_HANDLE;
Expand Down