Initial commit

This commit is contained in:
mykola2312 2020-01-25 10:01:58 +02:00
commit 633f20d561
46 changed files with 2484 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*.obj
*.sdf
*.suo
*.opensdf
ipch/
masterlist/
serverbrowser/

1
README.md Normal file
View file

@ -0,0 +1 @@
# servertool

42
serverbrowser.sln Normal file
View file

@ -0,0 +1,42 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverbrowser", "serverbrowser\serverbrowser.vcxproj", "{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "servertool", "servertool\servertool.vcxproj", "{FF615871-8561-4F2E-9307-9CEA2E7BE381}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "masterlist", "masterlist\masterlist.vcxproj", "{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Debug|Win32.ActiveCfg = Release|Win32
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Debug|Win32.Build.0 = Release|Win32
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Debug|x64.ActiveCfg = Debug|x64
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Debug|x64.Build.0 = Debug|x64
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Release|Win32.ActiveCfg = Release|Win32
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Release|Win32.Build.0 = Release|Win32
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Release|x64.ActiveCfg = Release|x64
{4CAC26DD-5286-43A0-8C9C-60CB1B9613FE}.Release|x64.Build.0 = Release|x64
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Debug|Win32.ActiveCfg = Debug|Win32
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Debug|Win32.Build.0 = Debug|Win32
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Debug|x64.ActiveCfg = Debug|Win32
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Release|Win32.ActiveCfg = Release|Win32
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Release|Win32.Build.0 = Release|Win32
{FF615871-8561-4F2E-9307-9CEA2E7BE381}.Release|x64.ActiveCfg = Release|x64
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Debug|Win32.ActiveCfg = Debug|Win32
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Debug|Win32.Build.0 = Debug|Win32
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Debug|x64.ActiveCfg = Debug|Win32
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Release|Win32.ActiveCfg = Release|Win32
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Release|Win32.Build.0 = Release|Win32
{84DA515D-A7E8-4A95-A3A6-B45BEB09FA6E}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

BIN
servertool/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
servertool/icon16.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

51
servertool/main.c Normal file
View file

@ -0,0 +1,51 @@
#include "servertool.h"
#include "serverlist.h"
#include "masterscan.h"
#include "serverinfo.h"
#include "resource.h"
#include <CommCtrl.h>
APPLICATION_T g_App;
INT APIENTRY wWinMain(HINSTANCE hInst,HINSTANCE hPrevInst,
LPWSTR lpCmdLine,INT nCmdShow)
{
WSADATA WSA;
MSG Msg;
g_App.hInst = hInst;
g_App.nCmdShow = nCmdShow;
//Load stuff
InitCommonControls();
g_App.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1));
g_App.hIconSm = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON2));
//Init WSA
WSAStartup(MAKEWORD(2,2),&WSA);
//Register windows
InitServerListWindow();
InitMasterScanWindow();
InitServerInfoWindow();
//Do something
CreateServerListWindow();
//CreateMasterScanPopup();
//Main loop
while(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
WSACleanup();
return (INT)Msg.wParam;
}

1
servertool/master.dat Normal file
View file

@ -0,0 +1 @@
Ð@È4i„Ð@È'iƒÐ@ÈAi‡Ð@ÈAiƒÐ@È4iƒÐ@È'i„

230
servertool/masterscan.c Normal file
View file

@ -0,0 +1,230 @@
#include "masterscan.h"
#include <CommCtrl.h>
MASTERSCAN_WINDOW_T g_MasterScan;
static INT iWidth = 400;
static INT iHeight = 350;
static LRESULT CALLBACK WndCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID InitMasterScanWindow()
{
WNDCLASSEX wndClass;
g_MasterScan.lpClass = MASTERSCAN_CLASS;
ZeroMemory(&wndClass,sizeof(WNDCLASSEX));
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.lpszClassName = g_MasterScan.lpClass;
wndClass.hInstance = g_App.hInst;
wndClass.lpfnWndProc = WndCallback;
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.hIcon = g_App.hIcon;
wndClass.hIconSm = g_App.hIconSm;
RegisterClassEx(&wndClass);
}
VOID CreateMasterScanWindow()
{
g_MasterScan.IsPopup = FALSE;
g_MasterScan.hWnd = CreateWindow(MASTERSCAN_CLASS,L"Master servers",
WINDOW_STYLE,CW_USEDEFAULT,CW_USEDEFAULT,
iWidth,iHeight,NULL,NULL,g_App.hInst,NULL);
ShowWindow(g_MasterScan.hWnd,g_App.nCmdShow);
UpdateWindow(g_MasterScan.hWnd);
}
VOID CreateMasterScanPopup()
{
//CreateMasterScanWindow();
//SetWindowPos(g_MasterScan.hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
g_MasterScan.IsPopup = TRUE;
g_MasterScan.hWnd = CreateWindowEx(WS_EX_TOPMOST,
MASTERSCAN_CLASS,
L"Master servers [first scan]",
WS_OVERLAPPED|WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,
iWidth,iHeight,g_MasterScan.hParent,NULL,g_App.hInst,NULL);
ShowWindow(g_MasterScan.hWnd,g_App.nCmdShow);
UpdateWindow(g_MasterScan.hWnd);
}
static DWORD WINAPI ScanThread(LPVOID lpArg)
{
//Do some work
//Send message to thread
FindMasterServers((MASTERFINDPARAMETERS_T*)lpArg);
PostMessage(g_MasterScan.hWnd,WM_ENDMASTERSCAN,0,0);
return 0;
}
static VOID AddServer(struct sockaddr_in* addrs)
{
LV_ITEM Item;
WCHAR szText[32];
ZeroMemory(&Item,sizeof(LV_ITEM));
Item.iItem = g_MasterScan.MasterNum;
Item.mask = LVIF_TEXT;
Item.pszText = LPSTR_TEXTCALLBACK;
Item.cchTextMax = 64;
ListView_InsertItem(g_MasterScan.hList,&Item);
MultiByteToWideChar(CP_UTF8,0,inet_ntoa(addrs->sin_addr),-1,szText,32);
ListView_SetItemText(g_MasterScan.hList,Item.iItem,0,szText);
_itow(ntohs(addrs->sin_port),szText,10);
ListView_SetItemText(g_MasterScan.hList,Item.iItem,1,szText);
g_MasterScan.MasterNum++;
SendMessage(g_MasterScan.hProgressBar,PBM_SETPOS,g_MasterScan.MasterNum,0);
}
VOID AddMasterServers()
{
INT i;
INT iSize;
iSize = g_MasterScan.MasterNum;
g_MasterScan.MasterNum = 0;
for(i = 0; i < iSize; i++)
AddServer(&g_MasterScan.addrs[i]);
}
VOID DoMasterScan(LPCSTR lpSearch,HWND hParent)
{
g_MasterScan.hParent = hParent;
CreateMasterScanPopup();
SendMessage(g_MasterScan.hProgressBar,PBM_SETRANGE,0,MAKELPARAM(0,6));
g_MasterScan.MasterNum = 0;
g_MasterScan.ScanParams.addrs = g_MasterScan.addrs;
g_MasterScan.ScanParams.AddServer = AddServer;
//Start thread
g_MasterScan.hScanThread = CreateThread(0,0,ScanThread,&g_MasterScan.ScanParams,0,NULL);
SetWindowText(g_MasterScan.hLabel,L"Scanning..");
}
static VOID AddMaster()
{
WCHAR szText[64];
char szAddr[64];
struct sockaddr_in addr;
GetWindowText(g_MasterScan.hMasterIpEdit,szText,64);
if(wcslen(szText) == 0) return;
WideCharToMultiByte(CP_UTF8,0,szText,-1,szAddr,64,NULL,NULL);
addr.sin_addr.s_addr = inet_addr(szAddr);
GetWindowText(g_MasterScan.hMasterPortEdit,szText,64);
if(wcslen(szText) == 0) return;
addr.sin_port = htons(_wtoi(szText));
SetWindowText(g_MasterScan.hMasterIpEdit,L"");
SetWindowText(g_MasterScan.hMasterPortEdit,L"");
if(g_MasterScan.MasterNum == 32)
{
MessageBox(g_MasterScan.hWnd,
L"Reached limit of master servers!",
L"Error",
MB_ICONERROR);
return;
}
CopyMemory(&g_MasterScan.addrs[g_MasterScan.MasterNum],
&addr,sizeof(struct sockaddr_in));
AddServer(&g_MasterScan.addrs[g_MasterScan.MasterNum]);
}
static HWND CreateListView(LPCREATESTRUCT lpCreate,HWND hParent,INT x,INT y,INT w,INT h)
{
HWND hList;
LV_COLUMN Column;
hList = CreateWindowEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,L"",WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_EDITLABELS,
x,y,w,h,hParent,NULL,lpCreate->hInstance,NULL);
ZeroMemory(&Column,sizeof(LV_COLUMN));
Column.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH;
Column.cx = w-(w/4);
Column.iSubItem = 0;
Column.iOrder = 0;
Column.pszText = L"Address";
ListView_InsertColumn(hList,0,&Column);
Column.cx = w/4;
Column.iSubItem = 1;
Column.iOrder = 1;
Column.pszText = L"Port";
ListView_InsertColumn(hList,1,&Column);
return hList;
}
static LRESULT CALLBACK WndCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LPCREATESTRUCT lpCreate;
switch(Msg)
{
case WM_CREATE:
//Create something
lpCreate = (LPCREATESTRUCT)lParam;
g_MasterScan.hProgressBar = CreateWindow(PROGRESS_CLASS,L"",WS_CHILD|WS_VISIBLE,
6,10,380,20,hWnd,NULL,lpCreate->hInstance,NULL);
g_MasterScan.hLabel = CreateWindow(L"STATIC",L"Status",WS_CHILD|WS_VISIBLE,
6,35,100,20,hWnd,NULL,lpCreate->hInstance,NULL);
g_MasterScan.hList = CreateListView(lpCreate,hWnd,6,50,380,200);
g_MasterScan.hMasterIpEdit = CreateWindowEx(WS_EX_CLIENTEDGE,L"Edit",L"",WS_CHILD|WS_VISIBLE,
6,255,300,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_MasterScan.hMasterPortEdit = CreateWindowEx(WS_EX_CLIENTEDGE,L"Edit",L"",WS_CHILD|WS_VISIBLE,
310,255,76,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_MasterScan.hMasterAddBtn = CreateWindow(L"Button",L"Add master server",WS_CHILD|WS_VISIBLE,
6,285,380,25,hWnd,(HMENU)IDC_MASTERSCAN_ADDMASTER_BTN,lpCreate->hInstance,NULL);
if(!g_MasterScan.IsPopup)
AddMasterServers();
else
{
EnableWindow(g_MasterScan.hMasterIpEdit,FALSE);
EnableWindow(g_MasterScan.hMasterPortEdit,FALSE);
EnableWindow(g_MasterScan.hMasterAddBtn,FALSE);
}
break;
case WM_COMMAND:
//Command
if(LOWORD(wParam) == IDC_MASTERSCAN_ADDMASTER_BTN)
AddMaster();
break;
case WM_ENDMASTERSCAN:
CloseHandle(g_MasterScan.hScanThread);
SendMessage(g_MasterScan.hParent,WM_ENDMASTERSCAN,
g_MasterScan.MasterNum,
(LPARAM)g_MasterScan.addrs);
SetWindowText(g_MasterScan.hLabel,L"Done");
DestroyWindow(hWnd);
break;
case WM_CLOSE:
if(g_MasterScan.IsPopup) return TRUE;
break;
case WM_DESTROY:
break;
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}

37
servertool/masterscan.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef __MASTERSCAN_H
#define __MASTERSCAN_H
#include "servertool.h"
#define MASTERSCAN_CLASS L"ServerTool_MasterScan"
#define IDC_MASTERSCAN_ADDMASTER_BTN 134
typedef struct {
LPCWSTR lpClass;
HWND hParent;
HWND hWnd;
HWND hProgressBar;
HWND hLabel;
HWND hList;
HWND hMasterIpEdit;
HWND hMasterPortEdit;
HWND hMasterAddBtn;
struct sockaddr_in addrs[32];
INT MasterNum;
BOOL IsPopup;
HANDLE hScanThread;
MASTERFINDPARAMETERS_T ScanParams;
} MASTERSCAN_WINDOW_T;
VOID InitMasterScanWindow();
VOID CreateMasterScanWindow();
VOID CreateMasterScanPopup();
VOID DoMasterScan(LPCSTR lpSearch,HWND hParent);
extern MASTERSCAN_WINDOW_T g_MasterScan;
#endif

BIN
servertool/resource.h Normal file

Binary file not shown.

275
servertool/serverinfo.c Normal file
View file

@ -0,0 +1,275 @@
#include "serverinfo.h"
#include <CommCtrl.h>
#include <stdio.h>
#include <stdlib.h>
SERVERINFO_WINDOW_T g_ServerInfo;
static LRESULT CALLBACK WndCallback(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
static INT iWidth = 400;
static INT iHeight = 640;
VOID InitServerInfoWindow()
{
WNDCLASSEX wndClass;
g_ServerInfo.lpClass = SERVERINFO_CLASS;
ZeroMemory(&wndClass,sizeof(WNDCLASSEX));
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.lpszClassName = g_ServerInfo.lpClass;
wndClass.hInstance = g_App.hInst;
wndClass.lpfnWndProc = WndCallback;
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.hIcon = g_App.hIcon;
wndClass.hIconSm = g_App.hIconSm;
RegisterClassEx(&wndClass);
}
VOID CreateServerInfoWindow()
{
g_ServerInfo.hWnd = CreateWindow(SERVERINFO_CLASS,
L"Server-Info",WINDOW_STYLE,
CW_USEDEFAULT,CW_USEDEFAULT,
iWidth,iHeight,NULL,NULL,
g_App.hInst,NULL);
ShowWindow(g_ServerInfo.hWnd,g_App.nCmdShow);
UpdateWindow(g_ServerInfo.hWnd);
}
static VOID AddServer(SERVER_T* Server)
{
static WCHAR szText[1024];
swprintf(szText,1024,
L"Name: %s\r\n"
L"Map: %s\r\n"
L"Game: %s\r\n"
L"Players: %d\r\n"
L"Slots: %d\r\n"
L"Type: %C\r\n"
L"System: %C\r\n"
L"Password: %d\r\n"
L"VAC: %d\r\n",
Server->szName,
Server->szMap,
Server->szGame,
Server->cPlayers,
Server->cMaxPlayers,
Server->cType,
Server->cOS,
Server->cVisibility,
Server->cVAC);
SetWindowText(g_ServerInfo.hInfoBox,szText);
}
static VOID AddPlayer(PCHAR pName,UINT Score,FLOAT Duration)
{
WCHAR szText[64];
LV_ITEM Item;
INT Idx;
ULONG Time;
Idx = g_ServerInfo.PlayerNum;
ZeroMemory(&Item,sizeof(Item));
Item.mask = LVIF_TEXT;
Item.pszText = LPSTR_TEXTCALLBACK;
Item.cchTextMax = 64;
Item.iItem = Idx;
Item.iSubItem = 0;
ListView_InsertItem(g_ServerInfo.hPlayerList,&Item);
MultiByteToWideChar(CP_UTF8,0,pName,-1,szText,64);
ListView_SetItemText(g_ServerInfo.hPlayerList,Idx,0,szText);
swprintf(szText,64,L"%u",Score);
ListView_SetItemText(g_ServerInfo.hPlayerList,Idx,1,szText);
Time = (ULONG)Duration;
swprintf(szText,64,L"%02u:%02u:%02u",Time/3600,(Time/60)%60,Time%60);
ListView_SetItemText(g_ServerInfo.hPlayerList,Idx,2,szText);
g_ServerInfo.PlayerNum++;
}
static VOID AddRule(PCHAR pName,PCHAR pValue)
{
WCHAR szText[MAX_PATH];
LV_ITEM Item;
INT Idx;
Idx = g_ServerInfo.RuleNum;
ZeroMemory(&Item,sizeof(Item));
Item.mask = LVIF_TEXT;
Item.pszText = LPSTR_TEXTCALLBACK;
Item.cchTextMax = 64;
Item.iItem = Idx;
Item.iSubItem = 0;
ListView_InsertItem(g_ServerInfo.hRuleList,&Item);
MultiByteToWideChar(CP_UTF8,0,pName,-1,szText,MAX_PATH);
ListView_SetItemText(g_ServerInfo.hRuleList,Idx,0,szText);
MultiByteToWideChar(CP_UTF8,0,pValue,-1,szText,MAX_PATH);
ListView_SetItemText(g_ServerInfo.hRuleList,Idx,1,szText);
g_ServerInfo.RuleNum++;
}
static DWORD WINAPI RequestThread(LPVOID lpArg)
{
GetServerInfo((NETADR_T*)lpArg,AddServer,AddPlayer,AddRule);
PostMessage(g_ServerInfo.hWnd,WM_ENDSERVERINFOREQUEST,0,0);
return 0;
}
static VOID RequestServerInfo()
{
WCHAR szText[64];
char szAddr[32];
PWCHAR pDel;
NETADR_T Addr;
g_ServerInfo.PlayerNum = 0;
g_ServerInfo.RuleNum = 0;
SetWindowText(g_ServerInfo.hInfoBox,L"");
ListView_DeleteAllItems(g_ServerInfo.hPlayerList);
ListView_DeleteAllItems(g_ServerInfo.hRuleList);
if(g_ServerInfo.hRequestThread)
{
TerminateThread(g_ServerInfo.hRequestThread,0);
CloseHandle(g_ServerInfo.hRequestThread);
}
GetWindowText(g_ServerInfo.hAddressEdit,szText,32);
pDel = wcschr(szText,L':');
if(!pDel) return;
*pDel = L'\0';
WideCharToMultiByte(CP_UTF8,0,szText,-1,szAddr,32,NULL,NULL);
Addr.sin_addr.s_addr = inet_addr(szAddr);
Addr.sin_port = htons(_wtoi(pDel+1));
g_ServerInfo.hRequestThread = CreateThread(NULL,0,RequestThread,&Addr,0,NULL);
SetWindowText(g_ServerInfo.hRequestBtn,L"Wait..");
}
VOID EndServerInfoRequest()
{
SetWindowText(g_ServerInfo.hRequestBtn,L"Request");
CloseHandle(g_ServerInfo.hRequestThread);
g_ServerInfo.hRequestThread = NULL;
}
static HWND CreatePlayerList(LPCREATESTRUCT lpCreate,HWND hParent,INT x,INT y)
{
HWND hList;
LV_COLUMN Column;
hList = CreateWindowEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,L"",
WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_EDITLABELS,x,y,380,150,
hParent,NULL,lpCreate->hInstance,NULL);
ZeroMemory(&Column,sizeof(Column));
Column.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
Column.iOrder = 0;
Column.iSubItem = 0;
Column.cx = 190;
Column.pszText = L"Name";
ListView_InsertColumn(hList,0,&Column);
Column.iOrder = 1;
Column.iSubItem = 1;
Column.cx = 95;
Column.pszText = L"Score";
ListView_InsertColumn(hList,1,&Column);
Column.iOrder = 2;
Column.iSubItem = 2;
Column.cx = 90;
Column.pszText = L"Time";
ListView_InsertColumn(hList,2,&Column);
return hList;
}
static HWND CreateRulesList(LPCREATESTRUCT lpCreate,HWND hParent,INT x,INT y)
{
HWND hList;
LV_COLUMN Column;
hList = CreateWindowEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,L"",
WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_EDITLABELS,x,y,380,170,
hParent,NULL,lpCreate->hInstance,NULL);
ZeroMemory(&Column,sizeof(Column));
Column.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
Column.iOrder = 0;
Column.iSubItem = 0;
Column.cx = 140;
Column.pszText = L"Name";
ListView_InsertColumn(hList,0,&Column);
Column.iOrder = 1;
Column.iSubItem = 1;
Column.cx = 235;
Column.pszText = L"Value";
ListView_InsertColumn(hList,1,&Column);
return hList;
}
static LRESULT CALLBACK WndCallback(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
LPCREATESTRUCT lpCreate;
switch(Msg)
{
case WM_CREATE:
lpCreate = (LPCREATESTRUCT)lParam;
g_ServerInfo.hAddressEdit = CreateWindowEx(WS_EX_CLIENTEDGE,L"Edit",L"Address:Port",
WS_CHILD|WS_VISIBLE,6,10,280,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_ServerInfo.hRequestBtn = CreateWindow(L"Button",L"Request",WS_CHILD|WS_VISIBLE,
295,10,92,25,hWnd,(HMENU)IDC_SERVERINFO_REQUEST_BTN,lpCreate->hInstance,NULL);
g_ServerInfo.hInfoBox = CreateWindowEx(WS_EX_CLIENTEDGE,L"Edit",L"",
WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE|ES_AUTOVSCROLL|ES_LEFT,
6,40,380,200,hWnd,NULL,lpCreate->hInstance,NULL);
CreateWindow(L"STATIC",L"Players",WS_CHILD|WS_VISIBLE,
6,245,100,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_ServerInfo.hPlayerList = CreatePlayerList(lpCreate,hWnd,6,275);
CreateWindow(L"STATIC",L"Server's ConVar (FCVAR_NOTIFY)",
WS_CHILD|WS_VISIBLE,6,405,380,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_ServerInfo.hRuleList = CreateRulesList(lpCreate,hWnd,6,435);
g_ServerInfo.PlayerNum = 0;
g_ServerInfo.RuleNum = 0;
break;
case WM_COMMAND:
if(LOWORD(wParam) == IDC_SERVERINFO_REQUEST_BTN)
RequestServerInfo();
break;
case WM_ENDSERVERINFOREQUEST:
EndServerInfoRequest();
break;
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}

31
servertool/serverinfo.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef __SERVERINFO_H
#define __SERVERINFO_H
#include "servertool.h"
#define SERVERINFO_CLASS L"ServerTool_ServerInfo"
#define IDC_SERVERINFO_REQUEST_BTN 135
typedef struct {
LPCWSTR lpClass;
HWND hWnd;
HWND hAddressEdit;
HWND hRequestBtn;
HWND hInfoBox;
HWND hPlayerList;
HWND hRuleList;
INT PlayerNum;
INT RuleNum;
HANDLE hRequestThread;
} SERVERINFO_WINDOW_T;
VOID InitServerInfoWindow();
VOID CreateServerInfoWindow();
extern SERVERINFO_WINDOW_T g_ServerInfo;
#endif

611
servertool/serverlist.c Normal file
View file

@ -0,0 +1,611 @@
#include "serverlist.h"
#include "masterscan.h"
#include "serverinfo.h"
#include <CommCtrl.h>
#include <stdio.h>
#include <stdlib.h>
SERVERLIST_WINDOW_T g_ServerList;
static INT iWidth = 1072;
static INT iHeight = 600;
static LRESULT CALLBACK WndCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID InitServerListWindow()
{
WNDCLASSEX wndClass;
g_ServerList.lpClass = SERVERLIST_CLASS;
ZeroMemory(&wndClass,sizeof(WNDCLASSEX));
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.lpszClassName = g_ServerList.lpClass;
wndClass.hInstance = g_App.hInst;
wndClass.lpfnWndProc = WndCallback;
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.hIcon = g_App.hIcon;
wndClass.hIconSm = g_App.hIconSm;
RegisterClassEx(&wndClass);
}
VOID CreateServerListWindow()
{
g_ServerList.hWnd = CreateWindow(SERVERLIST_CLASS,L"ServerList",
WINDOW_STYLE,CW_USEDEFAULT,CW_USEDEFAULT,
iWidth,iHeight,NULL,NULL,g_App.hInst,NULL);
ShowWindow(g_ServerList.hWnd,g_App.nCmdShow);
UpdateWindow(g_ServerList.hWnd);
}
static VOID StartMasterScan(HWND hParent)
{
DoMasterScan("\\appid\\320",hParent);
}
static VOID LoadMasterServers(HWND hParent)
{
HANDLE hFile;
LARGE_INTEGER size;
NETADR_T Addr;
DWORD dwRead;
INT i;
hFile = CreateFile(L"master.dat",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
StartMasterScan(hParent);
return;
}
GetFileSizeEx(hFile,&size);
g_ServerList.MasterNum = (INT)(size.QuadPart/sizeof(NETADR_T));
if(g_ServerList.MasterNum > 32)
g_ServerList.MasterNum = 32;
g_MasterScan.MasterNum = g_ServerList.MasterNum;
for(i = 0; i < g_ServerList.MasterNum; i++)
{
ReadFile(hFile,&Addr,sizeof(NETADR_T),&dwRead,NULL);
g_ServerList.Masters[i].Conn.addr.sin_family = AF_INET;
g_ServerList.Masters[i].Conn.addr.sin_addr = Addr.sin_addr;
g_ServerList.Masters[i].Conn.addr.sin_port = Addr.sin_port;
g_MasterScan.addrs[i].sin_family = AF_INET;
g_MasterScan.addrs[i].sin_addr = Addr.sin_addr;
g_MasterScan.addrs[i].sin_port = Addr.sin_port;
}
CloseHandle(hFile);
g_ServerList.Params.Masters = g_ServerList.Masters;
g_ServerList.Params.MasterNum = g_ServerList.MasterNum;
g_MasterScan.ScanParams.addrs = g_MasterScan.addrs;
}
static VOID SaveMasters()
{
HANDLE hFile;
NETADR_T Addr;
DWORD dwWrote;
INT i;
hFile = CreateFile(L"master.dat",GENERIC_ALL,0,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
for(i = 0; i < g_ServerList.MasterNum; i++)
{
Addr.sin_addr = g_ServerList.Masters[i].Conn.addr.sin_addr;
Addr.sin_port = g_ServerList.Masters[i].Conn.addr.sin_port;
WriteFile(hFile,&Addr,sizeof(NETADR_T),&dwWrote,NULL);
}
CloseHandle(hFile);
}
static VOID EndMasterScan(WPARAM wParam,LPARAM lParam)
{
INT i;
struct sockaddr_in* addrs;
if(wParam < MAX_MASTER_NUM) //We need 3 master servers at least
{
Sleep(5000);
StartMasterScan(g_ServerList.hWnd);
}
else
{
g_ServerList.MasterNum = (INT)wParam;
addrs = (struct sockaddr_in*)lParam;
for(i = 0; i < g_ServerList.MasterNum; i++)
{
CopyMemory(&g_ServerList.Masters[i].Conn.addr,
&addrs[i],sizeof(struct sockaddr_in));
}
//Save masters to file
SaveMasters();
}
}
static DWORD WINAPI RequestThread(LPVOID lpArg)
{
MASTERREQUESTPARAMETERS_T* Params;
Params = (MASTERREQUESTPARAMETERS_T*)lpArg;
DoMasterServers(Params->Masters,Params->MasterNum,Params->szSearch);
Params->Servers = GetUniqueServers(Params->Masters,Params->MasterNum,&Params->ServerNum);
SendMessage(Params->hParent,WM_ENDMASTERREQUEST,0,(LPARAM)Params);
return 0;
}
VOID MakeMasterServersRequest()
{
WCHAR szRequest[MAX_PATH];
if(g_ServerList.Params.ServerList)
{
free(g_ServerList.Params.ServerList);
g_ServerList.Params.ServerList = NULL;
}
if(g_ServerList.hScanThread)
{
TerminateThread(g_ServerList.hScanThread,0);
CloseHandle(g_ServerList.hScanThread);
g_ServerList.hScanThread = NULL;
}
ListView_DeleteAllItems(g_ServerList.hServerList);
SendMessage(g_ServerList.hProgressBar,PBM_SETPOS,0,0);
ZeroMemory(&g_ServerList.Params,sizeof(g_ServerList.Params));
GetWindowText(g_ServerList.hRequestEdit,szRequest,MAX_PATH);
WideCharToMultiByte(CP_UTF8,0,szRequest,-1,
g_ServerList.Params.szSearch,MAX_PATH,NULL,NULL);
g_ServerList.Params.hParent = g_ServerList.hWnd;
g_ServerList.Params.Masters = g_ServerList.Masters;
g_ServerList.Params.MasterNum = g_ServerList.MasterNum;
g_ServerList.hScanThread = CreateThread(0,0,RequestThread,
&g_ServerList.Params,0,NULL);
SetWindowText(g_ServerList.hLabel,L"Requests to masters..");
SetWindowText(g_ServerList.hRequestBtn,L"Stop");
}
static VOID AddServer(SERVER_T* Server)
{
LV_ITEM Item;
WCHAR szText[64];
char szAddr[64];
LPCWSTR pText;
INT Idx;
ZeroMemory(&Item,sizeof(LV_ITEM));
Idx = g_ServerList.ServerIdx;
Item.mask = LVIF_TEXT;
Item.pszText = LPSTR_TEXTCALLBACK;
Item.iItem = Idx;
ListView_InsertItem(g_ServerList.hServerList,&Item);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,0,Server->szName);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,1,Server->szMap);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,2,Server->szGame);
_itow(Server->cPlayers,szText,10);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,3,szText);
_itow(Server->cMaxPlayers,szText,10);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,4,szText);
switch(Server->cType)
{
case 'd': pText = L"Dedicated"; break;
case 'l': pText = L"Non-Dedic."; break;
case 'p': pText = L"SourceTV"; break;
default:
swprintf(szText,64,L"<%02X>",Server->cType&0xFF);
pText = szText;
}
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,5,(LPWSTR)pText);
switch(Server->cOS)
{
case 'l': pText = L"Linux"; break;
case 'w': pText = L"Windows"; break;
case 'm': pText = L"Mac OS"; break;
default:
swprintf(szText,64,L"<%02X>",Server->cOS&0xFF);
pText = szText;
}
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,6,(LPWSTR)pText);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,7,
Server->cVisibility ? L"Yes" : L"No");
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,8,
Server->cVAC ? L"Yes" : L"No");
sprintf(szAddr,"%s:%d",inet_ntoa(Server->Addr.sin_addr),
ntohs(Server->Addr.sin_port));
MultiByteToWideChar(CP_UTF8,0,szAddr,-1,szText,64);
ListView_SetItemText(g_ServerList.hServerList,Item.iItem,9,szText);
SendMessage(g_ServerList.hProgressBar,PBM_SETPOS,Idx,0);
g_ServerList.ServerIdx++;
}
typedef struct {
UINT Num;
UINT Size;
UINT WaitTime;
} BLOCKPARAMS_T;
static BLOCKPARAMS_T s_BlockSize[] = {
{300,32,2},
{512,128,3},
{1024,256,4},
{2048,512,5},
{4096,1024,7},
{-1,2048,10},
};
static BLOCKPARAMS_T* GetBlockParams(UINT Num)
{
INT i;
i = 0;
while(Num > s_BlockSize[i].Num){i++;}
return &s_BlockSize[i];
}
static DWORD WINAPI QueryThread(LPVOID lpArg)
{
MASTERREQUESTPARAMETERS_T* Params;
BLOCKPARAMS_T* Block;
NETADR_T* AddrPtr;
SERVER_T* ServerPtr;
INT iNum,iRemaind;
INT i;
Params = (MASTERREQUESTPARAMETERS_T*)lpArg;
Block = GetBlockParams(Params->ServerNum);
Params->ServerList = (SERVER_T*)calloc(Params->ServerNum,sizeof(SERVER_T));
ServerPtr = Params->ServerList;
g_ServerList.ServerIdx = 0;
iNum = Params->ServerNum/Block->Size;
iRemaind = Params->ServerNum%Block->Size;
AddrPtr = Params->Servers;
for(i = 0; i < iNum; i++)
{
QueryServers(AddrPtr,ServerPtr,Block->Size,AddServer,Block->WaitTime);
AddrPtr += Block->Size;
ServerPtr += Block->Size;
}
if(iRemaind)
QueryServers(AddrPtr,ServerPtr,iRemaind,AddServer,Block->WaitTime);
PostMessage(g_ServerList.hWnd,WM_ENDQUERYSERVERS,0,0);
return 0;
}
VOID EndMasterRequest()
{
WCHAR szText[64];
CloseHandle(g_ServerList.hScanThread);
swprintf(szText,64,L"Found %d servers. Request..",g_ServerList.Params.ServerNum);
SetWindowText(g_ServerList.hLabel,szText);
SendMessage(g_ServerList.hProgressBar,PBM_SETRANGE,0,MAKELPARAM(0,g_ServerList.Params.ServerNum));
//Query all servers
g_ServerList.hScanThread = CreateThread(0,0,QueryThread,&g_ServerList.Params,0,NULL);
}
VOID EndQueryServers()
{
SetWindowText(g_ServerList.hLabel,L"Done");
free(g_ServerList.Params.Servers);
g_ServerList.hScanThread = NULL;
//ZeroMemory(&g_ServerList.Params,sizeof(g_ServerList.Params));
SendMessage(g_ServerList.hProgressBar,PBM_SETPOS,0,0);
SetWindowText(g_ServerList.hRequestBtn,L"Execute");
}
VOID StopAnyRequests()
{
TerminateThread(g_ServerList.hScanThread,0);
EndQueryServers();
}
typedef struct {
INT iWidth;
LPWSTR lpName;
} COLUMNHDR_T;
static COLUMNHDR_T Columns[] = {
{300,L"Name"},
{100,L"Map"},
{100,L"Game"},
{65,L"Players"},
{65,L"Slots"},
{95,L"Type"},
{80,L"System"},
{60,L"Password"},
{40,L"VAC"},
{150,L"Address"},
};
VOID CreateBar(LPCREATESTRUCT lpCreate,HWND hParent)
{
HMENU hMenuBar,hMenu;
hMenuBar = CreateMenu();
hMenu = CreateMenu();
AppendMenu(hMenu,MF_STRING,IDC_FILE_SAVEAS,L"Save ss..");
AppendMenu(hMenuBar,MF_POPUP,(UINT_PTR)hMenu,L"File");
hMenu = CreateMenu();
AppendMenu(hMenu,MF_STRING,IDC_SERVERS_MASTERS,L"Master servers");
AppendMenu(hMenu,MF_STRING,IDC_SERVERS_QUERY,L"Server-Info");
AppendMenu(hMenuBar,MF_POPUP,(UINT_PTR)hMenu,L"Servers");
hMenu = CreateMenu();
AppendMenu(hMenu,MF_STRING,IDC_HELP_HELP,L"Help");
AppendMenu(hMenu,MF_SEPARATOR,0,NULL);
AppendMenu(hMenu,MF_STRING,IDC_HELP_ABOUT,L"About program");
AppendMenu(hMenuBar,MF_POPUP,(UINT_PTR)hMenu,L"Help");
SetMenu(hParent,hMenuBar);
}
VOID DialogHelp()
{
MessageBox(g_ServerList.hWnd,
L"You must make request like it described here:"
L">>> https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol#Filter\n"
L"\n"
L"Example for Garry's Mod:\n\\appid\\4000\n\n"
L"\\appid\\%SteamAppId ÑÅÐÂÅÐÀ èãðû!!!%\\\n\n",
L"Help",
MB_ICONINFORMATION);
}
VOID DialogAbout()
{
MessageBox(g_ServerList.hWnd,
L"https://github.com/nikolaytihonov/servertool\n"
L"\thttps://steamcommunity.com/id/dominqnta\n"
L"\tDiscord: ISurface030#1470"
L"\n\nAuthor: nikolaytihonov",
L"About",
MB_ICONINFORMATION);
}
#define FILE_1STLINE L"Name\tMap\tGame\tPlayers\tSlots\tType\tSystem\tPassword\tVAC\tAddress\r\n"
VOID SaveServers()
{
HANDLE hFile;
static WCHAR szLine[512];
static WCHAR szPath[MAX_PATH];
static WCHAR szText[64];
static CHAR sz8Line[1024];
char szAddr[32];
PWCHAR pText;
OPENFILENAME ofn;
DWORD dwWrote;
INT i;
ZeroMemory(&ofn,sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = g_ServerList.hWnd;
ofn.lpstrFile = szPath;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = L".TXT";
if(!GetSaveFileName(&ofn))
{
MessageBox(g_ServerList.hWnd,L"Can't save file!",L"Error",MB_ICONERROR);
return;
}
hFile = CreateFile(szPath,GENERIC_ALL,0,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
MessageBox(g_ServerList.hWnd,L"Can't save file!",L"Error",MB_ICONERROR);
return;
}
WideCharToMultiByte(CP_UTF8,0,FILE_1STLINE,-1,sz8Line,sizeof(sz8Line),NULL,NULL);
WriteFile(hFile,sz8Line,(DWORD)strlen(sz8Line)*sizeof(CHAR),&dwWrote,NULL);
for(i = 0; i < g_ServerList.Params.ServerNum; i++)
{
SERVER_T* Server;
//swprintf(szLine,L"%s\t%s\t%s%d\t%d\t%s\t%s\t%s
Server = &g_ServerList.Params.ServerList[i];
if(!Server->IsValid) continue;
wcsncpy(szLine,Server->szName,512);
wcsncat(szLine,L" ",512);
wcsncat(szLine,Server->szMap,512);
wcsncat(szLine,L" ",512);
wcsncat(szLine,Server->szGame,512);
wcsncat(szLine,L" ",512);
_itow(Server->cPlayers,szText,10);
wcsncat(szLine,szText,512);
wcsncat(szLine,L" ",512);
_itow(Server->cMaxPlayers,szText,10);
wcsncat(szLine,szText,512);
wcsncat(szLine,L" ",512);
switch(Server->cType)
{
case 'd': pText = L"Dedicated"; break;
case 'l': pText = L"Non-Dedic."; break;
case 'p': pText = L"SourceTV"; break;
default:
swprintf(szText,64,L"<%02X>",Server->cType&0xFF);
pText = szText;
}
wcsncat(szLine,pText,512);
wcsncat(szLine,L" ",512);
switch(Server->cOS)
{
case 'l': pText = L"Linux"; break;
case 'w': pText = L"Windows"; break;
case 'm': pText = L"Mac OS"; break;
default:
swprintf(szText,64,L"<%02X>",Server->cOS&0xFF);
pText = szText;
}
wcsncat(szLine,pText,512);
wcsncat(szLine,L" ",512);
wcsncat(szLine,Server->cVisibility ? L"Yes" : L"No",512);
wcsncat(szLine,L" ",512);
wcsncat(szLine,Server->cVAC ? L"Yes" : L"No",512);
wcsncat(szLine,L" ",512);
sprintf(szAddr,"%s:%d",inet_ntoa(Server->Addr.sin_addr),
ntohs(Server->Addr.sin_port));
MultiByteToWideChar(CP_UTF8,0,szAddr,-1,szText,64);
wcsncat(szLine,szText,512);
wcsncat(szLine,L"\r\n",512);
WideCharToMultiByte(CP_UTF8,0,szLine,-1,sz8Line,sizeof(sz8Line),NULL,NULL);
WriteFile(hFile,sz8Line,(DWORD)strlen(sz8Line)*sizeof(CHAR),&dwWrote,NULL);
}
CloseHandle(hFile);
}
static HWND CreateListView(LPCREATESTRUCT lpCreate,HWND hParent,INT x,INT y,INT w,INT h)
{
HWND hList;
LV_COLUMN Column;
INT i;
hList = CreateWindowEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,L"",WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_EDITLABELS,
x,y,w,h,hParent,NULL,lpCreate->hInstance,NULL);
ZeroMemory(&Column,sizeof(LV_COLUMN));
Column.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH;
for(i = 0; i < sizeof(Columns)/sizeof(COLUMNHDR_T); i++)
{
Column.cx = Columns[i].iWidth;
Column.pszText = Columns[i].lpName;
Column.iSubItem = i;
Column.iOrder = i;
ListView_InsertColumn(hList,i,&Column);
}
return hList;
}
static LRESULT CALLBACK WndCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LPCREATESTRUCT lpCreate;
switch(Msg)
{
case WM_CREATE:
//Create something
lpCreate = (LPCREATESTRUCT)lParam;
g_ServerList.hProgressBar = CreateWindow(PROGRESS_CLASS,L"",WS_CHILD|WS_VISIBLE,
6,10,1055,20,hWnd,NULL,lpCreate->hInstance,NULL);
g_ServerList.hRequestEdit = CreateWindowEx(WS_EX_CLIENTEDGE,L"Edit",L"\\appid\\4000",
WS_CHILD|WS_VISIBLE,6,35,400,25,hWnd,NULL,lpCreate->hInstance,NULL);
g_ServerList.hRequestBtn = CreateWindow(L"Button",L"Request",WS_CHILD|WS_VISIBLE,
415,35,95,25,hWnd,(HMENU)IDC_REQUEST_BTN,lpCreate->hInstance,NULL);
g_ServerList.hLabel = CreateWindow(L"STATIC",L"Status",WS_CHILD|WS_VISIBLE,
525,35,200,30,hWnd,NULL,lpCreate->hInstance,NULL);
CreateBar(lpCreate,hWnd);
g_ServerList.hServerList = CreateListView(lpCreate,hWnd,6,70,1055,480);
g_ServerList.hScanThread = NULL;
g_ServerList.Params.Servers = NULL;
ZeroMemory(&g_ServerList.Params,sizeof(g_ServerList.Params));
//Find master servers
//StartMasterScan(hWnd);
LoadMasterServers(hWnd);
break;
case WM_ENDMASTERSCAN:
EndMasterScan(wParam,lParam);
break;
case WM_ENDMASTERREQUEST:
EndMasterRequest();
break;
case WM_ENDQUERYSERVERS:
EndQueryServers();
break;
case WM_COMMAND:
if(LOWORD(wParam) == IDC_REQUEST_BTN)
{
if(g_ServerList.hScanThread != 0)
StopAnyRequests();
else MakeMasterServersRequest();
}
else
{
switch(LOWORD(wParam))
{
case IDC_FILE_SAVEAS: SaveServers(); break;
case IDC_SERVERS_MASTERS:
CreateMasterScanWindow();
break;
case IDC_SERVERS_QUERY:
CreateServerInfoWindow();
break;
case IDC_HELP_HELP: DialogHelp(); break;
case IDC_HELP_ABOUT: DialogAbout(); break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}

39
servertool/serverlist.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef __SERVERLIST_H
#define __SERVERLIST_H
#include "servertool.h"
#define SERVERLIST_CLASS L"ServerTool_ServerList"
#define IDC_REQUEST_BTN 128
#define IDC_FILE_SAVEAS 129
#define IDC_SERVERS_MASTERS 130
#define IDC_SERVERS_QUERY 131
#define IDC_HELP_HELP 132
#define IDC_HELP_ABOUT 133
typedef struct {
LPCWSTR lpClass;
HWND hWnd;
HWND hProgressBar;
HWND hRequestEdit;
HWND hRequestBtn;
HWND hLabel;
HWND hServerList;
INT ServerIdx;
MASTER_T Masters[32];
INT MasterNum;
MASTERREQUESTPARAMETERS_T Params;
HANDLE hScanThread;
} SERVERLIST_WINDOW_T;
VOID InitServerListWindow();
VOID CreateServerListWindow();
extern SERVERLIST_WINDOW_T g_ServerList;
#endif

BIN
servertool/servertool.aps Normal file

Binary file not shown.

786
servertool/servertool.c Normal file
View file

@ -0,0 +1,786 @@
#include "servertool.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
LONG changed;
INT stage;
BOOL IsResending;
} CONNSTATUS_T;
static ULONG GetTimeNow()
{
return (LONG)time(NULL);
}
VOID FormatRequest(LPVOID lpBuf,NETADR_T* pAddr,LPSTR lpSearch,PSIZE_T pszLen)
{
PBYTE pCur;
SIZE_T szLen;
PCHAR pChar;
CHAR szFormat[32];
pCur = (PBYTE)lpBuf;
*pCur++ = 0x31;
*pCur++ = 0xFF;
sprintf(szFormat,"%s:%d",inet_ntoa(pAddr->sin_addr),
ntohs(pAddr->sin_port));
pChar = szFormat;
szLen = strlen(pChar)+1;
CopyMemory(pCur,pChar,szLen);
pCur += szLen;
pChar = lpSearch;
szLen = strlen(pChar)+1;
CopyMemory(pCur,pChar,szLen);
pCur += szLen;
*pszLen = (SIZE_T)((char*)pCur-(char*)lpBuf);
}
VOID MakeNonblocking(SOCKET s)
{
unsigned long arg = 1;
ioctlsocket(s, FIONBIO, &arg);
}
BOOL FindMasterServers(MASTERFINDPARAMETERS_T* pParams)
{
struct hostent* host;
NETADR_T addr;
CONNECTION_T m_conn[32];
INT m_num;
INT stages[32];
INT rel[32];
INT changed,tries;
WSAPOLLFD polls[32];
INT p_num;
static BYTE szPacket[1240];
SIZE_T szLen;
INT i;
host = gethostbyname("hl2master.steampowered.com");
if(!host) return FALSE;
addr.sin_addr.s_addr = 0;
addr.sin_port = htons(0);
FormatRequest(szPacket,&addr,"\\app\\4020",&szLen);
i = 0;
m_num = 0;
while(host->h_addr_list[i] != 0)
{
INT j;
for(j = 27010; j <= 27015; j++)
{
m_conn[m_num].s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
m_conn[m_num].addr.sin_family = AF_INET;
m_conn[m_num].addr.sin_addr = *(IN_ADDR*)host->h_addr_list[i];
m_conn[m_num].addr.sin_port = htons(j);
m_num++;
}
i++;
}
ZeroMemory(stages,sizeof(stages));
tries = 0;
do {
p_num = 0;
for(i = 0; i < m_num; i++)
{
if(stages[i] == 2) continue;
polls[p_num].fd = m_conn[i].s;
if(stages[i] == 0)
polls[p_num].events = POLLOUT;
else polls[p_num].events = POLLIN;
rel[p_num] = i;
p_num++;
}
changed = 0;
if(p_num == 0) break;
if(WSAPoll(polls,p_num,500) > 0) //5 second timeout
{
for(i = 0; i < p_num; i++)
{
CONNECTION_T* pConn;
pConn = &m_conn[rel[i]];
if(polls[i].revents & POLLOUT)
{
sendto(pConn->s,(const char*)szPacket,(INT)szLen,0,
(const struct sockaddr*)&pConn->addr,sizeof(struct sockaddr_in));
stages[rel[i]]++;
//printf("sent request to %s:%d\n",inet_ntoa(pConn->addr.sin_addr),
// ntohs(pConn->addr.sin_port));
changed = 1;
}
else if(polls[i].revents & POLLIN)
{
INT FromLen;
FromLen = sizeof(struct sockaddr_in);
recvfrom(pConn->s,(char*)szPacket,sizeof(szPacket),0,
(struct sockaddr*)&pConn->addr,&FromLen);
stages[rel[i]]++;
//Close
closesocket(pConn->s);
//Add to list
CopyMemory(pParams->addrs,&pConn->addr,sizeof(struct sockaddr_in));
pParams->addrs++;
pParams->AddServer(&pConn->addr);
//printf("recv response from %s:%d\n",inet_ntoa(pConn->addr.sin_addr),
// ntohs(pConn->addr.sin_port));
changed = 1;
}
//unnecessary for UDP
else if(polls[i].revents & (POLLHUP|POLLERR))
{
//Error
//Close
closesocket(pConn->s);
stages[rel[i]] = 2;
//printf("error %s:%d\n",inet_ntoa(pConn->addr.sin_addr),
// ntohs(pConn->addr.sin_port));
}
}
}
//printf("changed %d tries %d\n",changed,tries);
if(changed == 0)
{
if(tries++ == 2)
{
for(i = 0; i < m_num; i++)
{
if(stages[i] == 2) continue;
stages[i] = 2;
closesocket(m_conn[i].s);
}
}
} else tries = 0;
} while(p_num > 0);
return TRUE;
}
INT DoMasterServers(MASTER_T* Masters,INT MasterNum,LPCSTR lpSearch)
{
static BYTE szPacket[2048];
CONNSTATUS_T status[32];
WSAPOLLFD polls[32];
SIZE_T szLen;
INT rel[32];
INT i,p_num,CurTime,Delta;
INT servers;
PBYTE pPtr;
for(i = 0; i < MasterNum; i++)
{
Masters[i].Conn.s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
Masters[i].ServerNum = 0;
Masters[i].PacketNum = 0;
MakeNonblocking(Masters[i].Conn.s);
status[i].stage = 0;
status[i].changed = GetTimeNow();
}
servers = 0;
do {
p_num = 0;
for(i = 0; i < MasterNum; i++)
{
if(status[i].stage == 2)
continue;
polls[p_num].fd = Masters[i].Conn.s;
if(status[i].stage == 0)
polls[p_num].events = POLLOUT;
else polls[p_num].events = POLLIN;
rel[p_num] = i;
p_num++;
}
if(p_num == 0) break;
if(WSAPoll(polls,p_num,500))
{
for(i = 0; i < p_num; i++)
{
MASTER_T* Master;
Master = &Masters[rel[i]];
if(polls[i].revents & POLLOUT)
{
NETADR_T last;
if(Master->ServerNum == 0)
{
last.sin_addr.s_addr = 0;
last.sin_port = 0;
}
else last = Master->Servers[Master->ServerNum-1];
FormatRequest(szPacket,&last,(LPSTR)lpSearch,&szLen);
sendto(Master->Conn.s,(const char*)szPacket,(INT)szLen,0,
(const struct sockaddr*)&Master->Conn.addr,
sizeof(struct sockaddr_in));
status[rel[i]].stage = 1; //Request stage
status[rel[i]].changed = GetTimeNow();
}
else if(polls[i].revents & POLLIN)
{
INT FromLen;
INT SvNum;
FromLen = sizeof(struct sockaddr_in);
szLen = recvfrom(Master->Conn.s,(char*)szPacket,sizeof(szPacket),
0,(struct sockaddr*)&Master->Conn.addr,&FromLen);
//Now we need to process data
pPtr = szPacket;
if(Master->PacketNum == 0)
{
//First packet have header which we want to skip
szLen -= 6;
MoveMemory(szPacket,szPacket+6,szLen);
}
SvNum = (INT)(szLen/6);
//Check for ending mark
if(((NETADR_T*)szPacket+SvNum-1)->sin_addr.s_addr == 0)
{
//printf("got last packet\n");
SvNum--; //We don't want to copy ending mark
//status[rel[i]].stage = 2;
status[rel[i]].stage = 2;
if(Master->Conn.s)
{
closesocket(Master->Conn.s);
Master->Conn.s = 0;
}
continue;
} else status[rel[i]].stage = 0;
if(SvNum == 0) continue;
//Alocate space for server data and copy server
if(Master->ServerNum == 0)
Master->Servers = (NETADR_T*)malloc(SvNum*6);
else
{
Master->Servers = (NETADR_T*)realloc(
Master->Servers,(Master->ServerNum*6)+SvNum*6);
}
CopyMemory(Master->Servers+Master->ServerNum,szPacket,SvNum*6);
Master->ServerNum += SvNum;
//printf("got %d servers from %s:%d\n",SvNum,inet_ntoa(pMaster->Conn.addr.sin_addr),
// ntohs(pMaster->Conn.addr.sin_port));
servers += SvNum;
status[rel[i]].changed = GetTimeNow();
}
else if(polls[i].revents & (POLLHUP|POLLERR))
{
status[rel[i]].stage = 2;
if(Master->Conn.s)
{
closesocket(Master->Conn.s);
Master->Conn.s = 0;
}
//printf("POLLHUP|POLLERR\n");
}
}
}
CurTime = GetTimeNow();
for(i = 0; i < MasterNum; i++)
{
CONNSTATUS_T* pStat;
pStat = &status[i];
Delta = CurTime - pStat->changed;
if(Delta > 8)
{
//Get the fuck out!
pStat->stage = 2;
if(Masters[i].Conn.s)
{
closesocket(Masters[i].Conn.s);
Masters[i].Conn.s = 0;
}
}
}
} while(p_num != 0);
return servers;
}
VOID MasterFree(MASTER_T* Master)
{
if(Master->ServerNum)
free(Master->Servers);
}
BOOL IsServerAlreadyInList(NETADR_T* Servers,INT ServerNum,NETADR_T* Target)
{
INT i;
for(i = 0; i < ServerNum; i++)
{
if(!memcmp(Target,&Servers[i],sizeof(NETADR_T)))
return TRUE;
}
return FALSE;
}
NETADR_T* GetUniqueServers(MASTER_T* pMasters,INT MasterNum,INT* pServerNum)
{
INT i,j;
INT SvNum;
NETADR_T* pServers;
SvNum = 0;
pServers = NULL;
for(i = 0; i < MasterNum; i++)
{
for(j = 0; j < pMasters[i].ServerNum; j++)
{
if(!IsServerAlreadyInList(pServers,SvNum,&pMasters[i].Servers[j]))
{
if(SvNum == 0)
{
pServers = (NETADR_T*)malloc(sizeof(NETADR_T));
}
else
{
pServers = (NETADR_T*)realloc(pServers,sizeof(NETADR_T)*(SvNum+1));
}
CopyMemory(&pServers[SvNum++],&pMasters[i].Servers[j],sizeof(NETADR_T));
}
}
}
*pServerNum = SvNum;
return pServers;
}
VOID ParsePacket(PBYTE pPacket,SERVER_T* Server)
{
PBYTE pCur;
INT iNum;
pCur = pPacket;
if(*(PINT)pCur != -1)
{
wcscpy(Server->szName,L"!!<wrong header>!!");
return;
}
pCur += 5;
pCur++;
MultiByteToWideChar(CP_UTF8,0,(LPCSTR)pCur,-1,Server->szName,MAX_PATH);
pCur += strlen((const char*)pCur)+1;
MultiByteToWideChar(CP_UTF8,0,(LPCSTR)pCur,-1,Server->szMap,64);
pCur += strlen((const char*)pCur)+1;
pCur += strlen((const char*)pCur)+1; //Skip folder
MultiByteToWideChar(CP_UTF8,0,(LPCSTR)pCur,-1,Server->szGame,64);
pCur += strlen((const char*)pCur)+1;
pCur += 2; //Skip ID
Server->cPlayers = *pCur++;
Server->cMaxPlayers = *pCur++;
iNum = *pCur++;
Server->cPlayers += iNum;
Server->cType = *pCur++;
Server->cOS = *pCur++;
Server->cVisibility = *pCur++;
Server->cVAC = *pCur++;
}
static BYTE szSourceQuery[] = "\xFF\xFF\xFF\xFFTSource Engine Query";
VOID QueryServers(NETADR_T* Addrs,SERVER_T* Servers,INT ServerNum,
AddServer_t AddServer,INT WaitTime)
{
static WSAPOLLFD polls[SERVER_BLOCK];
static CONNECTION_T m_conn[SERVER_BLOCK];
static CONNSTATUS_T status[SERVER_BLOCK];
static INT rel[SERVER_BLOCK];
BYTE szPacket[1240];
INT i,p_num;
LONG CurTime,Delta;
ZeroMemory(status,sizeof(status));
ZeroMemory(rel,sizeof(rel));
for(i = 0; i < ServerNum; i++)
{
m_conn[i].s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
MakeNonblocking(m_conn[i].s);
m_conn[i].addr.sin_family = AF_INET;
m_conn[i].addr.sin_addr = Addrs[i].sin_addr;
m_conn[i].addr.sin_port = Addrs[i].sin_port;
status[i].stage = 0;
status[i].changed = GetTimeNow();
}
do {
p_num = 0;
for(i = 0; i < ServerNum; i++)
{
if(status[i].stage == 2) continue;
polls[p_num].fd = m_conn[i].s;
if(status[i].stage == 0)
polls[p_num].events = POLLOUT;
else polls[p_num].events = POLLIN;
rel[p_num] = i;
p_num++;
}
if(p_num == 0) break;
//We need to be precisous,
//because everything based on timings
if(WSAPoll(polls,p_num,1000))
{
for(i = 0; i < p_num; i++)
{
CONNECTION_T* pConn;
CONNSTATUS_T* pStat;
pConn = &m_conn[rel[i]];
pStat = &status[rel[i]];
if(polls[i].revents & POLLOUT)
{
//Send request
sendto(pConn->s,(const char*)szSourceQuery,25,
0,(const struct sockaddr*)&pConn->addr,sizeof(struct sockaddr_in));
pStat->stage = 1;
//pStat->changed = GetTimeNow();
}
else if(polls[i].revents & POLLIN)
{
INT FromLen;
FromLen = sizeof(struct sockaddr_in);
recvfrom(pConn->s,(char*)szPacket,sizeof(szPacket),0,
(struct sockaddr*)&pConn->addr,&FromLen);
//Parse packet
ZeroMemory(Servers,sizeof(SERVER_T));
Servers->Addr.sin_addr = pConn->addr.sin_addr;
Servers->Addr.sin_port = pConn->addr.sin_port;
ParsePacket(szPacket,Servers);
Servers->IsValid = TRUE;
AddServer(Servers);
Servers++;
closesocket(pConn->s);
pConn->s = 0;
pStat->stage = 2;
pStat->changed = GetTimeNow();
}
else if(polls[i].revents & (POLLHUP|POLLERR))
{
closesocket(pConn->s);
pConn->s = 0;
pStat->stage = 2;
}
}
}
CurTime = GetTimeNow();
for(i = 0; i < ServerNum; i++)
{
if(status[i].stage == 2) continue;
Delta = CurTime - status[i].changed;
if(Delta >= WaitTime)
{
//2 seconds no activity - get the fuck out!
status[i].stage = 2;
if(m_conn[i].s)
{
closesocket(m_conn[i].s);
m_conn[i].s = 0;
}
}
}
} while(p_num != 0);
}
static BOOL RecvTimeOut(CONNECTION_T* pConn,PBYTE pPacket,INT Len,INT TimeOut)
{
INT FromLen;
FromLen = sizeof(struct sockaddr_in);
recvfrom(pConn->s,(char*)pPacket,Len,0,
(struct sockaddr*)&pConn->addr,&FromLen);
return TRUE;
}
static VOID ParseRules(PBYTE pMem,AddRule_t AddRule)
{
PBYTE pPtr;
SHORT NumRules;
INT Len;
pPtr = pMem;
pPtr += 5;
NumRules = *(PSHORT)pPtr;
pPtr += 2;
while(NumRules--)
{
Len = (INT)strlen((const char*)pPtr)+1;
AddRule((PCHAR)pPtr,(PCHAR)pPtr+Len);
pPtr += Len;
pPtr += strlen((const char*)pPtr)+1;
}
}
static BOOL GetServerRules(CONNECTION_T* pConn,AddRule_t AddRule)
{
static BYTE szPacket[2048];
WSAPOLLFD poll;
PBYTE pMem;
PBYTE pPtr;
INT Len;
INT Stage;
UINT Challenge;
BOOL IsMultipacket;
INT Total,Current;
SHORT SwitchSize;
//Stage 0 - send request with challenge
//Stage 1 - if challenge is -1, request again with challenge
// otherwise, start parsing multipackets
//Stage 2 - final
Total = 0;
Current = 0;
SwitchSize = 0;
pMem = NULL;
Challenge = (UINT)-1;
Stage = 0;
do {
poll.fd = pConn->s;
if(Stage == 0)
poll.events = POLLOUT;
else poll.events = POLLIN;
if(WSAPoll(&poll,1,3000))
{
if(poll.revents & POLLOUT)
{
pPtr = szPacket;
*(PUINT)pPtr = (UINT)-1;
pPtr += 4;
*pPtr++ = 0x56;
*(PUINT)pPtr = (UINT)Challenge;
pPtr += 4;
sendto(pConn->s,(const char*)szPacket,9,0,
(const struct sockaddr*)&pConn->addr,sizeof(struct sockaddr_in));
Stage = 1;
}
else if(poll.revents & POLLIN)
{
INT FromLen;
pPtr = szPacket;
FromLen = sizeof(struct sockaddr_in);
Len = recvfrom(pConn->s,(char*)szPacket,sizeof(szPacket),0,
(struct sockaddr*)&pConn->addr,&FromLen);
if(*(PUINT)pPtr == -1)
{
if(Challenge == -1)
{
pPtr += 5;
Challenge = *(PUINT)pPtr;
Stage = 0; //Request again
}
else //If it regular packet
{
IsMultipacket = FALSE;
pMem = (PBYTE)malloc(Len);
CopyMemory(pMem,szPacket,Len);
Stage = 2;
}
}
else if(*(PUINT)pPtr == -2) //Multipacket
{
INT HdrSize;
IsMultipacket = TRUE;
pPtr += 4;
if(*(PUINT)pPtr & 0x80000000)
{
//Compressed??! FUCK YOU!
return FALSE;
}
pPtr += 4;
if(!Total) Total = *pPtr;
pPtr++;
Current = *pPtr++;
if(!SwitchSize) //Avoid exploit
SwitchSize = *(PSHORT)pPtr;
pPtr += 2;
HdrSize = (INT)(pPtr-szPacket);
Len -= HdrSize;
//Remove multipacket header
MoveMemory(szPacket,szPacket+HdrSize,Len);
if(Current == 0 || !pMem) //If first
{
//Allocate memory
pMem = (PBYTE)calloc(Total,SwitchSize);
}
//Copy memory at given index (current)
//Because UDP is unordered
if(Current < Total)
CopyMemory(pMem+SwitchSize*Current,szPacket,SwitchSize);
if(Current + 1 == Total) //Last packet
Stage = 2;
else Stage = 1;
}
}
}
else return FALSE; //Time out!
} while(Stage != 2);
ParseRules(pMem,AddRule);
free(pMem);
return TRUE;
}
BOOL GetServerInfo(NETADR_T* Addr,AddServer_t AddServer,
AddPlayer_t AddPlayer,AddRule_t AddRule)
{
static BYTE szPacket[1240];
CONNECTION_T m_conn;
PBYTE pPtr;
SERVER_T Server;
UINT Challenge;
m_conn.s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
m_conn.addr.sin_family = AF_INET;
m_conn.addr.sin_addr = Addr->sin_addr;
m_conn.addr.sin_port = Addr->sin_port;
//MakeNonblocking(m_conn.s);
//Request info
sendto(m_conn.s,(const char*)szSourceQuery,sizeof(szSourceQuery),0,
(const struct sockaddr*)&m_conn.addr,sizeof(struct sockaddr_in));
if(RecvTimeOut(&m_conn,szPacket,sizeof(szPacket),3000))
{
ParsePacket(szPacket,&Server);
AddServer(&Server);
}
else
{
closesocket(m_conn.s);
return FALSE;
}
//Request players
Challenge = (UINT)-1;
pPtr = szPacket;
*(PUINT)pPtr = (UINT)-1;
pPtr += 4;
*pPtr++ = 0x55;
*(PUINT)pPtr = Challenge;
pPtr += 4;
//Got challenge
sendto(m_conn.s,(const char*)szPacket,9,0,
(const struct sockaddr*)&m_conn.addr,sizeof(struct sockaddr_in));
if(RecvTimeOut(&m_conn,szPacket,sizeof(szPacket),3000))
{
Challenge = *(PUINT)(szPacket+5);
}
else
{
closesocket(m_conn.s);
return FALSE;
}
pPtr = szPacket;
*(PUINT)pPtr = (UINT)-1;
pPtr += 4;
*pPtr++ = 0x55;
*(PUINT)pPtr = Challenge;
pPtr += 4;
sendto(m_conn.s,(const char*)szPacket,9,0,
(const struct sockaddr*)&m_conn.addr,sizeof(struct sockaddr_in));
if(RecvTimeOut(&m_conn,szPacket,sizeof(szPacket),3000))
{
//Parse players
BYTE PlayerNum;
PCHAR Name;
UINT Score;
FLOAT Duration;
INT i;
pPtr = szPacket;
pPtr += 5;
PlayerNum = *pPtr++;
for(i = 0; i < PlayerNum; i++)
{
pPtr++;
Name = (PCHAR)pPtr;
pPtr += strlen((const char*)pPtr)+1;
Score = *(PUINT)pPtr;
pPtr += 4;
Duration = *(PFLOAT)pPtr;
pPtr += 4;
AddPlayer(Name,Score,Duration);
}
}
MakeNonblocking(m_conn.s);
//Parse rules
GetServerRules(&m_conn,AddRule);
closesocket(m_conn.s);
return TRUE;
}

103
servertool/servertool.h Normal file
View file

@ -0,0 +1,103 @@
#ifndef __SERVERTOOL_H
#define __SERVERTOOL_H
#include <WinSock2.h>
#define WINDOW_STYLE (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX)
#define POPUP_STYLE (WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX)
#define WM_ENDMASTERSCAN (WM_USER+1)
//WPARAM - MasterNum
//LPARAM - Addrs
#define WM_ENDMASTERREQUEST (WM_USER+2)
//LPARAM - Param ptr
#define WM_ENDQUERYSERVERS (WM_USER+3)
//LPARAM - Server num
#define WM_ENDSERVERINFOREQUEST (WM_USER+4)
#define SERVER_BLOCK 2048
#define MAX_MASTER_NUM 6
typedef struct {
HINSTANCE hInst;
INT nCmdShow;
HICON hIcon;
HICON hIconSm;
} APPLICATION_T;
typedef struct {
SOCKET s;
struct sockaddr_in addr;
} CONNECTION_T;
#pragma pack(push,1)
typedef struct {
IN_ADDR sin_addr;
SHORT sin_port;
} NETADR_T;
#pragma pack(pop)
typedef struct {
CONNECTION_T Conn;
NETADR_T* Servers;
INT ServerNum;
INT PacketNum;
} MASTER_T;
typedef struct {
LPCSTR lpszSearch;
struct sockaddr_in* addrs;
VOID (*AddServer)(struct sockaddr_in*);
} MASTERFINDPARAMETERS_T;
typedef struct {
WCHAR szName[MAX_PATH];
WCHAR szMap[64];
WCHAR szGame[64];
BYTE cPlayers;
BYTE cMaxPlayers;
BYTE cOS;
BYTE cType;
BYTE cVisibility;
BYTE cVAC;
BOOL IsValid;
NETADR_T Addr;
} SERVER_T;
typedef struct {
IN char szSearch[MAX_PATH];
IN MASTER_T* Masters;
IN INT MasterNum;
IN HWND hParent;
OUT NETADR_T* Servers;
OUT INT ServerNum;
SERVER_T* ServerList;
} MASTERREQUESTPARAMETERS_T;
typedef struct {
WCHAR szName[32];
INT Score;
FLOAT Duration;
} PLAYER_T;
typedef VOID (*AddServer_t)(SERVER_T*);
typedef VOID (*AddPlayer_t)(PCHAR,UINT,FLOAT);
typedef VOID (*AddRule_t)(PCHAR,PCHAR);
VOID FormatRequest(LPVOID lpBuf,NETADR_T* pAddr,LPSTR lpSearch,PSIZE_T pszLen);
VOID MakeNonblocking(SOCKET s);
BOOL FindMasterServers(MASTERFINDPARAMETERS_T* pParams);
INT DoMasterServers(MASTER_T* pMasters,INT MasterNum,LPCSTR lpSearch);
VOID MasterFree(MASTER_T* Master);
BOOL IsServerAlreadyInList(NETADR_T* Servers,INT ServerNum,NETADR_T* Target);
NETADR_T* GetUniqueServers(MASTER_T* pMasters,INT MasterNum,INT* pServerNum);
VOID ParsePacket(PBYTE pPacket,SERVER_T* Server);
VOID QueryServers(NETADR_T* Addrs,SERVER_T* Servers,INT ServerNum,
AddServer_t AddServer,INT WaitTime);
BOOL GetServerInfo(NETADR_T* Addr,AddServer_t AddServer,
AddPlayer_t AddPlayer,AddRule_t AddRule);
extern APPLICATION_T g_App;
#endif

BIN
servertool/servertool.rc Normal file

Binary file not shown.

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{FF615871-8561-4F2E-9307-9CEA2E7BE381}</ProjectGuid>
<RootNamespace>servertool</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>WS2_32.lib;Comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.c" />
<ClCompile Include="masterscan.c" />
<ClCompile Include="serverinfo.c" />
<ClCompile Include="serverlist.c" />
<ClCompile Include="servertool.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="masterscan.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="serverinfo.h" />
<ClInclude Include="servertool.h" />
<ClInclude Include="serverlist.h" />
</ItemGroup>
<ItemGroup>
<None Include="icon.ico" />
<None Include="icon16.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="servertool.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Файлы исходного кода">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Заголовочные файлы">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Файлы ресурсов">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
<ClCompile Include="serverlist.c">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
<ClCompile Include="masterscan.c">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
<ClCompile Include="servertool.c">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
<ClCompile Include="serverinfo.c">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="serverlist.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
<ClInclude Include="masterscan.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
<ClInclude Include="servertool.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
<ClInclude Include="serverinfo.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="icon16.ico">
<Filter>Файлы ресурсов</Filter>
</None>
<None Include="icon.ico">
<Filter>Файлы ресурсов</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="servertool.rc">
<Filter>Файлы ресурсов</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@


View file

@ -0,0 +1 @@


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,20 @@
D:\serverbrowser\servertool\x64\Release\cl.command.1.tlog
D:\serverbrowser\servertool\x64\Release\CL.read.1.tlog
D:\serverbrowser\servertool\x64\Release\CL.write.1.tlog
D:\serverbrowser\servertool\x64\Release\link.command.1.tlog
D:\serverbrowser\servertool\x64\Release\link.read.1.tlog
D:\serverbrowser\servertool\x64\Release\link.write.1.tlog
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\MAIN.OBJ
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\MASTERSCAN.OBJ
D:\serverbrowser\servertool\x64\Release\mt.command.1.tlog
D:\serverbrowser\servertool\x64\Release\mt.read.1.tlog
D:\serverbrowser\servertool\x64\Release\mt.write.1.tlog
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\SERVERINFO.OBJ
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\SERVERLIST.OBJ
D:\serverbrowser\servertool\x64\Release\servertool.exe.intermediate.manifest
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\SERVERTOOL.OBJ
D:\serverbrowser\servertool\x64\Release\servertool.vcxprojResolveAssemblyReference.cache
D:\serverbrowser\servertool\x64\Release\servertool.write.1.tlog
D:\SERVERBROWSER\SERVERTOOL\X64\RELEASE\VC100.PDB
D:\SERVERBROWSER\X64\RELEASE\SERVERTOOL.EXE
D:\serverbrowser\x64\Release\servertool.pdb

View file

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View file

@ -0,0 +1,2 @@
#v4.0:v100:false
Release|x64|D:\serverbrowser\|

View file

@ -0,0 +1,33 @@
Построение начато 25.01.2020 9:51:48.
1>Проект "D:\serverbrowser\servertool\servertool.vcxproj" в узле 2 (целевые объекты build).
1>InitializeBuildStatus:
Создание "x64\Release\servertool.unsuccessfulbuild", так как было задано "AlwaysCreate".
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\CL.exe /c /Zi /nologo /W3 /WX- /O2 /Oi /GL /D _CRT_SECURE_NO_WARNINGS /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo"x64\Release\\" /Fd"x64\Release\vc100.pdb" /Gd /TC /errorReport:prompt main.c masterscan.c serverinfo.c serverlist.c servertool.c
main.c
masterscan.c
serverinfo.c
serverlist.c
servertool.c
ResourceCompile:
Для всех выходных данных обновления не требуется.
Link:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"D:\serverbrowser\x64\Release\servertool.exe" /NOLOGO WS2_32.lib Comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /ManifestFile:"x64\Release\servertool.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"D:\serverbrowser\x64\Release\servertool.pdb" /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"D:\serverbrowser\x64\Release\servertool.lib" /MACHINE:X64 x64\Release\servertool.res
x64\Release\main.obj
x64\Release\masterscan.obj
x64\Release\serverinfo.obj
x64\Release\serverlist.obj
x64\Release\servertool.obj
Создание кода
Создание кода завершено
servertool.vcxproj -> D:\serverbrowser\x64\Release\servertool.exe
Manifest:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\mt.exe /nologo /verbose /outputresource:"D:\serverbrowser\x64\Release\servertool.exe;#1" /manifest x64\Release\servertool.exe.intermediate.manifest
FinalizeBuildStatus:
Файл "x64\Release\servertool.unsuccessfulbuild" удаляется.
Обращение к "x64\Release\servertool.lastbuildstate".
1>Построение проекта "D:\serverbrowser\servertool\servertool.vcxproj" завершено (целевые объекты build).
Построение успешно завершено.
Затраченное время: 00:00:04.88

Binary file not shown.

Binary file not shown.

1
x64/Release/master.dat Normal file
View file

@ -0,0 +1 @@
Ð@È4i„Ð@È'iƒÐ@È4iƒÐ@È'i„Ð@ÈAi‡Ð@ÈAiƒ

BIN
x64/Release/servertool.exe Normal file

Binary file not shown.

BIN
x64/Release/servertool.pdb Normal file

Binary file not shown.