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();
}
|