// SBCheck 2.0 by PsyQo // Simple Sandbox checker #define WINDOWS_LEAN_AND_MEAN #include #include #include // Some constants #define SANDBOX_HOST "rose-sandbox.servegame.org" #define SANDBOX_PORT 29000 #define ROSE_CMDLINE "TRose.exe @TRIGGER_SOFT@ _server " SANDBOX_HOST #define MSGBOX_CAPTION "SBCheck 2.0 by PsyQo" #define WINDOW_CAPTION "SBCheck 2.0 by PsyQo" #define WINDOW_WIDTH 400 #define WINDOW_HEIGHT 82 // Function prototypes. LRESULT CALLBACK wndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); void doCheck(); void doLaunch(); // Eek! Global variables! This is a bad practice kids, but look away for now. HWND g_hSBCWindow = NULL; HWND g_hText = NULL; HWND g_hCheckButton = NULL; HWND g_hLaunchButton = NULL; HWND g_hExitButton = NULL; time_t g_timeReCheck = 0; int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nShowCmd ) { WSADATA wsaData; // Initialize winsock if ( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) != 0 ) { MessageBox( NULL, "Could not initialize Winsock", MSGBOX_CAPTION, MB_ICONERROR | MB_OK ); return EXIT_FAILURE; } // Register main window. WNDCLASS sbcClass; memset( &sbcClass, 0, sizeof( WNDCLASS )); sbcClass.lpfnWndProc = ( WNDPROC ) wndProc; sbcClass.hInstance = hInstance; sbcClass.lpszClassName = "SBCheck"; sbcClass.style = 0; sbcClass.hCursor = LoadCursor( 0, IDC_ARROW ); sbcClass.hIcon = LoadIcon( 0, IDI_WINLOGO ); sbcClass.hbrBackground = ( HBRUSH )( COLOR_WINDOW ); if ( RegisterClass( &sbcClass ) == 0 ) { MessageBox( NULL, "Could not register SBCheck window class", MSGBOX_CAPTION, MB_ICONERROR | MB_OK ); WSACleanup(); return EXIT_FAILURE; } // Create window. g_hSBCWindow = CreateWindow( "SBCheck", WINDOW_CAPTION, WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL ); if ( g_hSBCWindow == NULL ) { MessageBox( NULL, "Could not create SBCheck window", MSGBOX_CAPTION, MB_ICONERROR| MB_OK ); WSACleanup(); return EXIT_FAILURE; } // Enter main loop. MSG msg; while ( true ) { // Don't be a CPU hog. Sleep( 25 ); if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) { if ( msg.message == WM_QUIT ) { // We should quit, break out of the main loop. Bye bye! break; } // Handle message. TranslateMessage( &msg ); DispatchMessage( &msg ); continue; } if ( time( NULL ) > g_timeReCheck ) EnableWindow( g_hCheckButton, true ); } WSACleanup(); // Done! return EXIT_SUCCESS; } LRESULT CALLBACK wndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch ( msg ) { case WM_CREATE: // Create textbox. g_hText = CreateWindow( "STATIC", "apptext", SS_SUNKEN | WS_CHILD | WS_VISIBLE, 4, 4, WINDOW_WIDTH - 14, 20, hWnd, NULL, ( HINSTANCE ) GetWindowLong ( hWnd,GWL_HINSTANCE ), NULL ); SetWindowText( g_hText, "" ); // Create buttons g_hCheckButton = CreateWindow( "BUTTON", "Check", BS_CENTER | BS_FLAT | WS_CHILD | WS_VISIBLE, 4, 28, 60, 24, hWnd, NULL, ( HINSTANCE ) GetWindowLong ( hWnd,GWL_HINSTANCE ), NULL ); g_hLaunchButton = CreateWindow( "BUTTON", "Launch ROSE", BS_CENTER | BS_FLAT | WS_DISABLED | WS_CHILD | WS_VISIBLE, 72, 28, 100, 24, hWnd, NULL, ( HINSTANCE ) GetWindowLong ( hWnd,GWL_HINSTANCE ), NULL ); g_hExitButton = CreateWindow( "BUTTON", "Exit", BS_CENTER | BS_FLAT | WS_CHILD | WS_VISIBLE, WINDOW_WIDTH - 70, 28, 60, 24, hWnd, NULL, ( HINSTANCE ) GetWindowLong ( hWnd,GWL_HINSTANCE ), NULL ); // Attach wndprocs break; case WM_COMMAND: // A button was clicked, check which one if (( HWND ) lParam == g_hCheckButton ) doCheck(); else if (( HWND ) lParam == g_hLaunchButton ) doLaunch(); else if (( HWND ) lParam == g_hExitButton ) PostQuitMessage( 0 ); break; case WM_CLOSE: // Program termination requested. PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, msg, wParam, lParam ); } return 0; } void doCheck() { // Disable check and launch buttons EnableWindow( g_hCheckButton, false ); EnableWindow( g_hLaunchButton, false ); SetWindowText( g_hText, " Checking..." ); // Try to resolve rose-sandbox.servegame.org HOSTENT *pHE = gethostbyname( SANDBOX_HOST ); if ( pHE == NULL ) { // Could not resolve host, Sandbox might be offline (or there's no internet connection, or your nameserver is fscked :)) SetWindowText( g_hText, " Could not resolve '" SANDBOX_HOST "'. Your internet connection might be down." ); EnableWindow( g_hCheckButton, true ); return; } // Try to connect to the Sandbox SOCKET clientSocket = socket( AF_INET, SOCK_STREAM, 0 ); if ( clientSocket == INVALID_SOCKET ) { SetWindowText( g_hText, " socket() failed" ); EnableWindow( g_hCheckButton, true ); return; } sockaddr_in addr; memset( &addr, 0, sizeof( addr )); addr.sin_family = AF_INET; addr.sin_addr = *(( in_addr * ) pHE->h_addr ); addr.sin_port = htons( SANDBOX_PORT ); if ( connect( clientSocket, ( sockaddr * ) &addr, sizeof( addr )) == SOCKET_ERROR ) { // Could not connect, Sandbox is probably down SetWindowText( g_hText, " Could not connect to the Sandbox, it's probably down, try again later." ); g_timeReCheck = time( NULL ) + 5; return; } // Yay! Connected, close the connection immediately and notify the user closesocket( clientSocket ); SetWindowText( g_hText, " Sandbox seems to be up!" ); EnableWindow( g_hLaunchButton, true ); g_timeReCheck = time( NULL ) + 5; } void doLaunch() { // Attempt to launch ROSE STARTUPINFO si; // } Gotta love Microsoft's naming conventions :) PROCESS_INFORMATION pi; // } memset( &si, 0, sizeof( si )); si.cb = sizeof( si ); if ( CreateProcess( NULL, ROSE_CMDLINE, NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ) == 0 ) { MessageBox( g_hSBCWindow, "Could not launch ROSE. Try to start it yourself using '" ROSE_CMDLINE "'.", MSGBOX_CAPTION, MB_ICONERROR | MB_OK ); return; } // We don't need these, so close them CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); }