summaryrefslogtreecommitdiff
path: root/MySpace/server_con.cpp
blob: f3c6d79dcc4da86675d82bb334ab7226c844d390 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "common.h"
#include "server_con.h"
#include "net.h"

#include "NetMessage.h"

#define SERVER_READ_BUFFER_SIZE				(1024 * 32)

int status = ID_STATUS_OFFLINE;
bool server_running = false, server_stop = false;
HANDLE server_connection = 0;

void CALLBACK sttMainThreadStatusCallback( ULONG dwParam ) {
	if(status != dwParam) {
		int previous_status = status;
		status = dwParam;
		ProtoBroadcastAck(MODULE,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previous_status, status);
	}
}

int waitcallback(unsigned int *timeout) {
	PUShowMessage("waitcallback", SM_NOTIFY);
	return server_stop ? 0 : 1;
}

int try_ports[9] = {1863, 6660,6661,6662,6665,6668,6669,80,0443};

void __cdecl ServerThreadFunc(void*) {
	NETLIBOPENCONNECTION conn_data = {0};
	conn_data.cbSize = sizeof(NETLIBOPENCONNECTION);
	conn_data.flags = NLOCF_V2;
	conn_data.szHost = "im.myspace.akadns.net";
	conn_data.wPort = DBGetContactSettingDword(0, MODULE, "LastPort", try_ports[0]);
	conn_data.timeout = 10;
	conn_data.waitcallback = waitcallback;

	QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_CONNECTING);		

	server_running = true;

	char *recv_buffer = new char[SERVER_READ_BUFFER_SIZE];
	int bytes = 0;
	char mt[256];
	int tries = 0;
	bool login = true;

	while(!Miranda_Terminated() && !server_stop) {
		if(login) {
			if(server_connection) Netlib_CloseHandle(server_connection);
			server_connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data);
		}
		bytes = Netlib_Recv(server_connection, (char *)recv_buffer, SERVER_READ_BUFFER_SIZE, MSG_DUMPASTEXT);

		if(bytes == 0) {
			PUShowMessage("Connection closed", SM_NOTIFY);
			if(login && tries < 9) {
				conn_data.wPort = try_ports[tries++];
			} else
				break;
		} else if(bytes == SOCKET_ERROR) {
			PUShowMessage("Socket ERROR", SM_NOTIFY);
			break;
		} else {
			if(login) {
				login = false;
				QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_ONLINE);
			}

			mir_snprintf(mt, 256, "recvd %d bytes", bytes);
			PUShowMessage(mt, SM_NOTIFY);

			NetMessage msg;
			msg.parse(recv_buffer, bytes);
			if(msg.exists(NMString("lc"))) {
				NMString val;
				msg.get(NMString("lc"), val);
				mir_snprintf(mt, 256, "Login message: type is %s", val.text);
				PUShowMessage(mt, SM_NOTIFY);
				// challenge/response:
				// 
			} else if(msg.exists(NMString("persistr"))) {
				NMString cmd, dsn, lid;
				msg.get(NMString("cmd"), cmd);
				msg.get(NMString("dsn"), dsn);
				msg.get(NMString("lid"), lid);
				mir_snprintf(mt, 256, "Perist message: type is %s,%s,%s", cmd.text, dsn.text, lid.text);
				PUShowMessage(mt, SM_NOTIFY);
			}
		}
	}
	if(server_connection) {
		Netlib_CloseHandle(server_connection);
		server_connection = 0;
	}
	delete recv_buffer;

	QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_OFFLINE);	
	server_running = false;
}

void StartThread() {
	if(!server_running) {
		server_stop = false;
		mir_forkthread(ServerThreadFunc, 0);
	}
}

void StopThread() {
	if(server_running) {
		server_stop = true;
		if(server_connection) {
			Netlib_CloseHandle(server_connection);
			server_connection = 0;
		}
	}
}

void InitServerConnection() {
	StartThread();
}

void DeinitServerConnection() {
	StopThread();
}