ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/Daodan/MSVC/Mariusnet.c
Revision: 587
Committed: Mon Feb 7 05:34:47 2011 UTC (14 years, 8 months ago) by gumby
Content type: text/x-csrc
File size: 14232 byte(s)
Log Message:

File Contents

# Content
1
2 #include <winsock2.h>
3 #include "bool.h"
4 #include "Flatline_Net.h"
5 #include "Flatline_Win32.h"
6 #include "Mariusnet_Defs.h"
7 #include "Daodan_Console.h"
8 #include <stdio.h>
9 #include <inaddr.h>
10 #pragma comment(lib, "wininet.lib")
11
12
13 typedef struct hostent hostent ;
14 typedef struct in_addr in_addr;
15
16 char MariusLogin[32]={0};
17 unsigned char MariusPassword[16]={0};
18
19 m_room RoomList[64] = {0};
20 bool RoomListGotten = 0;
21
22 bool Are_We_Logged_In = 0;
23
24 RGBA blue = {0xFF, 0, 0, 0};
25 RGBA green = {0, 0xFF, 0, 0};
26 RGBA red = {0, 0, 0xFF, 0};
27
28 RGBA grey = {0x80,0x80,0x80,0x80};
29
30 int MariusNet_OutgoingPacketWrapper(int socket, const sockaddr* address, marius_packet* data, short datalen)
31 {
32 data->header.PacketSize = htonl(datalen);
33 //NetUDPSocket_Send( socket, address, (char*)data, sizeof(marius_header) );
34 //datalen -= sizeof(marius_header);
35 //(char*)data += sizeof(marius_header);
36 return NetUDPSocket_Send( socket, address, (char*)data, datalen);
37 }
38
39 int PacketCached = 0;
40 int MariusNet_IncomingPacketWrapper(int socket, char buffer[], int bufferlength, int flags)
41 {
42 int inSize = 0;
43 unsigned fullSize = -1;
44 static char cacheBuffer[1440] = {0};
45 bool NeedMoreData = 0;
46 if(PacketCached)
47 {
48 unsigned int PacketSize = ntohl(((marius_packet*)cacheBuffer)->header.PacketSize);
49 /*
50 if(ntohs(((marius_packet*)cacheBuffer)->header.PacketSignature) != 0xDEAD)
51 {
52 PacketCached = PacketSize = 0;
53 NeedMoreData = 1;
54 }
55 */
56
57
58
59 if(PacketCached >= PacketSize)
60 {
61 memcpy( buffer, cacheBuffer, PacketSize );
62 PacketCached -= PacketSize;
63 }
64 else
65 {
66 memcpy( buffer, cacheBuffer, PacketCached );
67 inSize += PacketCached;
68 NeedMoreData = 1;
69 PacketCached = 0;
70 }
71 if(PacketCached < 0)
72 {
73 DDrConsole_PrintF("Warning, took too much from cache");
74 PacketCached = 0;
75 }
76 else if (PacketCached > 0)// && ntohs((short*)(cacheBuffer + PacketSize)) == 0xDEAD)
77 {
78 memcpy( cacheBuffer, cacheBuffer + PacketSize, PacketCached );
79 }
80 else
81 {
82 memset(cacheBuffer, 0, 1440);
83 }
84
85 if(!NeedMoreData) return PacketSize;
86
87 }
88 do
89 {
90 int tempSize = recv(socket, buffer + inSize, bufferlength, flags);
91 if(tempSize == SOCKET_ERROR)
92 {
93 NetCatchError();
94 return SOCKET_ERROR;
95 }
96
97 if(fullSize == -1)
98 {
99 if(ntohs(((marius_packet*)buffer)->header.PacketSignature) != 0xDEAD)
100 {
101 DDrConsole_PrintF("Bad header signature...closing Mariusnet connection");
102 return SOCKET_ERROR;
103 }
104 fullSize = ntohl(((marius_packet*)buffer)->header.PacketSize);
105 }
106 inSize += tempSize;
107
108 }
109 while(inSize < fullSize);
110
111 //double packet madness
112 if(inSize > fullSize
113 && ntohs(*(short*)(buffer + fullSize)) == 0xDEAD
114 && ntohl(((marius_packet*)(buffer + fullSize))->header.PacketSize) > 0
115 && inSize - fullSize > sizeof(marius_header)
116 )
117 {
118 memcpy(cacheBuffer, buffer + fullSize, inSize - fullSize);
119
120 PacketCached = inSize - fullSize;
121 }
122 else PacketCached = 0;
123 return inSize;
124 }
125
126
127 sockaddr_in Marius_Server;
128
129
130 bool MariusNet_Initialize()
131 {
132 hostent* host_info = 0;
133 //host_info = gethostbyname("myth.mariusnet.com");
134
135 host_info = gethostbyname("metaserver.lhowon.org");
136 if(!host_info)
137 {
138 DDrConsole_PrintF("Error, could not resolve myth.mariusnet.com");
139 return 1;
140 }
141 Marius_Server.sin_port = htons(6321);
142 Marius_Server.sin_family = AF_INET;
143 Marius_Server.sin_addr.S_un.S_addr = *(ULONG*)host_info->h_addr_list[0];
144 return 0;
145 }
146
147 void Initialize_MPacket( marius_packet* packet, short ID )
148 {
149 memset( packet, 0, sizeof(marius_packet) );
150 packet->header.PacketSignature = htons(0xDEAD);
151 packet->header.PacketId = htons(ID);
152
153 }
154
155 void Initialize_LoginPacket( marius_packet* packet)
156 {
157 int NameSize = 0;
158 int TeamSize = 0;
159 char (*test)[] = packet;
160 Initialize_MPacket(packet, pt_PlayerLogin);
161
162 packet->login.UpdateAppearance = 1;
163 packet->login.Platform = htons(1);
164 strncpy(packet->login.LoginId, MariusLogin, 32);
165 packet->login.EncryptionType = htons(1);
166 strcpy(packet->login.AppName, "MARATHON" ); //ONI ;)
167 strncpy(packet->login.BuildDate, __DATE__, 32 );
168 strncpy(packet->login.BuildTime, __TIME__, 32 );
169
170
171 packet->login.PlayerInfo.clientVersion = htons(5000);
172 NameSize = sprintf(packet->login.PlayerInfo.Name, MariusLogin);
173 //TeamSize = sprintf(packet->login.PlayerInfo.Name + NameSize, "TCTF") + 1;
174
175 packet->login.PlayerInfoSize = htons(40 + NameSize + TeamSize);
176 }
177
178 char EncryptionTypes[][32] =
179 {
180 "Plaintext",
181 "Braindead Simple",
182 };
183
184 enum {
185 SyntaxError,
186 GamesNotAllowed,
187 InvalidVersion,
188 BadUserOrPassword,
189 UserNotLoggedIn,
190 BadMetaserverVersion,
191 UserAlreadyLoggedIn,
192 UnknownGameType,
193 LoginSuccessful,
194 LogoutSuccessful,
195 PlayerNotInRoom,
196 GameAlreadyExists,
197 AccountAlreadyLoggedIn,
198 RoomFull,
199 AccountLocked,
200 NotSupported
201 };
202
203 static const char* sRoomNames[] = {
204 "Crows Bridge",
205 "Otter Ferry",
206 "White Falls",
207 "Silvermines",
208 "Shoal",
209 "Madrigal",
210 "Tyr",
211 "Ash",
212 "Scales",
213 "Covenant",
214 "Muirthemne",
215 "Seven Gates",
216 "Bagrada",
217 "The Barrier",
218 "Forest Heart",
219 "The Ermine",
220 "The Dire Marsh",
221 "The Highlands",
222 "The Drowned Kingdom",
223 "The Great Devoid",
224 "Shiver",
225 "The Caterthuns",
226 "Soulblighter",
227 "Balor",
228 "Sons of Myrgard",
229 "Heart of the Stone",
230 "Arrival",
231 "Ingue Ferroque",
232 "Vimy Ridge",
233 "Stilwell Road"
234 };
235 void MSNet_LoginError_Output( int code )
236 {
237 switch(code)
238 {
239 case(BadUserOrPassword):
240 DDrConsole_PrintF( "Login denied: bad username or password." );
241 break;
242 case(UserAlreadyLoggedIn):
243 DDrConsole_PrintF( "Login denied: that user is already logged in.");
244 break;
245 case(AccountAlreadyLoggedIn):
246 DDrConsole_PrintF( "Login denied: that account is already logged in.");
247 break;
248 case(RoomFull):
249 DDrConsole_PrintF( "Login denied: room is full!?");
250 break;
251 case(AccountLocked):
252 DDrConsole_PrintF( "Login denied: your account is locked.");
253 break;
254 default:
255 DDrConsole_PrintF("There was a problem connecting to the server"
256 "that tracks Internet games. Please try again later.");
257 break;
258 }
259
260 }
261 int MSNet_Room_Join( short Room, char* Key)
262 {
263 marius_packet mPacket = {0};
264
265 char incomingData[1400] = {0};
266 marius_packet* incomingPacket = (marius_packet*)incomingData;
267 int sent_bytes = 0;
268
269 sockaddr_in SockAddr;
270 int Room_Socket = NetTCPSocket_Create(RoomList[Room].Port, &SockAddr);
271
272 sockaddr_in RoomAddr = {0};
273 RoomAddr.sin_port = RoomList[Room].Port;
274 RoomAddr.sin_family = AF_INET;
275 RoomAddr.sin_addr.S_un.S_addr = RoomList[Room].IPAddress;
276
277
278
279 DDrConsole_PrintF("Joining room %hi", Room);
280
281 if(Room_Socket == -1)
282 {
283 DDrConsole_PrintF("Failed to initialize room socket!");
284 }
285
286 if(connect( Room_Socket, (sockaddr *)&RoomAddr, sizeof(sockaddr_in)))
287 {
288 NetCatchError();
289 return 1;
290 }
291
292 Initialize_MPacket(&mPacket, pt_ChatRoomLogin);
293 memcpy(mPacket.chatroom_join.RoomKey, Key, 32);
294 strcpy(mPacket.chatroom_join.Name, MariusLogin);
295 sent_bytes = MariusNet_OutgoingPacketWrapper(Room_Socket, (sockaddr*)&RoomAddr, (char*)&mPacket,
296 sizeof(marius_header) + 33 + strlen(MariusLogin));
297
298
299
300 Initialize_MPacket(&mPacket, pt_RoomPlayerInfo);
301 mPacket.player_info.clientVersion = htons(5000);
302 sprintf(mPacket.player_info.Name, MariusLogin);
303 sent_bytes = MariusNet_OutgoingPacketWrapper(Room_Socket, (sockaddr*)&RoomAddr, (char*)&mPacket,
304 sizeof(marius_header) + 40 + strlen(MariusLogin));
305
306 if(MariusNet_IncomingPacketWrapper(Room_Socket, incomingData, 1400, 0) == SOCKET_ERROR)
307 {
308 return 0;
309 }
310
311 if(ntohs(incomingPacket->header.PacketId)== pt_LoginInfo)
312 {
313 //DDrConsole_PrintF("Login failed: %s", incomingPacket->login_denied.DenialMessage );
314 MSNet_LoginError_Output(ntohl(incomingPacket->login_denied.code));
315 return 0;
316 }
317
318 while(1)
319 {
320 if(MariusNet_IncomingPacketWrapper(Room_Socket, incomingData, 1400, 0) == SOCKET_ERROR)
321 {
322 return 0;
323 }
324 switch(ntohs(incomingPacket->header.PacketId))
325 {
326 case pt_RoomList:
327 case pt_PlayerInfo:
328 case pt_GameList:
329 case pt_PlayerList:
330 //Do nothing for now
331 break;
332 case pt_BlueBarMsg:
333 DDrConsole_PrintColored(incomingPacket->motd.Message, 0, blue, grey );
334 break;
335 case pt_ChatMessage:
336 break;
337 case pt_KeepAlive:
338 MariusNet_OutgoingPacketWrapper(Room_Socket, (sockaddr*)&RoomAddr, incomingData,
339 sizeof(marius_header));
340 break;
341 default:
342 DDrConsole_PrintF("Got packet of type %hi", ntohs(incomingPacket->header.PacketId));
343 break;
344 }
345 }
346
347 return 0;
348 }
349
350 DWORD WINAPI MSNet_Handler(void* unused)
351 {
352 int Port = 4156;
353 int Marius_Socket = -1;
354 int PlayerID;
355 char RoomToken[33] = {0};
356 int i = 0;
357
358
359
360 sockaddr_in Marius_Addr = {0};
361
362 if(Are_We_Logged_In)
363 {
364 DDrConsole_PrintF("You're already logged in!");
365 return 0;
366 }
367
368 NetPlatform_Initalize();
369
370
371 if(MariusNet_Initialize())
372 {
373 return 0;
374 }
375
376 //Horribly set up.
377 while( (Marius_Socket == -1 || Marius_Socket == 0 )&& Port < 6641)
378 {
379
380 //Marius_Socket = NetTCPSocket_Create(Port, &Marius_Addr);
381 //NetUDPSocket_Close( Marius_Socket );
382 Marius_Socket = NetTCPSocket_Create(Port, &Marius_Addr);
383 //Port++;
384 }
385
386 if(Marius_Socket != -1)
387 {
388 unsigned char incomingData[1400] = {0};
389 short incomingLength = 0;
390 marius_packet* incomingPacket = &incomingData;
391 //Initialize
392 marius_packet mPacket;
393 int sent_bytes;
394 Initialize_LoginPacket(&mPacket);
395
396 DDrConsole_PrintF("Logging into Mariusnet <%s>...", inet_ntoa(Marius_Server.sin_addr));
397 if(connect( Marius_Socket, &Marius_Server, sizeof(sockaddr_in)))
398 {
399 NetCatchError();
400 return 0;
401 }
402 DDrConsole_PrintF("Sending Player Info...");
403 sent_bytes = MariusNet_OutgoingPacketWrapper(Marius_Socket, (sockaddr*)&Marius_Server, (char*)&mPacket,
404 sizeof(marius_header) + sizeof(m_player_login) - (sizeof(m_player_info) - ntohs(mPacket.login.PlayerInfoSize) ) );
405 /*
406 if(!NetUDPSocket_Recieve(Marius_Socket, (sockaddr*)&Marius_Addr,incomingData, &incomingLength))
407 {
408 DDrConsole_PrintF("Data: %s Length %i", incomingData, incomingLength);
409 return 0;
410 }
411 */
412 if(MariusNet_IncomingPacketWrapper(Marius_Socket, incomingData, 1400, 0) == SOCKET_ERROR)
413 {
414 return 0;
415 }
416
417 if(ntohs(incomingPacket->header.PacketId)== pt_EncryptionKey)
418 {
419 //recv( Marius_Socket, incomingData, 1440, 0);
420 DDrConsole_PrintF("Encryption Type %s", EncryptionTypes[ntohs(incomingPacket->salt.EncryptionType)] );
421
422 Initialize_MPacket(&mPacket, pt_Password);
423 if(incomingPacket->salt.EncryptionType)
424 {
425
426 unsigned char* Hash = mPacket.password.passHash;
427 unsigned char* Salt = incomingPacket->salt.salt;
428 unsigned char Pass[16] = {0};
429
430 memset(Pass, 0x23, 16);
431 strcpy(Pass, MariusPassword );
432
433 for( i = 0; i < 16; i++ ) Hash[i] = Pass[i]^Salt[i];
434 for( i = 1; i < 16; i++ ) Hash[i] = Hash[i]^Hash[i-1];
435 for( i = 1; i < 16; i++ )
436 {
437 short value = ~( Hash[i]*Hash[i-1] );
438 Hash[i] = (unsigned char) value;
439
440 }
441 }
442 else
443 {
444 strncpy(mPacket.password.passHash, MariusPassword, 16);
445 }
446
447 DDrConsole_PrintF("Sending Password...");
448 sent_bytes = MariusNet_OutgoingPacketWrapper(Marius_Socket, (sockaddr*)&Marius_Server, (char*)&mPacket, sizeof(marius_header) + sizeof(m_password) );
449
450 if(!NetUDPSocket_Recieve(Marius_Socket, (sockaddr*)&Marius_Addr,incomingData, &incomingLength))
451 {
452 return 0;
453 }
454 DDrConsole_PrintF("Password ACK!");
455 if(ntohs(incomingPacket->header.PacketId)== pt_PasswordAck)
456 {
457
458 Initialize_MPacket(&mPacket, pt_Localization);
459 mPacket.localization.one = htonl(1);
460 mPacket.localization.two = htonl(2);
461 mPacket.localization.three = htonl(3);
462 mPacket.localization.zero = 0;
463 sent_bytes = MariusNet_OutgoingPacketWrapper(Marius_Socket, (sockaddr*)&Marius_Server, (char*)&mPacket, sizeof(marius_header) + sizeof(m_localization) );
464
465 if(MariusNet_IncomingPacketWrapper(Marius_Socket, incomingData, 1400, 0) == SOCKET_ERROR)
466 {
467 return 0;
468 }
469 }
470 }
471
472 if(ntohs(incomingPacket->header.PacketId)== pt_UserLoggedIn)
473 {
474 PlayerID = ntohl(incomingPacket->login_success.userID);
475 //Not sure if this is a string or byte array, so I allocated 33 bytes,
476 //so it always zero terminates.
477 memcpy(RoomToken, incomingPacket->login_success.Token, 32);
478 DDrConsole_PrintF("Logged into Mariusnet!");
479 }
480 else if(ntohs(incomingPacket->header.PacketId)== pt_LoginInfo)
481 {
482 //DDrConsole_PrintF("Login failed: %s", incomingPacket->login_denied.DenialMessage );
483 MSNet_LoginError_Output(ntohl(incomingPacket->login_denied.code));
484 return 0;
485 }
486 else
487 {
488 DDrConsole_PrintF("Something went wrong! Disconnecting from Mariusnet");
489 return 0;
490 }
491
492
493 do
494 {
495 if(MariusNet_IncomingPacketWrapper(Marius_Socket, incomingData, 1400, 0) == SOCKET_ERROR)
496 {
497 return 0;
498 }
499 if(ntohs(incomingPacket->header.PacketId)== pt_RoomList)
500 {
501 DDrConsole_PrintF("Got room list!");
502 RoomListGotten = 1;
503 memcpy(RoomList, incomingPacket->roomlist.Rooms,
504 ntohl(incomingPacket->header.PacketSize) - sizeof(marius_header));
505 }
506 else if(ntohs(incomingPacket->header.PacketId)== pt_PlayerInfo)
507 {
508 //What do we do with this?!
509 DDrConsole_PrintF("Got player info!");
510 }
511 else
512 {
513 DDrConsole_PrintF("Invalid packet type %hi", ntohs(incomingPacket->header.PacketId));
514 return 0;
515 }
516 }
517 while(PacketCached || !RoomListGotten);
518
519 for(i = 0; i < 64, RoomList[i].IPAddress != 0 ; i++)
520 {
521 int IP = ntohl(RoomList[i].IPAddress);
522 DDrConsole_PrintF("Room %i %s IP %s Port %hi Players %hi",
523 i,
524 sRoomNames[ntohs(RoomList[i].RoomIndex)],
525 inet_ntoa(*(in_addr*)&IP),
526 ntohs(RoomList[i].Port),
527 ntohs(RoomList[i].PlayerCount)
528 );
529 }
530
531 closesocket(Marius_Socket);
532
533 MSNet_Room_Join( 1, RoomToken );
534
535
536 }
537 return 0;
538 }
539
540 bool MSNet_Login(char* username, char* password)
541 {
542 sprintf_s(MariusLogin, 32, "%s", username);
543 sprintf_s(MariusPassword, 16, "%s", password);
544 CreateThread(NULL, 0, MSNet_Handler, NULL, 0, 0);
545
546 return 0;
547 }
548