www.pudn.com > gamedata.rar > servergame.c
// servergame.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "common.h"
#include "resource.h"
#define MAX_LOADSTRING 100
#define MAX_CHAR 1024
// 用 key 追踪 每一个单独的文件句柄
// 的I/O 端口的状态.
#define MAX_LOADSTRING 100
// Global Variables:
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
HANDLE ghCompletionPort;
char szLoginInfo[2048];
struct GAMESERVERINFO pServerInfo[64];
struct optiondata option;
// Global Variables:
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
TBBUTTON tbButtons[] =
{
{ 0, IDM_STARTSERVICE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 1, IDM_STOPSERVICE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 2, IDM_FONTCOLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 3, IDM_BACKCOLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
};
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ReadPack(struct logindata *login)
{
int i = 0;
BOOL bResult;
int err;
DWORD numRead;
while (++i)
{
// 读取一个单字符
bResult = ReadFile(
(HANDLE)login->sock,
login->InBuffer,
1,
&numRead,
&login->ovIn);
// 这里,等待一个信息包.
if (bResult) return;
err = GetLastError();
// 获取状态,这里并不代表错误
if (err == ERROR_IO_PENDING)
return;
if ( err == ERROR_INVALID_USER_BUFFER ||
err == ERROR_NOT_ENOUGH_QUOTA ||
err == ERROR_NOT_ENOUGH_MEMORY )
{
if (i == 5)
{
Sleep(50); // 等待并重试
continue;
}
}
break;
}
}
//
// 确保我们运行在正确的版本下 Windows 2003 Server (sp1, or later)
//
BOOL CheckOsVersion()
{
OSVERSIONINFO ver;
BOOL bResult;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult = GetVersionEx((LPOSVERSIONINFO) &ver);
if ((!bResult) ||
(ver.dwPlatformId != VER_PLATFORM_WIN32_NT))
{
MessageBox(NULL, "You Must Have Windows 2003 Server Sp1 or Later\n", "信息", 0);
return FALSE;
}
return TRUE;
}
DWORD WINAPI ThreadFunc(LPVOID pVoid)
{
BOOL bResult;
DWORD dwNumRead;
struct logindata *pCntx;
LPOVERLAPPED lpOverlapped;
char tmp[50];
UNREFERENCED_PARAMETER(pVoid);
// 无限循环从 I/O completion port 获取信息.
for (;;)
{
bResult = GetQueuedCompletionStatus(
ghCompletionPort,
&dwNumRead,
&(DWORD)pCntx,
&lpOverlapped,
INFINITE
);
if (bResult == FALSE
&& lpOverlapped == NULL)
{
// FatalError(
// "ThreadFunc - GetQueuedCompletionStatus()错误.\n");
}
else if (bResult == FALSE
&& lpOverlapped != NULL)
{
// sprintf(tmp, "bResult == FALSE lpOverlapped != NULL %d\n", pCntx->sock);
// SaveLog(tmp);
if (closeusersocket(pCntx->sock) == -1)
CloseHandle(pCntx->ovOut.hEvent);
}
else if (dwNumRead == 0)
{
// sprintf(tmp, "dwNumRead == 0 %d\n", pCntx->sock);
// SaveLog(tmp);
if (closeusersocket(pCntx->sock) == -1)
CloseHandle(pCntx->ovOut.hEvent);
}
else
{
pCntx->OutBuffer[pCntx->nOutBufIndex++] = pCntx->InBuffer[0];
if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55)) && (pCntx->nOutBufIndex == 2))
{
memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer));
pCntx->nOutBufIndex = 0;
}
if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55) || (((BYTE)pCntx->OutBuffer[4] != 0xD5) && ((BYTE)pCntx->OutBuffer[4] != 0xF9))) && (pCntx->nOutBufIndex==5))
{
memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer));
pCntx->nOutBufIndex = 0;
}
if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&
((int)(BYTE)pCntx->OutBuffer[2] + (int)(BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex==8))
{
if ((BYTE)pCntx->OutBuffer[4] == 0xD5)
{
memset(tmp, 0x00, sizeof(tmp));
tmp[0] = (char)0xAA;
tmp[1] = (char)0x55;
tmp[2] = (char)0x0A;
tmp[3] = (char)0x00;
tmp[4] = (char)0xD6;
tmp[5] = (char)0x10;
tmp[6] = (char)0x10;
tmp[7] = (char)0x10;
tmp[8] = (char)0x10;
tmp[9] = (char)0x10;
tmp[10] = (char)0x10;
tmp[11] = (char)0x10;
tmp[12] = (char)0x10;
tmp[13] = (char)0x01;
tmp[14] = (char)0x55;
tmp[15] = (char)0xAA;
send(pCntx->sock, tmp, 16, 0);
memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer));
pCntx->nOutBufIndex = 0;
}
}
else if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&
((BYTE)pCntx->OutBuffer[2] + (BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex>=12))
{
analysedata(pCntx, pCntx->OutBuffer, pCntx->nOutBufIndex);
memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer));
pCntx->nOutBufIndex = 0;
}
// 开始读取
ReadPack(pCntx);
}
}
return 0;
}
void CreateWorkerThreads()
{
SYSTEM_INFO sysinfo;
#ifdef _CLIBTHREAD
UINT dwThreadId;
#else
DWORD dwThreadId;
#endif
DWORD dwThreads;
DWORD i;
GetSystemInfo(&sysinfo);
dwThreads = sysinfo.dwNumberOfProcessors * option.thread + 2;
for (i=0; isock = newsocket;
pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//为写信息包过程设置(事件对象) event .
pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1);
CreateIoCompletionPort( //为请求绑定端口
(HANDLE)newsocket,
ghCompletionPort,
(DWORD)pKey,
0);
ReadPack(pKey); // 完成第一次读操作
sprintf(tmp, "%d.%d.%d.%d 连接", clientAddress.sin_addr.S_un.S_un_b.s_b1,
clientAddress.sin_addr.S_un.S_un_b.s_b2,
clientAddress.sin_addr.S_un.S_un_b.s_b3,
clientAddress.sin_addr.S_un.S_un_b.s_b4);
InsertLogMsg(tmp);
}
// uninstallsqldata();
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// HACCEL hAccelTable;
char szfilepath[256];
char szfilename[256];
char tmp[100];
// Initialize global strings
GetExeDir(szfilepath);
sprintf(szfilename, "%sservergame.ini", szfilepath);
GetPrivateProfileString("SERVER", "PORT", "", tmp, 24, szfilename);
option.port = atoi(tmp);
GetPrivateProfileString("ODBC", "ACCOUNT_DSN", "", option.accountdsn, 24, szfilename);
GetPrivateProfileString("ODBC", "ACCOUNT_UID", "", option.accountuid, 24, szfilename);
GetPrivateProfileString("ODBC", "ACCOUNT_PWD", "", option.accountpwd, 24, szfilename);
GetPrivateProfileString("ODBC", "CHAR_DSN", "", option.chardsn, 24, szfilename);
GetPrivateProfileString("ODBC", "CHAR_UID", "", option.charuid, 24, szfilename);
GetPrivateProfileString("ODBC", "CHAR_PWD", "", option.charpwd, 24, szfilename);
GetPrivateProfileString("ODBC", "DOOR_DSN", "", option.doordsn, 24, szfilename);
GetPrivateProfileString("ODBC", "DOOR_UID", "", option.dooruid, 24, szfilename);
GetPrivateProfileString("ODBC", "DOOR_PWD", "", option.doorpwd, 24, szfilename);
GetPrivateProfileString("ODBC", "WAREHOUSE_DSN", "", option.warehousedsn, 24, szfilename);
GetPrivateProfileString("ODBC", "WAREHOUSE_UID", "", option.warehouseuid, 24, szfilename);
GetPrivateProfileString("ODBC", "WAREHOUSE_PWD", "", option.warehousepwd, 24, szfilename);
GetPrivateProfileString("ODBC", "INFO_DSN", "", option.infodsn, 24, szfilename);
GetPrivateProfileString("ODBC", "INFO_UID", "", option.infouid, 24, szfilename);
GetPrivateProfileString("ODBC", "INFO_PWD", "", option.infopwd, 24, szfilename);
GetPrivateProfileString("ODBC", "LUMP_DSN", "", option.lumpdsn, 24, szfilename);
GetPrivateProfileString("ODBC", "LUMP_UID", "", option.lumpuid, 24, szfilename);
GetPrivateProfileString("ODBC", "LUMP_PWD", "", option.lumppwd, 24, szfilename);
GetPrivateProfileString("ODBC", "LOG_DSN", "", option.logdsn, 24, szfilename);
GetPrivateProfileString("ODBC", "LOG_UID", "", option.loguid, 24, szfilename);
GetPrivateProfileString("ODBC", "LOG_PWD", "", option.logpwd, 24, szfilename);
GetPrivateProfileString("SYSTEM", "CPUTHREAD", "", tmp, 24, szfilename);
option.thread = atoi(tmp);
GetPrivateProfileString("GAME", "MAXONLINE", "", tmp, 24, szfilename);
option.max_online = atoi(tmp);
GetPrivateProfileString("GAME", "GAMESPEED", "", tmp, 24, szfilename);
option.speed_number = atoi(tmp);
GetPrivateProfileString("GAME", "WELCOMEINFO", "", tmp, 100,szfilename);
strcpy(option.welcomeinfo, tmp);
GetPrivateProfileString("TEST", "NOW", "", tmp, 24, szfilename);
option.testnow = atoi(tmp);
GetPrivateProfileString("TEST", "ME1", "", tmp, 24, szfilename);
option.menow1 = atoi(tmp);
GetPrivateProfileString("TEST", "ME2", "", tmp, 24, szfilename);
option.menow2 = atoi(tmp);
GetPrivateProfileString("TEST", "X", "", tmp, 24, szfilename);
option.now_x = atoi(tmp);
GetPrivateProfileString("TEST", "Y", "", tmp, 24, szfilename);
option.now_y = atoi(tmp);
if (!CheckOsVersion())
return 0;
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SERVERGAME);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_GLOBALCLASS|CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIcon = LoadIcon((HINSTANCE)hInstance, MAKEINTRESOURCE(IDI_SERVERGAME));
wc.hInstance = (HINSTANCE)hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszClassName = _GAME_SERVER_CLASS;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
DWORD dwStyle;
int i;
int nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS];
int nCnt;
RECT rcMainWnd, rcToolBar, rcStatusBar;
LV_COLUMN lvc;
char szText[64];
INITCOMMONCONTROLSEX icex;
hInst = hInstance;
dwStyle = WS_THICKFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
//OleInitialize(NULL);
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES | ICC_INTERNET_CLASSES | ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
option.hMainWnd = CreateWindowEx(0, _GAME_SERVER_CLASS, _GAME_SERVER_TITLE,
dwStyle | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, (HINSTANCE)hInstance, NULL);
option.hToolBar = CreateToolbarEx(option.hMainWnd, WS_CHILD|CCS_TOP|WS_VISIBLE|SBS_SIZEGRIP,
_IDW_TOOLBAR, sizeof(tbButtons) / sizeof(TBBUTTON), (HINSTANCE)hInstance, IDB_TOOLBAR,
(LPCTBBUTTON)&tbButtons, sizeof(tbButtons) / sizeof(TBBUTTON),
_BMP_CX, _BMP_CY, _BMP_CX, _BMP_CY, sizeof(TBBUTTON));
GetClientRect(option.hMainWnd, &rcMainWnd);
GetWindowRect(option.hToolBar, &rcToolBar);
option.hStatusBar = CreateWindowEx(0L, STATUSCLASSNAME, _T(""), WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP,
0, rcMainWnd.bottom - _STATUS_HEIGHT, (rcMainWnd.right - rcMainWnd.left), _STATUS_HEIGHT, option.hMainWnd, (HMENU)_IDW_STATUSBAR, hInst, NULL);
nCnt = 0;
for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0; i--)
nStatusPartsWidths[nCnt++] = (rcMainWnd.right - rcMainWnd.left) - (90 * i);
SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths);
SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(0, 0), (LPARAM)_TEXT("服务器关闭"));
SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(1, 0), (LPARAM)_TEXT("在线 0 人"));
SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(2, 0), (LPARAM)_TEXT("怪物 0 个"));
SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(3, 0), (LPARAM)_TEXT("矿石 0 个"));
GetWindowRect(option.hStatusBar, &rcStatusBar);
option.hLogMsgWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, _TEXT(""),
WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS,
0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMainWnd.right - rcMainWnd.left),
(rcMainWnd.bottom - rcMainWnd.top) - (rcToolBar.bottom - rcToolBar.top) + 2
- (rcStatusBar.bottom - rcStatusBar.top),
option.hMainWnd, NULL, (HINSTANCE)hInstance, NULL);
ListView_SetExtendedListViewStyleEx(option.hLogMsgWnd, 0, LVS_EX_FULLROWSELECT);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 100;
lvc.pszText = szText;
for (i = 0; i < 3; i++)
{
lvc.iSubItem = i;
LoadString((HINSTANCE)hInstance, IDS_LVS_LABEL1 + i, szText, sizeof(szText));
ListView_InsertColumn(option.hLogMsgWnd, i, &lvc);
}
ListView_SetColumnWidth(option.hLogMsgWnd, 2, 220 );
SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STOPSERVICE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
ShowWindow(option.hMainWnd, SW_SHOW);
UpdateWindow(option.hMainWnd);
InvalidateRect(option.hMainWnd, NULL, TRUE );
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rcToolBar, rcMain, rcStatusBar;
int nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS];
int i, nCnt;
TCHAR szMsg[128];
TCHAR szTitle[128];
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
OnCommand(wParam, lParam);
return TRUE;
/* case WM_ERASEBKGND:
return TRUE;
case WM_PAINT:
return TRUE;
*/
case WM_SIZE:
{
if (option.hToolBar && option.hMainWnd && option.hStatusBar)
{
GetWindowRect(option.hToolBar, &rcToolBar);
GetClientRect(option.hMainWnd, &rcMain);
GetWindowRect(option.hStatusBar, &rcStatusBar);
MoveWindow(option.hToolBar, 0, 0, LOWORD(lParam), (rcToolBar.bottom - rcToolBar.top), TRUE);
MoveWindow(option.hStatusBar, 0, rcMain.bottom - (rcStatusBar.bottom - rcStatusBar.top),
LOWORD(lParam), (rcStatusBar.bottom - rcStatusBar.top), TRUE);
MoveWindow(option.hLogMsgWnd, 0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMain.right - rcMain.left),
(rcMain.bottom - rcMain.top) - (rcToolBar.bottom - rcToolBar.top) - (rcStatusBar.bottom - rcStatusBar.top) + 2,
TRUE);
nCnt = 0;
for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0 ; i--)
nStatusPartsWidths[nCnt++] = (rcStatusBar.right - rcStatusBar.left) - (90 * i);
SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths);
// InvalidateRect(option.hStatusBar, NULL, TRUE );
// ShowWindow(option.hStatusBar, SW_SHOW);
}
break;
}
case WM_CLOSE:
{
LoadString(hInst, IDS_PROGRAM_QUIT, szMsg, sizeof(szMsg));
LoadString(hInst, IDS_PROGRAM_TITLE, szTitle, sizeof(szTitle));
if (MessageBox(option.hMainWnd, szMsg, szTitle, MB_ICONINFORMATION|MB_YESNO) == IDYES)
{
// ClearServerSocket();
// DisconnectFromServer();
// savelumpinfo(Lump_info);
saveserveruser();
OnCommand(IDM_STOPSERVICE, 0L);
// save_map_image();
// CoUninitialize();
WSACleanup();
PostQuitMessage(0);
}
return 0L;
}
}
return (DefWindowProc(hWnd, message, wParam, lParam));
}
// Mesage handler for about box.
LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
}
return TRUE;
}
return FALSE;
}
LRESULT CALLBACK InfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
char tmp[255];
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg, IDC_EDIT, "服务器10分钟后重新启动, 请下线.");
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_SEND)
{
GetDlgItemText(hDlg, IDC_EDIT, tmp, 255);
speakalluser(tmp);
}
return TRUE;
case WM_CLOSE:
EndDialog(hDlg, FALSE);
return TRUE;
}
return FALSE;
}