📄 netsocket.cpp
字号:
// NetSocket.cpp : implementation file
//
#include "stdafx.h"
#include "Netmsg.h"
#include "NetSocket.h"
#include "ContactView.h"
#include "Conversation.h"
#include "ConversationThread.h"
#include "SoundThread.h"
#include "FileSend.h"
#include <mmsystem.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//The class for contact sockets
CNetSocket::CNetSocket()
{
m_nTimeOut = 5000;
Contact = NULL;
m_pFile = NULL;
m_pArchiveIn = NULL;
m_pArchiveOut = NULL;
GetApp()->Sockets.AddTail(this);
}
CNetSocket::CNetSocket(CContact *contact)
{
m_nTimeOut = 5000;
Contact = contact;
if (Contact->GetSock())
{
if (Contact->GetSock() != this)
{
if (::IsSocket(Contact->GetSock()))
delete Contact->GetSock();
}
}
Contact->SetSock(this);
m_pFile = NULL;
m_pArchiveIn = NULL;
m_pArchiveOut = NULL;
GetApp()->Sockets.AddTail(this);
}
CNetSocket::~CNetSocket()
{
if (m_pArchiveOut != NULL)
{
m_pArchiveOut->Abort();
delete m_pArchiveOut;
m_pArchiveOut = NULL;
}
if (m_pArchiveIn != NULL)
{
m_pArchiveIn->Abort();
delete m_pArchiveIn;
m_pArchiveIn = NULL;
}
if (m_pFile != NULL)
delete m_pFile;
GetApp()->Sockets.RemoveAt(GetApp()->Sockets.Find(this));
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CNetSocket, CSocket)
//{{AFX_MSG_MAP(CNetSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CNetSocket member functions
void CNetSocket::OnClose(int nErrorCode)
{
CSocket::OnClose(nErrorCode);
if (Contact->Flags & CFL_AUTHENTICATE_NO)
{
GetApp()->View->DeleteContact(Contact);
return;
}
Contact->SignOffline();
}
void CNetSocket::Init()
{
m_pFile = new CSocketFile(this);
m_pArchiveIn = new CArchive(m_pFile, CArchive::load);
m_pArchiveOut = new CArchive(m_pFile, CArchive::store);
}
void CNetSocket::OnReceive(int nErrorCode)
{
if (!IsSocket(this))
return;
CSocket::OnReceive(nErrorCode);
TRY
{
do
{
CContact *pContact = Contact;
CString tmp;
m_pArchiveIn->ReadString(tmp);
#ifdef _DEBUG
FILE *f = fopen("socklog.txt", "a");
if (f)
{
fprintf(f, "IN: %s [%s]: %s\n", Contact->GetScreenName(), Contact->GetHostName().Get(), tmp);
fclose(f);
}
#endif
Process(tmp);
if (!IsSocket(this))
return; //this class was destroyed while we were processing, get out.
}
while (!m_pArchiveIn->IsBufferEmpty());
}
CATCH(CFileException, e)
{
m_pArchiveOut->Abort();
return;
}
END_CATCH
}
void CNetSocket::SendString(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
SendStringV(fmt, args);
}
void CNetSocket::SendStringV(char *fmt, va_list args)
{
if (!IsSocket(this))
return;
if (!CAsyncSocket::FromHandle(m_hSocket))
return;
CString Sends;
Sends.FormatV(fmt, args);
Sends += "\n";
TRY
{
#ifdef _DEBUG
FILE *f = fopen("socklog.txt", "a");
if (f)
{
fprintf(f, "OUT: %s [%s]: %s", Contact->GetScreenName(), Contact->GetHostName().Get(), Sends);
fclose(f);
}
#endif
m_pArchiveOut->WriteString(Sends);
m_pArchiveOut->Flush();
}
CATCH (CFileException, e)
{
m_pArchiveOut->Abort();
return;
}
END_CATCH
}
bool CNetSocket::Open()
{
if (!Create()) return false;
if (!Contact) return false;
if (!Connect(Contact->GetHostName().Get(), 8400)) return false;
m_pFile = new CSocketFile(this);
Contact->WeConnected = true;
m_pArchiveIn = new CArchive(m_pFile, CArchive::load);
m_pArchiveOut = new CArchive(m_pFile, CArchive::store);
Contact->SetSock(this);
::SendMyOnline(Contact);
return true;
}
void ::SendMyOnline(CContact *To)
{
char font[512];
uital2(&GetApp()->View->Me.uFont, sizeof(USERFONT), font);
if (!To)
{
SendToAllOnline(false, false, "NAME %s", GetApp()->View->Me.GetScreenName());
if (GetApp()->View->Me.IsAway())
SendToAllOnline(false, false, "AWAY %s", GetApp()->View->Me.GetAwayReason());
SendToAllOnline(false, false, "FONT %s", font);
}
else
{
if ((To->IsBlocked()) || (GetApp()->View->Me.IsOffline())) return;
if (!IsSocket(To->GetSock())) return;
To->GetSock()->SendString("NAME %s", GetApp()->View->Me.GetScreenName());
if (GetApp()->View->Me.IsAway())
To->GetSock()->SendString("AWAY %s", GetApp()->View->Me.GetAwayReason());
To->GetSock()->SendString("FONT %s", font);
}
}
void CNetSocket::Process(CString data)
{
if (!IsSocket(this))
return;
char Data[2128];
strcpy(Data, data);
char Process[64], Message[2048];
strcpy(Process, strtok(Data, " "));
char *msg = strtok(NULL, "");
if (msg) strcpy(Message, msg);
else strcpy(Message, "");
if (!strcmp(Process, "NAME"))
{
Contact->SetScreenName(Message);
GetApp()->View->BuildList();
if (Contact->IsOnline()) return;
if (Contact->Flags & CFL_AUTHENTICATE_NO)
{
Contact->Flags &= ~CFL_AUTHENTICATE_NO;
char buf[512];
sprintf(buf, "A connection from %s was recieved, \
this address is not in your contact list, do you wish to add it? \
If not the contact will remain on your list blocked.", Contact->GetHostName().Get());
if (MessageBox(GetApp()->View->mainWnd->GetSafeHwnd(), buf,
"New Contact", MB_YESNO|MB_ICONQUESTION) == IDYES)
{
if (!IsSocket(this)) return;
}
else
{
if (!IsSocket(this)) return;
Contact->Flags |= CFL_BLOCKED;
}
::SendMyOnline(Contact);
}
Contact->ShowOnline();
return;
}
else if (!strcmp(Process, "OFFLINE"))
{
Contact->WeConnected = false;
if (Contact->IsOffline()) return;
Contact->ShowOffline();
return;
}
else if (!strcmp(Process, "MESSAGE"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsConvWindowOpen())
{
Contact->pThread->Conv->SendMessage(WM_RECEIVEDMESSAGE, 0, (LPARAM) nstrdup(Message));
}
else
{
GetApp()->View->NewConversation(Contact, nstrdup(Message));
}
return;
}
else if (!strcmp(Process, "TYPING"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsConvWindowOpen())
{
Contact->pThread->Conv->SendMessage(WM_TYPENOTIFY, 1, 0);
}
return;
}
else if (!strcmp(Process, "NOTTYPING"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsConvWindowOpen())
{
Contact->pThread->Conv->SendMessage(WM_TYPENOTIFY, 0, 0);
}
return;
}
else if (!strcmp(Process, "FILE"))
{
char buf[1024], len[64], port[64], filename[1024], *tport, *tlen, *tfilename;
CContact *pContact = Contact;
tport = strtok(Message, " ");
tlen = strtok(NULL, " ");
tfilename = strtok(NULL, "");
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (!tport || !tlen || !tfilename)
{
SendString("ERROR Invalid FONT format");
return;
}
else if (atoi(tport) < 1 || strtoul(tlen, NULL, 10) <= 0 || !stricmp(tfilename, ""))
{
SendString("ERROR Invalid FONT format");
return;
}
strcpy(port, tport);
strcpy(len, tlen);
strcpy(filename, tfilename);
sprintf(buf, "The user %s is trying to send you a file called '%s', click OK to accept or Cancel to decline", Contact->GetScreenName(), filename);
int result = MessageBox(Contact->IsConvWindowOpen() ? Contact->pThread->Conv->GetSafeHwnd() :
GetApp()->View->GetSafeHwnd(), buf, "File transfer", MB_OKCANCEL|MB_ICONINFORMATION);
if (!IsSocket(this))
return;
if (result == IDOK)
{
if (pContact->IsOffline())
{
MessageBox(NULL, "This user has gone offline", "Send file", MB_OK|MB_ICONSTOP);
return;
}
SendString("FILEXFEROK");
GetApp()->View->StartFileTransfer(GetApp()->View->GetSafeHwnd(), Contact, false, filename, atoi(port), strtoul(len, NULL, 10));
}
else
{
if (pContact->IsOffline())
{
return;
}
SendString("FILEXFERCANCEL");
}
return;
}
else if (!strcmp(Process, "FONT"))
{// this could reeally go wrong if something was sent wrong, use SOME checking.
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (strlen(Message) != (sizeof(USERFONT) * 2))
{
SendString("ERROR Bad USERFONT size");
return;
}
else
{
uifal2(&Contact->uFont, sizeof(USERFONT), Message);
PluginsContactStatusChanged(Contact, CT_FONT);
}
}
else if (!strcmp(Process, "FILEXFEROK"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsTransfering())
{
if (Contact->Transfer->Sending)
Contact->Transfer->TransferAccepted();
}
return;
}
else if (!strcmp(Process, "FILEXFERCANCEL"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsTransfering())
{
if (Contact->Transfer->Sending)
Contact->Transfer->TransferFailed();
}
return;
}
else if (!strcmp(Process, "CANCELXFER"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
if (Contact->IsTransfering())
Contact->Transfer->TransferFailed();
return;
}
else if (!strcmp(Process, "TRANSFERCOMPLETE"))
{
//we don't need to be told this anymore, leave for protoctl compatibility
}
else if (!strcmp(Process, "AWAY"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
Contact->SetAway(true, Message);
}
else if (!strcmp(Process, "BACK"))
{
if (Contact->IsBlocked())
{
SendString("ERROR You are blocked");
return;
}
Contact->SetAway(false, Message);
}
else if (!strcmp(Process, "ERROR"))
{
#ifdef _DEBUG
FILE *f = fopen("socklog.txt", "a");
if (f)
{
fprintf(f, "ERROR: %s [%s]: %s\n", Contact->GetScreenName(), Contact->GetHostName().Get(), Message);
fclose(f);
}
#endif
}
}
bool ::IsSocket(CNetSocket *Sock)
{
if (!Sock) return false;
POSITION pos;
pos = GetApp()->Sockets.GetHeadPosition();
while (pos)
{
if (GetApp()->Sockets.GetNext(pos) == Sock)
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -