Initial commit
This commit is contained in:
commit
633f20d561
46 changed files with 2484 additions and 0 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
*.obj
|
||||
*.sdf
|
||||
*.suo
|
||||
*.opensdf
|
||||
ipch/
|
||||
masterlist/
|
||||
serverbrowser/
|
||||
1
README.md
Normal file
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# servertool
|
||||
42
serverbrowser.sln
Normal file
42
serverbrowser.sln
Normal 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
BIN
servertool/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
servertool/icon16.ico
Normal file
BIN
servertool/icon16.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
51
servertool/main.c
Normal file
51
servertool/main.c
Normal 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
1
servertool/master.dat
Normal file
|
|
@ -0,0 +1 @@
|
|||
Ð@È4i„Ð@È'iƒÐ@ÈAi‡Ð@ÈAiƒÐ@È4iƒÐ@È'i„
|
||||
230
servertool/masterscan.c
Normal file
230
servertool/masterscan.c
Normal 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
37
servertool/masterscan.h
Normal 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
BIN
servertool/resource.h
Normal file
Binary file not shown.
275
servertool/serverinfo.c
Normal file
275
servertool/serverinfo.c
Normal 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
31
servertool/serverinfo.h
Normal 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
611
servertool/serverlist.c
Normal 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
39
servertool/serverlist.h
Normal 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
BIN
servertool/servertool.aps
Normal file
Binary file not shown.
786
servertool/servertool.c
Normal file
786
servertool/servertool.c
Normal 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
103
servertool/servertool.h
Normal 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
BIN
servertool/servertool.rc
Normal file
Binary file not shown.
135
servertool/servertool.vcxproj
Normal file
135
servertool/servertool.vcxproj
Normal 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>
|
||||
64
servertool/servertool.vcxproj.filters
Normal file
64
servertool/servertool.vcxproj.filters
Normal 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>
|
||||
3
servertool/servertool.vcxproj.user
Normal file
3
servertool/servertool.vcxproj.user
Normal 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>
|
||||
BIN
servertool/x64/Release/CL.read.1.tlog
Normal file
BIN
servertool/x64/Release/CL.read.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/CL.write.1.tlog
Normal file
BIN
servertool/x64/Release/CL.write.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/cl.command.1.tlog
Normal file
BIN
servertool/x64/Release/cl.command.1.tlog
Normal file
Binary file not shown.
1
servertool/x64/Release/link-cvtres.read.1.tlog
Normal file
1
servertool/x64/Release/link-cvtres.read.1.tlog
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
1
servertool/x64/Release/link-cvtres.write.1.tlog
Normal file
1
servertool/x64/Release/link-cvtres.write.1.tlog
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
BIN
servertool/x64/Release/link.command.1.tlog
Normal file
BIN
servertool/x64/Release/link.command.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/link.read.1.tlog
Normal file
BIN
servertool/x64/Release/link.read.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/link.write.1.tlog
Normal file
BIN
servertool/x64/Release/link.write.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/mt.command.1.tlog
Normal file
BIN
servertool/x64/Release/mt.command.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/mt.read.1.tlog
Normal file
BIN
servertool/x64/Release/mt.read.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/mt.write.1.tlog
Normal file
BIN
servertool/x64/Release/mt.write.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/rc.command.1.tlog
Normal file
BIN
servertool/x64/Release/rc.command.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/rc.read.1.tlog
Normal file
BIN
servertool/x64/Release/rc.read.1.tlog
Normal file
Binary file not shown.
BIN
servertool/x64/Release/rc.write.1.tlog
Normal file
BIN
servertool/x64/Release/rc.write.1.tlog
Normal file
Binary file not shown.
20
servertool/x64/Release/servertool.Build.CppClean.log
Normal file
20
servertool/x64/Release/servertool.Build.CppClean.log
Normal 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
|
||||
10
servertool/x64/Release/servertool.exe.intermediate.manifest
Normal file
10
servertool/x64/Release/servertool.exe.intermediate.manifest
Normal 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>
|
||||
2
servertool/x64/Release/servertool.lastbuildstate
Normal file
2
servertool/x64/Release/servertool.lastbuildstate
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#v4.0:v100:false
|
||||
Release|x64|D:\serverbrowser\|
|
||||
33
servertool/x64/Release/servertool.log
Normal file
33
servertool/x64/Release/servertool.log
Normal 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
|
||||
BIN
servertool/x64/Release/servertool.res
Normal file
BIN
servertool/x64/Release/servertool.res
Normal file
Binary file not shown.
Binary file not shown.
0
servertool/x64/Release/servertool.write.1.tlog
Normal file
0
servertool/x64/Release/servertool.write.1.tlog
Normal file
BIN
servertool/x64/Release/vc100.pdb
Normal file
BIN
servertool/x64/Release/vc100.pdb
Normal file
Binary file not shown.
1
x64/Release/master.dat
Normal file
1
x64/Release/master.dat
Normal file
|
|
@ -0,0 +1 @@
|
|||
Ð@È4i„Ð@È'iƒÐ@È4iƒÐ@È'i„Ð@ÈAi‡Ð@ÈAiƒ
|
||||
BIN
x64/Release/servertool.exe
Normal file
BIN
x64/Release/servertool.exe
Normal file
Binary file not shown.
BIN
x64/Release/servertool.pdb
Normal file
BIN
x64/Release/servertool.pdb
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue