📄 server.cpp
字号:
// server.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "server.h"
#include "MainFrm.h"
#include "common.h"
#include "serverDoc.h"
#include "serverView.h"
#include "Clog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CServerApp
BEGIN_MESSAGE_MAP(CServerApp, CWinApp)
//{{AFX_MSG_MAP(CServerApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
//ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
//ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerApp construction
CServerApp::CServerApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CServerApp object
CServerApp theApp;
CMainFrame *pFrame;
/////////////////////////////////////////////////////////////////////////////
// CServerApp initialization
BOOL CServerApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
PlayerCount = 0;
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CServerDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CServerView));
pDocTemplate->SetContainerInfo(IDR_CNTR_INPLACE);
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
GetCurrentDirectory(MAX_PATH,ch_RunPath);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
pFrame = (CMainFrame*)AfxGetMainWnd();
ReadScoreRecordFromFile(GetUniteStr(ch_RunPath,"\\score.txt"));
CreateServerSocket();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CServerApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CServerApp message handlers
BOOL CServerApp::CreateServerSocket()
{
MsgBufferCount = 0;
PlayerAdding = FALSE;
cs_Server=new CServerSocket;
if(cs_Server==NULL)
{
WarningBox("Create Sever Socket Failed!");
return FALSE;
}
uint_nPort = 8000;
cs_Server->Create(uint_nPort);
GetHostName(ch_HostName);
GetHostIP(ch_HostAdr);
ServerLog.AddLogInfoToBuffer("Create Sever Socket Successful");
ServerLog.AddLogInfoToBuffer(GetUniteStr("Host IP : ",ch_HostAdr));
ServerLog.AddLogInfoToBuffer(GetUniteStr("Host Name : ",ch_HostName));
ServerLog.AddLogInfoToBuffer(GetUniteStr("Port : ",NumToStr(uint_nPort)));
cs_Server->Listen();
ServerLog.AddLogInfoToBuffer("Begin Listening .....");
return TRUE;
}
void CServerApp::EndServerSocket()
{
for(int i=0;i<PlayerCount;i++)
{
PlayerInfo[i].cs_ClientPtr->Close();
delete PlayerInfo[i].cs_ClientPtr;
}
cs_Server->Close();
delete cs_Server;
}
int CServerApp::ExitInstance()
{
// TODO: Add your specialized code here and/or call the base class
ServerLog.ClearLogBuffer();
EndServerSocket();
return CWinApp::ExitInstance();
}
BOOL CServerApp::AddNewPlayer()
{
CReceiveSocket *cs_NewPlayer;
cs_NewPlayer = new CReceiveSocket;
SOCKADDR SockAddr;
int int_AddrLen=16;
if(cs_Server->Accept(*cs_NewPlayer,&SockAddr,&int_AddrLen))
{
SockAddrToIPStr(&SockAddr,cs_NewPlayer->ch_PlayerIP);
cs_NewPlayer->PlayerNo = PlayerCount;
PlayerInfo[PlayerCount].cs_ClientPtr = cs_NewPlayer;
cs_NewPlayer->bo_CreateGame = FALSE;
cs_NewPlayer->bo_GameRunning = FALSE;
pFrame->AddPlayerInfoToTable(cs_NewPlayer);
PlayerCount++;
}
else
{
ServerLog.AddLogInfoToBuffer("New Guest Login Failed ,Server Accept Failed");
return FALSE;
}
return TRUE;
}
BOOL CServerApp::GetNewPlayerName(CReceiveSocket *cs_NewPlayer)
{
LOGIN_INFO rLoginInfo;
//设置列表中的名字
cs_NewPlayer->Receive(&rLoginInfo,sizeof(LOGIN_INFO),0);
strcpy(cs_NewPlayer->ch_PlayerName,rLoginInfo.ch_Name);
pFrame->SetPlayerNameInTable(cs_NewPlayer);
//发送游戏列表
SendGameListMsg(cs_NewPlayer,FALSE);
SendNewPlayerToAll(cs_NewPlayer);
//显示登录成功
char ch_LogStr[36];
strcpy(ch_LogStr,cs_NewPlayer->ch_PlayerIP);
strcat(ch_LogStr," Login Successful");
ServerLog.AddLogInfoToBuffer(ch_LogStr);
return TRUE;
}
BOOL CServerApp::DeletePlayer(CReceiveSocket *cs_Player)
{
int PlayerNo = cs_Player->PlayerNo;
//显示玩家离去信息
char *ch_ShowStr=new char[64];
strcpy(ch_ShowStr,cs_Player->ch_PlayerIP);
if(cs_Player->bo_GameRunning)
{
strcat(ch_ShowStr," Run Game and ");
}
strcat(ch_ShowStr," Exit ");
ServerLog.AddLogInfoToBuffer(ch_ShowStr);
delete[] ch_ShowStr;
pFrame->DeletePlayerInfoFromTable(PlayerNo);
delete cs_Player;
cs_Player = NULL;
for(int i=PlayerNo;i<PlayerCount-1;i++)
{
PlayerInfo[i].cs_ClientPtr = PlayerInfo[i+1].cs_ClientPtr;
PlayerInfo[i].cs_ClientPtr->PlayerNo--;
}
PlayerCount--;
return TRUE;
}
BOOL CServerApp::SendPlayerChatMsg(char *ch_ChatMsg,CReceiveSocket *cs_Player)
{
int int_MsgSize=*(ch_ChatMsg+1);
int int_ContentSize = int_MsgSize - 3;
int int_NameLength=strlen(cs_Player->ch_PlayerName);
int_MsgSize+=(int_NameLength+1); //名字长度加上:长度
char *ch_FullChatMsg=new char[int_MsgSize];
*(ch_FullChatMsg+0)=MSGTYPE_CHAT;
*(ch_FullChatMsg+1)=int_MsgSize;
char *ch_Ptr=ch_FullChatMsg+2;
strcpy(ch_Ptr,cs_Player->ch_PlayerName);
ch_Ptr+=int_NameLength;
strcpy(ch_Ptr,":");
ch_Ptr+=1;
memcpy(ch_Ptr,ch_ChatMsg+2,int_ContentSize);
ch_Ptr+=int_ContentSize;
strcpy(ch_Ptr,"");
for(int i=0;i<PlayerCount;i++)
{
PlayerInfo[i].cs_ClientPtr->Send(ch_FullChatMsg,int_MsgSize,0);
}
delete[] ch_FullChatMsg;
return TRUE;
}
BOOL CServerApp::SendGameListMsg(CReceiveSocket *cs_Client,BOOL bo_ToAll)
{
char *ch_GameList = new char[MAX_MESSAGE];
char *ch_Ptr = ch_GameList;
*(ch_GameList+0) = MSGTYPE_GAMESERVERLIST;
ch_Ptr+=2;
int n = 0;
int int_IpSize;
int int_NameSize;
int i=0;
CReceiveSocket *cs_OtherPlayer;
for(i=0;i<PlayerCount-1;i++)
{
cs_OtherPlayer = PlayerInfo[i].cs_ClientPtr;
if(cs_OtherPlayer->bo_CreateGame && !cs_OtherPlayer->bo_GameRunning)
{
int_IpSize = strlen(cs_OtherPlayer->ch_PlayerIP);
int_NameSize = strlen(cs_OtherPlayer->ch_PlayerName);
*ch_Ptr = int_IpSize;
ch_Ptr++;
memcpy(ch_Ptr,cs_OtherPlayer->ch_PlayerIP,int_IpSize+1);
ch_Ptr+=int_IpSize;
*ch_Ptr = int_NameSize;
ch_Ptr++;
memcpy(ch_Ptr,cs_OtherPlayer->ch_PlayerName,int_NameSize+1);
ch_Ptr+=int_NameSize;
n++;
if(n>=MAX_GAMESERVER) break;
}
}
if(n==0)
{
n=-1;
}
*(ch_GameList+1)=n;
int Result=0;
if(bo_ToAll)
{
for(i=0;i<PlayerCount;i++)
{
Result = PlayerInfo[i].cs_ClientPtr->Send(ch_GameList,strlen(ch_GameList),0);
}
}
else
{
Result = cs_Client->Send(ch_GameList,strlen(ch_GameList),0);
if(Result == SOCKET_ERROR)
{
return FALSE;
}
}
return TRUE;
}
BOOL CServerApp::HandleMessageBuffer()
{
for(int i=0;i<MsgBufferCount;i++)
{
char *ch_TempBuffer=MsgBuffer[i].MsgBufferPtr;
char MsgType = *(ch_TempBuffer+0);
CReceiveSocket *cs_Player = MsgBuffer[i].cs_Player;
switch(MsgType)
{
case MSGTYPE_GETSCORER:
{
SendScorer(cs_Player);
break;
}
case MSGTYPE_EXIT:
{
theApp.DeletePlayer(cs_Player);
break;
}
case MSGTYPE_CHAT:
{
theApp.SendPlayerChatMsg(ch_TempBuffer,cs_Player);
break;
}
case MSGTYPE_RUNGAME:
{
cs_Player->bo_GameRunning = TRUE;
break;
}
case MSGTYPE_CREATEGAME:
{
cs_Player->bo_CreateGame = TRUE;
ServerLog.AddLogInfoToBuffer(GetUniteStr(cs_Player->ch_PlayerIP," Create Game"));
theApp.SendGameListMsg(cs_Player,TRUE);
break;
}
case MSGTYPE_CANCELGAME:
{
cs_Player->bo_CreateGame = FALSE;
ServerLog.AddLogInfoToBuffer(GetUniteStr(cs_Player->ch_PlayerIP," Cancel Game"));
theApp.SendGameListMsg(cs_Player,TRUE);
break;
}
}
delete[] ch_TempBuffer;
}
MsgBufferCount = 0;
return TRUE;
}
BOOL CServerApp::GetMessageFromPlayerSocket()
{
for(int i=0;i<PlayerCount;i++)
{
if(!PlayerInfo[i].cs_ClientPtr->bo_MessageReceiving)
{
for(int j=0;j<PlayerInfo[i].cs_ClientPtr->MsgBufferCount;j++)
{
MsgBuffer[MsgBufferCount].MsgBufferPtr = PlayerInfo[i].cs_ClientPtr->MsgBuffer[j];
MsgBuffer[MsgBufferCount].cs_Player = PlayerInfo[i].cs_ClientPtr;
MsgBufferCount++;
}
PlayerInfo[i].cs_ClientPtr->MsgBufferCount = 0;
}
}
return TRUE;
}
BOOL CServerApp::OnIdle(LONG lCount)
{
// TODO: Add your specialized code here and/or call the base class
if(!PlayerAdding)
{
HandleMessageBuffer();
GetMessageFromPlayerSocket();
}
return 1;
//return CWinApp::OnIdle(lCount);
}
void CServerApp::ReadScoreRecordFromFile(char *FileName)
{
FILE *fp_Score;
fp_Score = fopen(FileName,"rb");
int n=0;
if(fp_Score!=NULL)
{
char PlayerName[MAX_NAME];
char Resource[10];
char Population[10];
char Military[10];
while(!feof(fp_Score) && n<MAX_SCORE)
{
fscanf(fp_Score,"%s",PlayerName);
fscanf(fp_Score,"%s",Resource);
fscanf(fp_Score,"%s",Population);
fscanf(fp_Score,"%s\n",Military);
strcpy(ScorerInfo.ScorerName[n],PlayerName);
ScorerInfo.Score[n][0] = atol(Resource);
ScorerInfo.Score[n][1] = atol(Population);
ScorerInfo.Score[n][2] = atol(Military);
n++;
}
fclose(fp_Score);
}
for(int i=n;i<MAX_SCORE;i++)
{
strcpy(ScorerInfo.ScorerName[i],"玩家x");
ScorerInfo.Score[i][0] = 1000;
ScorerInfo.Score[i][1] = 1500;
ScorerInfo.Score[i][2] = 2000;
}
}
void CServerApp::SendScorer(CReceiveSocket *cs_Player)
{
ScorerInfo.MsgType = MSGTYPE_SCORER;
cs_Player->Send(&ScorerInfo,sizeof(SCORER_INFO),0);
}
void CServerApp::SendNewPlayerToAll(CReceiveSocket *cs_Player)
{
CReceiveSocket *cs_OtherPlayer;
char NewPlayerMsg[MAX_NAME+1];
char *MsgPtr = NewPlayerMsg+1;
NewPlayerMsg[0] = MSGTYPE_PLAYERIN;
strcpy(MsgPtr,cs_Player->ch_PlayerName);
int n=0;
for(int i=0;i<PlayerCount-1;i++)
{
cs_OtherPlayer = PlayerInfo[i].cs_ClientPtr;
cs_OtherPlayer->Send(NewPlayerMsg,MAX_NAME+1,0);
n++;
if(n>=MAX_GAMESERVER) break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -