12-25-2025, 06:51 PM
Enet .h file
QBLive_UI.h
QBLive_Server.h
QBLive_Client.h
Qb64 Side Server
QB64 side Client
It'll be work but now hopefully you get no virus reports!
John
QBLive_UI.h
Code: (Select All)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <commctrl.h>
#include <process.h>
#include <cstdint>
#include <string>
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "user32.lib")
// --- UI CONSTANTS ---
#define IDC_PORT_LABEL 1000
#define IDC_PORT_EDIT 1001
#define IDC_BTN_START 1002
#define IDC_BTN_STOP 1003
#define IDC_LIST_CLIENTS 1004
#define IDC_BTN_KICK 1005
#define IDC_CHK_REUSE 1006
#define IDC_STATUS_BAR 1007
// --- GLOBAL HANDLES ---
HWND hMainDlg = NULL;
HWND hClientList = NULL;
typedef void (__stdcall *UI_EVENT_CALLBACK)(int32_t action, const char* data);
UI_EVENT_CALLBACK g_EventCallback = nullptr;
// --- DYNAMIC DIALOG TEMPLATE HELPER ---
// This builds the window structure in memory (VB6 style layout)
void BuildServerUI(HWND hwnd) {
// Port Label and Input
CreateWindowEx(0, "STATIC", "Server Port:", WS_CHILD | WS_VISIBLE, 10, 15, 80, 20, hwnd, (HMENU)IDC_PORT_LABEL, NULL, NULL);
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "12347", WS_CHILD | WS_VISIBLE | ES_NUMBER, 90, 12, 60, 22, hwnd, (HMENU)IDC_PORT_EDIT, NULL, NULL);
// Options
CreateWindowEx(0, "BUTTON", "Auto-Reuse Port", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 160, 15, 120, 20, hwnd, (HMENU)IDC_CHK_REUSE, NULL, NULL);
SendMessage(GetDlgItem(hwnd, IDC_CHK_REUSE), BM_SETCHECK, BST_CHECKED, 0);
// Action Buttons
CreateWindowEx(0, "BUTTON", "START SERVER", WS_CHILD | WS_VISIBLE, 10, 50, 130, 35, hwnd, (HMENU)IDC_BTN_START, NULL, NULL);
CreateWindowEx(0, "BUTTON", "STOP SERVER", WS_CHILD | WS_VISIBLE, 150, 50, 130, 35, hwnd, (HMENU)IDC_BTN_STOP, NULL, NULL);
// Client List
CreateWindowEx(0, "STATIC", "Active Clients:", WS_CHILD | WS_VISIBLE, 10, 100, 100, 20, hwnd, NULL, NULL, NULL);
hClientList = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_NOTIFY, 10, 120, 270, 150, hwnd, (HMENU)IDC_LIST_CLIENTS, NULL, NULL);
// Management
CreateWindowEx(0, "BUTTON", "KICK SELECTED", WS_CHILD | WS_VISIBLE, 10, 280, 270, 30, hwnd, (HMENU)IDC_BTN_KICK, NULL, NULL);
// Status Bar
CreateWindowEx(0, "STATIC", "STATUS: IDLE", WS_CHILD | WS_VISIBLE | SS_SUNKEN, 0, 320, 300, 20, hwnd, (HMENU)IDC_STATUS_BAR, NULL, NULL);
}
// --- WINDOW PROCEDURE ---
LRESULT CALLBACK ServerWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
BuildServerUI(hwnd);
return 0;
case WM_COMMAND:
if (g_EventCallback) {
int wmId = LOWORD(wParam);
if (wmId == IDC_BTN_START) {
char buf[10];
GetWindowText(GetDlgItem(hwnd, IDC_PORT_EDIT), buf, 10);
SetWindowText(GetDlgItem(hwnd, IDC_STATUS_BAR), "STATUS: RUNNING");
g_EventCallback(1, buf); // Action 1: Start
}
if (wmId == IDC_BTN_STOP) {
SetWindowText(GetDlgItem(hwnd, IDC_STATUS_BAR), "STATUS: STOPPED");
g_EventCallback(0, ""); // Action 0: Stop
}
if (wmId == IDC_BTN_KICK) {
int sel = (int)SendMessage(hClientList, LB_GETCURSEL, 0, 0);
if (sel != LB_ERR) {
char name[32];
SendMessage(hClientList, LB_GETTEXT, sel, (LPARAM)name);
g_EventCallback(2, name); // Action 2: Kick
}
}
}
return 0;
case WM_CLOSE:
hMainDlg = NULL;
DestroyWindow(hwnd);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
// --- BACKGROUND UI THREAD ---
void UI_Thread_Proc(void* param) {
WNDCLASS wc = { 0 };
wc.lpfnWndProc = ServerWndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszClassName = "QBLive_Admin_UI";
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
hMainDlg = CreateWindowEx(WS_EX_TOPMOST, wc.lpszClassName, "QBLive S-Tier Admin Panel", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 310, 380, NULL, NULL, wc.hInstance, NULL);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// --- EXPORTED FUNCTIONS ---
extern "C" {
__declspec(dllexport) void UI_Show(uintptr_t callback) {
if (!hMainDlg) {
g_EventCallback = (UI_EVENT_CALLBACK)callback;
_beginthread(UI_Thread_Proc, 0, NULL);
}
}
__declspec(dllexport) void UI_UpdateList(const char* name, int action) {
if (!hClientList) return;
if (action == 1) SendMessage(hClientList, LB_ADDSTRING, 0, (LPARAM)name); // 1 = Add
else if (action == 0) { // 0 = Remove
int idx = (int)SendMessage(hClientList, LB_FINDSTRINGEXACT, -1, (LPARAM)name);
if (idx != LB_ERR) SendMessage(hClientList, LB_DELETESTRING, idx, 0);
}
}
}
QBLive_Server.h
Code: (Select All)
#ifndef QBLIVE_SERVER_H
#define QBLIVE_SERVER_H
#define ENET_IMPLEMENTATION
#include <winsock2.h>
#include <windows.h>
#include <commctrl.h>
#include <string>
#include <cstdio>
#include "enet.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
// IDs for UI Controls
#define ID_BTN_START 101
#define ID_BTN_STOP 102
#define ID_BTN_KICK 104
#define IDM_EXIT 203
#define ID_STATE_TEXT 301
#define ID_EDIT_PORT 401
#define ID_LIST_CLIENTS 501
// Global Handles
static HWND g_hStateLabel = NULL;
static HWND g_hPortEdit = NULL;
static HWND g_hClientList = NULL;
static ENetHost* g_Server = NULL;
static int g_LastStartedPort = 7777;
static char g_LastPacketData[1024] = { 0 };
// Helper: Find the index of a client in the listbox by their ENetPeer pointer
static int FindClientIndex(ENetPeer* peer) {
int count = (int)SendMessage(g_hClientList, LB_GETCOUNT, 0, 0);
for (int i = 0; i < count; i++) {
if ((ENetPeer*)SendMessage(g_hClientList, LB_GETITEMDATA, i, 0) == peer) return i;
}
return -1;
}
// Helper: Get Public IP using Curl
std:
tring GetGlobalIP_Clean() {
char buffer[128];
std:
tring result = "";
FILE* pipe = _popen("curl -4 -s ifconfig.me", "r");
if (!pipe) return "0.0.0.0";
if (fgets(buffer, sizeof(buffer), pipe) != NULL) result = buffer;
_pclose(pipe);
if (result.length() < 7) return "127.0.0.1";
result.erase(result.find_last_not_of(" \n\r\t") + 1);
return result;
}
// Helper: Update the main status text
void RefreshStatusUI(const char* status, const char* ip, int port) {
if (!g_hStateLabel) return;
std:
tring info = "Status: " + std:
tring(status) +
"\nPublic IP: " + std:
tring(ip) +
"\nPort: " + std::to_string(port) +
"\nClients: " + (g_Server ? std::to_string(g_Server->connectedPeers) : "0");
SetWindowText(g_hStateLabel, info.c_str());
}
// Main Window Logic
static LRESULT CALLBACK MyWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_BTN_START:
if (!g_Server) {
char portBuf[10];
GetWindowText(g_hPortEdit, portBuf, 10);
int userPort = atoi(portBuf);
if (userPort <= 0) { userPort = 7777; SetWindowText(g_hPortEdit, "7777"); }
g_LastStartedPort = userPort;
if (enet_initialize() == 0) {
ENetAddress addr;
addr.host = ENET_HOST_ANY;
addr.port = (enet_uint16)userPort;
g_Server = enet_host_create(&addr, 32, 2, 0, 0);
if (g_Server) RefreshStatusUI("Running", GetGlobalIP_Clean().c_str(), userPort);
}
}
break;
case ID_BTN_STOP:
if (g_Server) {
for (size_t i = 0; i < g_Server->peerCount; ++i) {
if (g_Server->peers[i].state == ENET_PEER_STATE_CONNECTED) {
enet_peer_disconnect(&g_Server->peers[i], 500);
}
}
enet_host_flush(g_Server);
Sleep(100);
SendMessage(g_hClientList, LB_RESETCONTENT, 0, 0);
enet_host_destroy(g_Server);
g_Server = NULL;
enet_deinitialize();
RefreshStatusUI("Stopped", "---", 0);
}
break;
case ID_BTN_KICK: {
int sel = (int)SendMessage(g_hClientList, LB_GETCURSEL, 0, 0);
if (sel != LB_ERR) {
ENetPeer* peer = (ENetPeer*)SendMessage(g_hClientList, LB_GETITEMDATA, sel, 0);
if (peer) enet_peer_disconnect(peer, 403);
}
break;
}
case IDM_EXIT:
PostQuitMessage(0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
extern "C" {
__declspec(dllexport) void InitServerUI() {
HINSTANCE hInst = GetModuleHandle(NULL);
WNDCLASS wc = { 0 };
wc.lpfnWndProc = MyWinProc; wc.hInstance = hInst; wc.lpszClassName = "QBLiveClass";
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND main = CreateWindowEx(0, "QBLiveClass", "QBLive Server 2025",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hInst, NULL);
CreateWindow("BUTTON", "Start", WS_VISIBLE | WS_CHILD, 20, 20, 80, 30, main, (HMENU)ID_BTN_START, hInst, NULL);
CreateWindow("BUTTON", "Stop", WS_VISIBLE | WS_CHILD, 110, 20, 80, 30, main, (HMENU)ID_BTN_STOP, hInst, NULL);
CreateWindow("BUTTON", "Kick Selected", WS_VISIBLE | WS_CHILD, 450, 20, 120, 30, main, (HMENU)ID_BTN_KICK, hInst, NULL);
CreateWindow("STATIC", "Port:", WS_VISIBLE | WS_CHILD, 210, 25, 40, 20, main, NULL, hInst, NULL);
g_hPortEdit = CreateWindow("EDIT", "7777", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_NUMBER, 255, 22, 60, 25, main, (HMENU)ID_EDIT_PORT, hInst, NULL);
CreateWindow("STATIC", "Connected Clients:", WS_VISIBLE | WS_CHILD, 450, 60, 150, 20, main, NULL, hInst, NULL);
g_hClientList = CreateWindow("LISTBOX", NULL, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, 450, 80, 300, 400, main, (HMENU)ID_LIST_CLIENTS, hInst, NULL);
g_hStateLabel = CreateWindow("STATIC", "Status: Ready", WS_VISIBLE | WS_CHILD, 20, 80, 400, 150, main, (HMENU)ID_STATE_TEXT, hInst, NULL);
}
__declspec(dllexport) void ProcessWindowEvents() {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); }
if (g_Server) {
ENetEvent event;
while (enet_host_service(g_Server, &event, 0) > 0) {
char ip[64];
enet_address_get_host_ip(&event.peer->address, ip, 64);
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
std:
tring entry = "IP: " + std:
tring(ip);
int idx = (int)SendMessage(g_hClientList, LB_ADDSTRING, 0, (LPARAM)entry.c_str());
SendMessage(g_hClientList, LB_SETITEMDATA, idx, (LPARAM)event.peer);
RefreshStatusUI("Running", "Active", g_LastStartedPort);
break;
}
case ENET_EVENT_TYPE_DISCONNECT: {
int idx = FindClientIndex(event.peer);
if (idx != -1) SendMessage(g_hClientList, LB_DELETESTRING, idx, 0);
RefreshStatusUI("Running", "Active", g_LastStartedPort);
break;
}
case ENET_EVENT_TYPE_RECEIVE:
strncpy(g_LastPacketData, (char*)event.packet->data, 1024);
enet_packet_destroy(event.packet);
break;
default: break;
}
}
}
}
__declspec(dllexport) int UDP_Has_Message() { return (g_LastPacketData[0] != '\0'); }
__declspec(dllexport) void UDP_Get_Message(char* buffer) { strcpy(buffer, g_LastPacketData); g_LastPacketData[0] = '\0'; }
}
#endif
QBLive_Client.h
Code: (Select All)
#ifndef QBLIVE_CLIENT_H
#define QBLIVE_CLIENT_H
#define ENET_IMPLEMENTATION
#include <winsock2.h>
#include <windows.h>
#include <string>
#include "enet.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
static ENetHost* g_ClientHost = NULL;
static ENetPeer* g_ServerPeer = NULL;
extern "C" {
__declspec(dllexport) int InitClient(const char* ip, int port) {
if (enet_initialize() != 0) return -1;
g_ClientHost = enet_host_create(NULL, 1, 2, 0, 0);
if (!g_ClientHost) return -2;
ENetAddress address;
enet_address_set_host(&address, ip);
address.port = (enet_uint16)port;
g_ServerPeer = enet_host_connect(g_ClientHost, &address, 2, 0);
return (g_ServerPeer) ? 0 : -3;
}
// UPDATED: Now returns 1=Connect, 2=Data, 3=Normal Disconnect, 403=Kicked, 500=Server Off
__declspec(dllexport) int UpdateClient() {
if (!g_ClientHost) return -1;
ENetEvent event;
while (enet_host_service(g_ClientHost, &event, 0) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: return 1;
case ENET_EVENT_TYPE_RECEIVE: enet_packet_destroy(event.packet); return 2;
case ENET_EVENT_TYPE_DISCONNECT:
// Check the data code the server sent us
if (event.data == 403) return 403;
if (event.data == 500) return 500;
return 3; // Generic disconnect
default: break;
}
}
return 0;
}
__declspec(dllexport) void ClientSendMessage(const char* msg) {
if (!g_ServerPeer) return;
ENetPacket* packet = enet_packet_create(msg, strlen(msg) + 1, ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(g_ServerPeer, 0, packet);
enet_host_flush(g_ClientHost);
}
__declspec(dllexport) void ShutdownClient() {
if (g_ServerPeer) enet_peer_disconnect_now(g_ServerPeer, 0);
if (g_ClientHost) enet_host_destroy(g_ClientHost);
enet_deinitialize();
}
}
#endif
Qb64 Side Server
Code: (Select All)
DECLARE LIBRARY "QBLive_Server"
SUB InitServerUI ()
SUB ProcessWindowEvents ()
FUNCTION UDP_Has_Message& ()
SUB UDP_Get_Message (buffer AS STRING)
END DECLARE
InitServerUI
DO
ProcessWindowEvents
IF UDP_Has_Message THEN
DIM m AS STRING * 1024
UDP_Get_Message m
PRINT "Message: "; m
END IF
_LIMIT 60
LOOP UNTIL _EXIT
QB64 side Client
Code: (Select All)
' QB64 Client Application
DECLARE LIBRARY "QBLive_Client"
FUNCTION InitClient& (ip AS STRING, BYVAL port AS LONG)
FUNCTION UpdateClient& ()
SUB ClientSendMessage (msg AS STRING)
SUB ShutdownClient ()
END DECLARE
PRINT "Connecting to QBLive Server..."
res& = InitClient("127.0.0.1" + CHR$(0), 7777)
IF res& < 0 THEN
PRINT "Failed to initialize client! Error:"; res&
END
END IF
isConnected = 0
DO
status& = UpdateClient
SELECT CASE status&
CASE 1: PRINT "Connected!"
CASE 3: PRINT "Disconnected from server.": END
CASE 403: PRINT "YOU HAVE BEEN KICKED!": END
CASE 500: PRINT "SERVER SHUTDOWN!": END
END SELECT
_LIMIT 60
LOOP UNTIL _EXIT
ShutdownClient
SYSTEM
It'll be work but now hopefully you get no virus reports!
John

