source: Daodan/MSVC/Flatline.c@ 573

Last change on this file since 573 was 573, checked in by gumby, 14 years ago
File size: 36.0 KB
Line 
1#include "Flatline.h"
2#include "Oni_Character.h"
3#include "Flatline_Server.h"
4#include "Flatline_Client.h"
5#include "Daodan_Utility.h"
6//#include <sys/time.h>
7#include <time.h>
8uint32_t last1 = 0; uint32_t last2 = 0;
9player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
10player_info * PlayerList[MAX_CONNECTIONS] = {0};
11const char * Rejection_Messages[][255] = {
12 {"Server is full"},
13 {"-2"},
14 {"-3"},
15 {"-4"},
16 {"-5"},
17};
18
19#define BETTER_SYNC
20
21void PlayerDisconnect( int Player )
22{
23 ONrGameState_DeleteCharacter(PlayerList[Player]->Chr);
24 memset(PlayerList[Player], 0, sizeof(player_info));
25 PlayerList[Player] = 0;
26 if(server_started)
27 {
28 FLsPublic_Event( EV_DISCONNECT, &Player );
29 }
30}
31
32void DoRareSync( short Player, sockaddr_in * sender )
33{
34 flatline_packet sync = {0};
35
36 if (Player > max_connections || !PlayerList[ Player ] ) return;
37
38
39// DDrConsole_PrintF( "Sending sync data for player %i, new index %u", Player, PlayerList[ Player ]->rare_sync_index);
40 sender->sin_addr.S_un.S_addr = htonl(sender->sin_addr.S_un.S_addr);
41 sync.id = RARE_SYNC_DATA;
42 sprintf( sync.rare_sync_data.Class, TMrInstance_GetInstanceName( PlayerList[ Player ]->Chr->ONCC ) );
43 //using ->Inventory instead of ->Chr->Inventory to keep the index and Inventory in sync, just in case.
44 memcpy( &(sync.rare_sync_data.Inventory), &(PlayerList[ Player ]->Inventory), sizeof(Inventory) );
45 //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
46 sync.rare_sync_data.Inventory.Weapons[0] = NULL;
47 sync.rare_sync_data.Inventory.Weapons[1] = NULL;
48 sync.rare_sync_data.Inventory.Weapons[2] = NULL;
49 sync.rare_sync_data.PlayerNum = Player;
50 sync.rare_sync_data.index = PlayerList[ Player ]->rare_sync_index;
51 NetTCPServer_Send( sender, (char*)&sync, sizeof(rare_sync_data) + FLATLINE_HEADER );
52}
53
54bool FLrServer_PacketCallback(char* data, int datalen, int from)
55{
56 int i, j;
57 bool found_player = 0;
58 flatline_packet * packet = (flatline_packet*)data;
59 static int recieved = 0;
60 sockaddr_in sender;
61 sender.sin_family = AF_INET;
62 sender.sin_port = htons(27777);
63 sender.sin_addr = *((struct in_addr*)(int*)&from);
64
65
66 //packet->data[datalen] = '\0';
67
68 //DDrConsole_PrintF("Packet \r%d recieved from %i", ++recieved, from);
69
70
71
72 //if data[0] != CONNECT_SEND, search in playerlist for ip address
73
74
75
76
77 switch(packet->id) {
78 flatline_packet connect_recv;
79 player_info * playah;
80 //rewrite this when we get TCP support.
81 //rewrite this before we get TCP support*
82 //the way of seeing if there is room for players sucks.
83 case CONNECT_SEND:
84 ;
85
86 connect_recv.id = CONNECT_REPLY;
87
88 //if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
89 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
90 playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
91 DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
92 if(!((int)playah > -5 && (int)playah <= 0)) {
93 flatline_packet new_char = {0};
94 CharacterObject* Char;
95 connect_recv.connect_reply.goodtogo = 1;
96 connect_recv.connect_reply.player_slot = playah->list_slot;
97 DDrConsole_PrintF("Slot: %i", playah->list_slot);
98
99 //sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
100 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
101 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
102 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
103 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
104 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
105 Sleep(100);
106
107 new_char.id = NEW_PLAYER;
108 Char = &new_char.new_player.Character;
109 memset(Char, 0, sizeof(CharacterObject));
110 Char->Header.Type = 'CHAR';
111 Char->OSD.Options = chr_dontaim;
112 //Build the NEWCHARACTERs for the new player
113 for(j = 0; j < max_connections; j++) {
114 if(PlayerList[j] != 0) {
115 new_char.new_player.Playernumber = j;
116 sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
117
118 sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
119 DDrConsole_PrintF("Class %s", Char->OSD.Class );
120
121 sprintf(Char->OSD.Class, "konoko_generic");
122 NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
123 }
124
125 }
126 }
127 else {
128 //fix the error messages...
129 DDrConsole_PrintF("Server is full. :(");
130 connect_recv.connect_reply.goodtogo = 0;
131 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
132 memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
133 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));
134
135 }
136
137
138 break;
139 case CONNECT_REPLY:
140 break; //do nothing...a server shouldn't recieve this type of packet.
141 case MESSAGE:
142 for(i = 0; i < MAX_PLAYERS; i++) {
143 //DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
144 if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
145 found_player = 1;
146 break;
147 }
148 }
149 if(found_player == 0) return true;
150 else {
151 char message_buffer[512] = {0};
152 flatline_packet message;
153 int message_size;
154 data[datalen] = 0;
155
156 DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
157 sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
158
159 message.id = MESSAGE;
160 message_size = sprintf(message.data, "%s", message_buffer);
161 COrMessage_Print(message_buffer, "chat", 0);
162 UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
163 break;
164 }
165 case CHANGE_NAME:
166 ; //wtf, needed or i get an error.
167 DDrConsole_PrintF("Changing Name to: %s", packet->data);
168 for(i = 0; i < MAX_PLAYERS; i++) {
169 if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
170 found_player = 1;
171 break;
172 }
173 }
174 if(found_player == 0) return true;
175 else {
176 bool name_exists = 0;
177 for(j = 0; j < MAX_PLAYERS; j++) {
178 if(!strcmp(packet->data, Players[j].name)) {
179 name_exists = 1;
180 break;
181 }
182 }
183 if(!name_exists) {
184 char message_buffer[1024];
185 sprintf(message_buffer,"%s changed their name to %s", Players[i].name, packet->data);
186 COrMessage_Print(message_buffer, "name_change", 0);
187 memcpy(Players[i].name, packet->data, 256);
188
189 }
190 break;
191 }
192 case PLAYER_INPUT:
193
194 for(i = 0; i < max_connections; i++) {
195 if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
196 found_player = 1;
197 break;
198 }
199 }
200
201 if(found_player == 0) return true;
202 else {
203 input_struct * packet_input = &packet->input_struct;
204
205
206 PlayerList[i]->Actions1 = packet_input->Actions1;
207 PlayerList[i]->Actions2 = packet_input->Actions2;
208 PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
209 PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
210 PlayerList[i]->LastInputTime = packet_input->Time;
211
212 break;
213 }
214 case RARE_SYNC_DATA_REQUEST:
215 DoRareSync( packet->sync_request , &sender);
216 break;
217 case NULL_PACKET:
218 if(1)
219 {
220 int p;
221 char arr[9999];
222 for (p = 0; p < datalen; p++)
223 {
224 sprintf(arr,"%x",((char*)&packet)[p]);
225 }
226 DDrStartupMessage(arr);
227 }
228 break;
229 default:
230 DDrConsole_PrintF("Warning, recieved badly formed packet!");
231 break;
232 }
233 return true;
234}
235
236void* TSrScores = 0;
237
238void FLrInit_Scores()
239{
240 void* TSFFTahoma;
241 int returnval;
242
243 if(!TSrScores){
244 TMrInstance_GetDataPtr( 'TSFF', "Tahoma", &TSFFTahoma);
245 returnval = TSrContext_New( TSFFTahoma, 7, 1, 1, 0, &TSrScores);
246 TSrContext_SetShade(TSrScores, 0xFFFFFFFF);
247 }
248 return;
249}
250
251void FLrRun_Scores()
252{
253 if(TSrScores)
254 {
255 const int scores_top = 20;
256 const int scores_left = 15;
257 //Convert to grabbing the height directly plox
258 const int line_height = 15;
259 unsigned char alpha = 0xCC;
260 unsigned int z;
261 uint16_t point[2] = {scores_left,scores_top};
262 //TSrContext_DrawText(TSrScores, "Name HP/HP", 0xCC, 0, point);
263 point[0] += 20;
264 TSrContext_DrawText(TSrScores, "Name", alpha, 0, point);
265 point[0] += 100;
266 TSrContext_DrawText(TSrScores, "Dmg", alpha, 0, point);
267 point[0] += 30;
268 TSrContext_DrawText(TSrScores, "K", alpha, 0, point);
269 point[0] += 30;
270 TSrContext_DrawText(TSrScores, "D", alpha, 0, point);
271 point[0] += 30;
272 TSrContext_DrawText(TSrScores, "Health", alpha, 0, point);
273 point[0] = scores_left;
274
275 point[1] += line_height;
276 for(z = 0; z < MAX_CONNECTIONS; z++)
277 {
278 if(PlayerList[z])
279 {
280
281 char tempString[32];
282
283 sprintf(tempString, "%i", z);
284 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
285 point[0] += 20;
286
287
288 TSrContext_DrawText(TSrScores, PlayerList[z]->Chr->Name, alpha, 0, point);
289 point[0] += 100;
290
291 sprintf(tempString, "%i", PlayerList[z]->Chr->Damage);
292 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
293 point[0] += 30;
294 sprintf(tempString, "%i", PlayerList[z]->Chr->Kills);
295 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
296 point[0] += 30;
297 sprintf(tempString, "%i", PlayerList[z]->player_data.Deaths);
298 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
299 point[0] += 30;
300 if(PlayerList[z]->Chr->Health)
301 {
302 sprintf(tempString, "%i", PlayerList[z]->Chr->Health);
303 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
304 point[0] += 25;
305 sprintf(tempString, "/%i", PlayerList[z]->Chr->MaxHealth);
306 TSrContext_DrawText(TSrScores, tempString, alpha, 0, point);
307 }
308 else
309 {
310 TSrContext_SetShade(TSrScores, 0x00FF0000);
311 TSrContext_DrawText(TSrScores, "DEAD", alpha, 0, point);
312 TSrContext_SetShade(TSrScores, 0xFFFFFFFF);
313 }
314 point[0] = scores_left;
315 point[1] += line_height;
316 }
317 }
318 }
319}
320
321bool FLrServer_Run()
322{
323 // Get the local hostname
324 char szHostName[255];
325 struct hostent *host_entry;
326 gethostname(szHostName, 255);
327 FLrInit_Scores();
328 host_entry=gethostbyname(szHostName);
329 DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
330 return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
331}
332
333
334 RGBA green = {0, 0xFF, 0, 0};
335 RGBA red = {0, 0, 0xFF, 0};
336 RGBA grey = {0x80,0x80,0x80,0x80};
337
338//FLrClient_Run
339//Looping function that waits for packets from the server.
340//TODO: Convert connection packet stuff to TCP
341int client_slot = 0;
342bool FLrClient_Run(flatline_packet* packet)
343{
344
345 char data[1400];
346 uint16_t len;
347 int j;
348 int sent_bytes;
349 client_connected = 0;
350
351
352 //starts the connection
353 DDrConsole_PrintF("Connecting to server %s on socket %i", inet_ntoa(address.sin_addr), client_sock);
354 sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
355 if(sent_bytes == SOCKET_ERROR) {
356 NetCatchError();
357 }
358 //loops once per second waiting for a reply.
359 for(j = 0; j < CONNECTION_TIMEOUT; j++) {
360 while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){
361 packet = (flatline_packet*)data;
362 if(packet->id == CONNECT_REPLY) {
363 if(packet->connect_reply.goodtogo){
364 client_connected = 1;
365
366 client_slot = ((connect_reply*)packet->data)->player_slot;
367
368 PlayerList[client_slot] = Players+client_slot;
369 PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter;
370
371 DDrConsole_PrintColored("Connection successful!",0,green, grey);
372
373 //disable local input.
374 DDrPatch_NOOP(0x004FA929, 5 + 6 + 5);
375
376 //DDrConsole_PrintF("Slot %i", ((connect_reply*)packet)->player_slot);
377 break;
378 }
379 else {
380 DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message);
381 return false;
382 break;
383 }
384 }
385 }
386 if(client_connected) break;
387 DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j);
388 Sleep(1000);
389 }
390 //the client timed out without recieving an error message.
391 if(!client_connected) {
392 DDrConsole_PrintColored("Connection timed out.",0,red, grey);
393 return false;
394 }
395 else
396 {
397 ActiveCharacter * Active;
398 flatline_packet packet;
399 FLrInit_Scores();
400//#define SPAM_INPUT
401#ifdef SPAM_INPUT
402 struct timeval lasttime;
403 struct timeval thistime;
404 gettimeofday(&lasttime, 0);
405#endif
406 while(1) {
407#ifdef SPAM_INPUT
408 gettimeofday(&thistime, 0);
409
410 //DDrConsole_PrintF("%i.%i | %i.%i | %i.%i",lasttime.tv_sec, lasttime.tv_usec, thistime.tv_sec, thistime.tv_usec,
411 // thistime.tv_sec - lasttime.tv_sec, thistime.tv_usec - lasttime.tv_usec);
412 //checks to see if enough time has passed since the last input update (by default once every 10ms)
413 if(
414 ((thistime.tv_sec > lasttime.tv_sec) && ((thistime.tv_usec + 1000000 - lasttime.tv_usec ) > update_rate * 1000) )
415 || ((thistime.tv_sec == lasttime.tv_sec) && ((thistime.tv_usec - lasttime.tv_usec ) > update_rate * 1000))
416 ) {
417
418 flatline_packet input_packet;
419 lasttime.tv_usec = ++thistime.tv_usec; //in case recieving packets takes less than 1 ms.
420
421 input_packet.id = PLAYER_INPUT;
422
423 if( ((GameState*)(ONgGameState))->Input.Current.Actions1 != last1 || ((GameState*)(ONgGameState))->Input.Current.Actions2 != last2) {
424 last1 =((GameState*)(ONgGameState))->Input.Current.Actions1;
425 last2 =((GameState*)(ONgGameState))->Input.Current.Actions2;
426 }
427
428 ((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
429 ((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
430 ((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
431 ((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
432 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
433 //if(sent_bytes == SOCKET_ERROR) NetCatchError();
434 }
435#endif
436 if(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, &packet, &len)) {
437 //packet = (flatline_packet*)data;
438 //DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id);
439 switch(packet.id) {
440 case MESSAGE:
441 COrMessage_Print(packet.data, "chat", 0);
442 break;
443 case NULL_PACKET:
444 if(1)
445 {
446 int p;
447 char arr[9999];
448 for (p = 0; p < len; p++)
449 {
450 sprintf(arr,"%x",((char*)&packet)[p]);
451 }
452 DDrStartupMessage(arr);
453 }
454 break;
455 case CONNECT_SEND:
456 ;if(1) {
457 flatline_packet connect_recv;
458 memcpy(&connect_recv.connect_reply.message,"This isn't a server!", sizeof("This isn't a server!"));
459 NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!"));
460 }
461 case CONNECT_REPLY:
462 break; //extra packet or something.
463 case NEW_PLAYER:
464 ;if(1) { //haxhaxhax
465 CharacterObject* Char = &(packet.new_player.Character);
466 uint32_t chr_index = packet.new_player.Playernumber;
467 Character* PC;
468 DDrConsole_PrintF("%i | %i", packet.new_player.Playernumber ,client_slot);
469 //Char->OSD.Options = 0;
470 if(packet.new_player.Playernumber == client_slot) {
471 PlayerList[packet.new_player.Playernumber] = &Players[0];
472 PC = (ONgGameState->PlayerCharacter);
473 Players[0].Chr = PC;
474
475 }
476 else {
477 ONrGameState_NewCharacter(Char, NULL, NULL, &chr_index);
478 ONgGameState->CharacterStorage[chr_index].charType = 0;
479 PlayerList[packet.new_player.Playernumber] = &Players[chr_index];
480 Players[chr_index].Chr = &(ONgGameState->CharacterStorage[chr_index]);
481 Players[chr_index].Chr->Flags &= 0xFFBFFFFF;
482 Players[chr_index].Chr->MaxHealth = 200;
483 Players[chr_index].spawnnumber = chr_index;
484 DDrConsole_PrintF("Spawning player %s, class %s, slot %i", ((new_player*)(packet.data))->Character.OSD.Name, ((new_player*)(packet.data))->Character.OSD.Class,chr_index) ;
485 }
486 //Players[((new_player*)(packet.data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet.data))->Character), NULL, NULL, 0);
487 break;
488 }
489 case PLAYER_DATA:
490 if(1) { //haxhaxhax
491 player_data* data = &packet.player_data;
492 uint16_t i = data->PlayerNum;
493 GameInput * Active_Input;
494 data = (void*)packet.data;
495
496 //DDrConsole_PrintF("Got data for Player %i, %x", i, PlayerList[i]);
497 if (i > max_connections) break;
498 if( !PlayerList[i] ) break;
499 //PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
500#ifndef BETTER_SYNC
501 PlayerList[i]->Chr->Health = data->Health;
502 PlayerList[i]->Chr->MaxHealth = data->MaxHealth;
503 PlayerList[i]->Chr->Position = data->Position;
504 PlayerList[i]->Chr->Location = data->Location;
505 PlayerList[i]->Chr->LastPosition = data->LastPosition;
506 PlayerList[i]->Chr->Facing = data->Facing;
507 PlayerList[i]->Chr->DesiredFacing = data->DesiredFacing;
508 PlayerList[i]->Chr->CosmeticFacing = data->CosmeticFacing;
509 PlayerList[i]->Actions1 = data->Inputs.Actions1;
510 PlayerList[i]->Actions2 = data->Inputs.Actions2;
511 PlayerList[i]->MouseDeltaX = data->Inputs.MouseDeltaX;
512 PlayerList[i]->MouseDeltaY = data->Inputs.MouseDeltaY;
513
514 Active = ((ActiveCharacter*)(ONrGetActiveCharacter(PlayerList[i]->Chr)));
515 if(!Active) break;
516
517 Active->PhyContext->Position = data->Position;
518#else
519 PlayerList[i]->Actions1 = data->Inputs.Actions1;
520 PlayerList[i]->Actions2 = data->Inputs.Actions2;
521 PlayerList[i]->MouseDeltaX = data->Inputs.MouseDeltaX;
522 PlayerList[i]->MouseDeltaY = data->Inputs.MouseDeltaY;
523 memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
524#endif
525 if( !server_started && data->rare_sync_index > PlayerList[i]->rare_sync_index )
526 {
527 int sent_bytes;
528 flatline_packet sync_request = {0};
529 sync_request.id = RARE_SYNC_DATA_REQUEST;
530 sync_request.sync_request = i;
531 //DDrConsole_PrintF( "Requesting sync data for player %i, old index %u, new index %i", i, PlayerList[i]->rare_sync_index, data->rare_sync_index);
532 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&sync_request, FLATLINE_HEADER + sizeof(int) );
533 }
534
535
536#if 0
537 TMrInstance_GetDataPtr('TRAM',data->Animation,Active->Animation);
538 Active->AnimationFromState = data->AnimationFromState;
539 Active->AnimationToState = data->AnimationToState;
540 Active->AnimationType = data->AnimationType;
541 Active->NextAnimationType = data->NextAnimationType;
542 Active->Frame = data->Frame;
543 Active->InterpolationCurrentFrame = data->InterpolationCurrentFrame;
544 Active->InterpolationFromState = data->InterpolationFromState;
545 Active->InterpolationLength = data->InterpolationLength;
546 memcpy(Active->InterpolationStartRotations, data->InterpolationStartRotations,
547 sizeof(Quaternion) * 19);
548 memcpy(Active->BoneMatrices, data->BoneMatrices,
549 sizeof(Quaternion) * 19);
550 Active->Stitch = data->Stitch;
551 Active->StitchHeight = data->StitchHeight;
552 Active->StitchVelocity = data->StitchVelocity;
553
554 Active->Overlay = data->Overlay;
555 memcpy(Active->OverlayRotations, data->OverlayRotations,
556 sizeof(Quaternion) * 19);
557#endif
558 //Active->animationtype2 = data->AnimationType2;
559 /*
560 if((int)*((char*)(Active + 0x1AF8) + 0x166) > data->Frame + 1)
561 *(uint16_t *)((char*)Active + 0x1C88) = data->Frame + 1;
562*/
563 break;
564 }
565 case RARE_SYNC_DATA:
566 if(1) {
567 sl_arg hax[2];
568 int dontuse;
569 uint16_t i = packet.rare_sync_data.PlayerNum;
570
571 if (i > max_connections) break;
572 if( !PlayerList[i] ) break;
573
574 //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
575 packet.rare_sync_data.Inventory.Weapons[0] = NULL;
576 packet.rare_sync_data.Inventory.Weapons[1] = NULL;
577 packet.rare_sync_data.Inventory.Weapons[2] = NULL;
578// TMrInstance_GetDataPtr( 'ONCC', packet.rare_sync_data.Class, PlayerList[ i ]->Chr->ONCC );
579
580 //add the target character
581 hax[0].type = sl_int32;
582 hax[0].value_int32 = PlayerList[ packet.rare_sync_data.PlayerNum ]->spawnnumber;
583
584 //add the new class
585 //fix this later so we cant buffer overflow :O
586 hax[1].type = sl_str32;
587 hax[1].value_str32 = packet.rare_sync_data.Class;
588
589 //we are directly calling a bsl function instead of using the normal method for two reasons
590 //1. it has all the checking built in
591 iSetCharacterClass( 0, 2, hax, &dontuse, &dontuse, hax );
592 //DDrConsole_PrintF( "Recieved sync data for player %i, class %s, old index %u, new index %u", i, packet.rare_sync_data.Class, PlayerList[i]->rare_sync_index, packet.rare_sync_data.index);
593 memcpy( &(PlayerList[ i ]->Chr->Inventory), &(packet.rare_sync_data.Inventory), sizeof(Inventory ));
594
595 PlayerList[i]->rare_sync_index = packet.rare_sync_data.index;
596 }
597 break;
598 case FLATLINE_EVENT:
599 FLcEvent_Handler(packet.flatline_event.event_index, packet.flatline_event.intArray);
600 default:
601 DDrConsole_PrintF("Warning, recieved badly formed packet!");
602 break;
603 }
604 }
605 else {
606 Sleep(1);
607 }
608 }
609 }
610 return true;
611}
612
613//wtf, this needs cleaned up...
614player_info *FLr_FindEmptySlot() {
615 int j;
616 for(j = 0; j < MAX_PLAYERS; j++) {
617 if (Players[j].ip == 0) {
618 return &Players[j];
619 }
620 }
621 return 0;
622}
623
624extern uint16_t max_connections;
625uint16_t FLr_FindEmptyListSlot() {
626 int j;
627 for(j = 0; j < max_connections; j++) {
628 if (PlayerList[j] == 0) {
629 return j;
630 }
631 }
632 return -1;
633}
634 typedef struct
635 {
636 uint16_t x;
637 uint16_t y;
638
639 } IMtPoint2D;
640static flatline_packet cache_input = {0};
641extern void* TSrTest;
642
643void ONrCharacter_SetAnimationInternal(Character *ioCharacter, ActiveCharacter *ioActiveCharacter,
644 short inFromState, short inNextAnimType, const void *inAnimation)
645{
646 void *characterClass = ioCharacter->ONCC;
647 //void *collection = ioCharacter->characterClass;
648 short index = ioCharacter->Number;//ONrCharacter_GetIndex(ioCharacter);
649 short animType;
650 if(inAnimation == NULL) return;
651 //UUmAssert(NULL != inAnimation);
652
653 animType = *((char*)inAnimation + 0x15A);
654
655 ioActiveCharacter->Animation = inAnimation;
656 ioActiveCharacter->Frame = 0;
657 ioActiveCharacter->AnimationFromState = inFromState;
658 ioActiveCharacter->AnimationType = animType;
659 ioActiveCharacter->NextAnimationType = inNextAnimType;
660 ioActiveCharacter->AnimationToState = TRrAnimation_GetTo((void *)inAnimation);
661
662 //UUmAssertTrigRange(ioCharacter->facing);
663
664/* if (gDebugCharacters && (index == gDebugCharacterTarget)) {
665 COrConsole_Printf("anim %s state %s type %s length %d",
666 TRrAnimation_GetName(inAnimation),
667 ONrAnimStateToString(TRrAnimation_GetTo(inAnimation)),
668 ONrAnimTypeToString(TRrAnimation_GetType(inAnimation)),
669 TRrAnimation_GetDuration(inAnimation));
670 }*/
671
672 return;
673}
674
675char ONrAnimState_IsFallen(short inAnimState)
676{
677 char result = false;
678
679 switch(inAnimState)
680 {
681 case 18://ONcAnimState_Fallen_Back:
682 case 50://ONcAnimState_Fallen_Front:
683 result = true;
684 break;
685 }
686
687 return result;
688}
689
690void FLrRespawn(int i)
691{
692 DDrConsole_Print( "Respawn!");
693 ONrCorpse_Create(PlayerList[i]->Chr);
694 ONrCharacter_SetHitPoints( PlayerList[i]->Chr, PlayerList[i]->Chr->MaxHealth);
695}
696void * ONICALL FLrInput_Update_Keys(void)
697{
698 uint16_t i;
699 /*DDrConsole_PrintF("Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x",
700 ONgGameState->Input.Current.Actions1, ONgGameState->Input.Current.Actions2,
701 ONgGameState->Input.Start.Actions1,ONgGameState->Input.Start.Actions2,
702 ONgGameState->Input.Stop.Actions1, ONgGameState->Input.Stop.Actions2,
703 ONgGameState->Input.Stopped.Actions2, ONgGameState->Input.Stopped.Actions2
704 );
705 */
706 ActiveCharacter * Active_Player = ONgGameState->ActiveCharacters;
707 //Active_Player->PhyContext->Rotation;
708 //Active_Player->PhyContext->Position;
709 //ONgGameState->PlayerCharacter->Position;
710
711
712
713 /*
714 if( ONgGameState->Input.MouseDeltaX != 0 || ONgGameState->Input.MouseDeltaY != 0 ||
715 ONgGameState->Input.field_8 != 0 || ONgGameState->Input.field_C != 0 )
716
717 DDrConsole_PrintF("%f %f | %f %f",
718 ONgGameState->Input.MouseDeltaX , ONgGameState->Input.MouseDeltaY,
719 ONgGameState->Input.field_8, ONgGameState->Input.field_C);
720
721 */
722 //if sprint timer is equal to 0, display 0
723 //else if sprint timer is equal to -1, display -1
724 //else display difference
725 //good thing this is just quick an dirty debug stuff :)
726
727 //basically it seems that if the difference is bigger than 15 frames, you cant dash. : /
728
729#ifndef SPAM_INPUT
730 if(client_connected)
731 {
732 int sent_bytes;
733 flatline_packet input_packet = {0};
734 input_packet.id = PLAYER_INPUT;
735 input_packet.input_struct.Time = ONgGameState->GameTime;
736 input_packet.input_struct.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
737 input_packet.input_struct.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
738 input_packet.input_struct.MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
739 input_packet.input_struct.MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
740
741 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
742
743 //return ONgGameState;
744 }
745#endif
746
747 if(!(server_started || client_connected)) return ONgGameState;
748
749 for(i = 0; i < max_connections; i++) {
750 ActiveCharacter * Active_Player;
751 GameInput * Active_Input;
752 if(PlayerList[i] == 0) continue;
753 if( !PlayerList[i]->Chr || (PlayerList[i]->flags == PF_SCRIPTEDAI && PlayerList[i]->Chr->Flags & ONcCharacterFlag_Dead ) )
754 {
755 PlayerDisconnect(i);
756 continue;
757 }
758 PlayerList[i]->Chr->Inventory.Weapons[0] = 0;
759 PlayerList[i]->Chr->Inventory.Weapons[1] = 0;
760 PlayerList[i]->Chr->Inventory.Weapons[2] = 0;
761 if( !client_connected && PlayerList[i]->Chr->Flags & ONcCharacterFlag_Dead )//dead
762 {
763 char doRespawn = false;
764 uint32_t Actions1Bitmask = Action_Punch | Action_Kick;
765 uint32_t Actions2Bitmask = Action2_Fire1 | Action2_Fire2;
766 if(client_connected) continue;
767 if(PlayerList[i]->state == STATE_ALIVE)
768 {
769 PlayerList[i]->state = STATE_DEAD;
770 PlayerList[i]->player_data.Deaths++;
771 }
772 if((i == 0 && ( ONgGameState->Input.Current.Actions1 & Actions1Bitmask || ONgGameState->Input.Current.Actions2 & Actions2Bitmask ))
773 || (PlayerList[i]->Actions1 & Actions1Bitmask) || (PlayerList[i]->Actions2 & Actions2Bitmask) )
774 {
775 FLrRespawn(i);
776 PlayerList[i]->state = STATE_ALIVE;
777 }
778 continue;
779 }
780 else
781 {
782 Active_Player = (void*)ONrGetActiveCharacter( PlayerList[i]->Chr);
783 // if(Active_Player == 0) continue;
784 //Active_Input = &(Active_Player->Input);
785 if(server_started) {
786 player_data * data;
787 flatline_packet data_out = {0};
788
789 //if( PlayerList[i]->Chr->Health == 0) PlayerList[i]->Chr->Health = PlayerList[i]->Chr->MaxHealth;
790
791 data_out.id = PLAYER_DATA;
792 data = (void*)&(data_out.data);
793 data->Deaths = PlayerList[i]->player_data.Deaths;
794 data->PlayerNum = i;
795 data->Kills = PlayerList[i]->Chr->Kills;
796 data->Damage = PlayerList[i]->Chr->Damage;
797 data->Health = PlayerList[i]->Chr->Health;
798 data->MaxHealth = PlayerList[i]->Chr->MaxHealth;
799 data->Facing = PlayerList[i]->Chr->Facing;
800 data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
801 if(Active_Player && Active_Player->PhyContext)
802 data->Position = Active_Player->PhyContext->Position;
803
804 if( PlayerList[i]->OldClass != PlayerList[i]->Chr->ONCC || memcmp( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) ) )
805 {
806 PlayerList[i]->OldClass = PlayerList[i]->Chr->ONCC;
807 memcpy( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) );
808 PlayerList[i]->rare_sync_index++;
809
810 }
811 data->rare_sync_index = PlayerList[i]->rare_sync_index;
812 if(Active_Player)
813 {
814 data->Frame = Active_Player->Frame;
815 memcpy(data->Animation, TMrInstance_GetInstanceName(Active_Player->Animation), 32);
816
817 if(Active_Player->targetThrow)
818 {
819 ActiveCharacter* Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
820 if(Target)
821 {
822 data->throw_data.throwing = Players[Active_Player->throwing].list_slot;
823 data->throw_data.throwFrame = Target->Frame;
824 strcpy_s(data->throw_data.throwName, 32, TMrInstance_GetInstanceName(Active_Player->targetThrow));
825 }
826 }
827 }
828 if(i == 0) {
829 data->Inputs.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
830 data->Inputs.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
831 data->Inputs.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
832 data->Inputs.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
833 }
834 else{
835 data->Inputs.Actions1 = PlayerList[i]->Actions1;
836 data->Inputs.Actions2 = PlayerList[i]->Actions2;
837 data->Inputs.MouseDeltaX = PlayerList[i]->MouseDeltaX;
838 data->Inputs.MouseDeltaY = PlayerList[i]->MouseDeltaY;
839 }
840 memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
841
842 UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
843 }
844 }
845 if(Active_Player == 0) continue;
846 else Active_Input = &(Active_Player->Input);
847 if( (server_started && i !=0) || (!server_started/* && i != client_slot*/) )
848 {
849 Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
850 Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
851 Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
852 Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
853
854 Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
855 Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
856 Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
857 Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
858 Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
859 Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
860 //DDrConsole_PrintF("Timer: %i", (Active_Player->SprintTimer != 0) ? (Active_Player->SprintTimer == -1) ? -1 : (ONgGameState->GameTime - Active_Player->SprintTimer) : 0);
861
862 //DDrConsole_PrintF("1E8 %u", ONgGameState->PlayerCharacter->field_1E8);
863/*
864 DDrConsole_PrintF("T %u | Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x",
865 PlayerList[i]->LastInputTime,
866 Active_Input->Current.Actions1, Active_Input->Current.Actions2,
867 Active_Input->Start.Actions1,Active_Input->Start.Actions2,
868 Active_Input->Stop.Actions1, Active_Input->Stop.Actions2,
869 Active_Input->Stopped.Actions1, Active_Input->Stopped.Actions2
870 );
871 */
872
873 if( !server_started )
874 {
875 if(PlayerList[i]->player_data.Health != 0)
876 {
877 Character* character = PlayerList[i]->Chr;
878 void* animation;
879 void* prev_character_animation = Active_Player->Animation;
880 int error;
881 td* throw_data= &PlayerList[i]->player_data.throw_data;
882
883 if(PlayerList[i]->Chr->Flags & ONcCharacterFlag_Dead)
884 {
885 FLrRespawn(i);
886 }
887
888 PlayerList[i]->Chr->Health = PlayerList[i]->player_data.Health;
889 PlayerList[i]->Chr->MaxHealth = PlayerList[i]->player_data.MaxHealth;
890 PlayerList[i]->Chr->Facing = PlayerList[i]->player_data.Facing;
891 PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->player_data.DesiredFacing;
892 PlayerList[i]->Actions1 = PlayerList[i]->player_data.Inputs.Actions1;
893 PlayerList[i]->Actions2 = PlayerList[i]->player_data.Inputs.Actions2;
894 PlayerList[i]->MouseDeltaX = PlayerList[i]->player_data.Inputs.MouseDeltaX;
895 PlayerList[i]->MouseDeltaY = PlayerList[i]->player_data.Inputs.MouseDeltaY;
896 PlayerList[i]->Chr->Damage = PlayerList[i]->player_data.Damage;
897 PlayerList[i]->Chr->Kills = PlayerList[i]->player_data.Kills;
898 if(Active_Player->PhyContext)
899 Active_Player->PhyContext->Position = PlayerList[i]->player_data.Position;
900
901 if (!(character->Flags & ONcCharacterFlag_BeingThrown/*ONcCharacterFlag_BeingThrown*/) &&
902 (PlayerList[i]->player_data.Animation[0] != '\0'))
903 {
904 // get a pointer to the animation
905 error =
906 TMrInstance_GetDataPtr(
907 'TRAM',
908 PlayerList[i]->player_data.Animation,
909 &animation);
910 if (error == 0)
911 {
912 short num_frames;
913 char updateAnimation = true;
914
915 // if the character is dead, make sure this animation is appropriate for death
916 if (character->Flags & 0x00000001)
917 {
918 int curToState = TRrAnimation_GetTo(Active_Player->Animation);
919 int newToState = TRrAnimation_GetTo(animation);
920
921 // if we are currently heading towards fallen and the new animation would not
922 // then this is a better animation to run when we are dead
923 if ((ONrAnimState_IsFallen(curToState)) &&
924 (!ONrAnimState_IsFallen(newToState)))
925 {
926 updateAnimation = false;
927 }
928 }
929
930 if ((updateAnimation) && (Active_Player->Animation == animation))
931 {
932 int oldFrame = Active_Player->Frame;
933 int newFrame = PlayerList[i]->player_data.Frame;
934
935 if (abs(oldFrame - newFrame) < 2)
936 {
937 updateAnimation = false;
938 }
939 }
940
941 if (updateAnimation)
942 {
943 // set the characters animation
944 ONrCharacter_SetAnimationInternal(
945 character, Active_Player,
946 TRrAnimation_GetFrom(Active_Player->Animation),
947 0,
948 animation);
949 //PlayerList[i]->player_data.Animation[0] = 0;
950 }
951
952 num_frames = TRrAnimation_GetDuration(Active_Player->Animation);
953
954 if (PlayerList[i]->player_data.Frame >= num_frames)
955 {
956 Active_Player->Frame = num_frames - 1;
957 }
958 else
959 {
960 Active_Player->Frame = PlayerList[i]->player_data.Frame ;
961 }
962 }
963 }
964
965 if (throw_data->throwName[0] && PlayerList[throw_data->throwing])
966 {
967 int realIndex = PlayerList[throw_data->throwing]->Chr->Number;
968 if ((throw_data->throwing != 0xFFFF) &&
969 (realIndex != Active_Player->throwing) &&
970 (throw_data->throwFrame < 10))
971 {
972 void *throw_animation;
973 ActiveCharacter* Target;
974
975 // get the animation
976 error =
977 TMrInstance_GetDataPtr(
978 'TRAM',
979 throw_data->throwName,
980 &throw_animation);
981 if (error != 0) return ONgGameState;
982
983 // set the throw target
984 Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[realIndex];
985 Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
986 if(Target)
987 {
988 if ((Target->Animation != throw_animation) &&
989 (prev_character_animation != animation) &&
990 !(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
991 {
992 // set the throw variables
993 Active_Player->targetThrow = throw_animation;
994 Active_Player->throwing = realIndex;
995
996 // run the throw
997 ONrCharacter_NewAnimationHook(character, Active_Player);
998 if (Active_Player->ThrowTargetCharacter)
999 {
1000 Target->Frame += 2;
1001 Target->thrownBy = character->Number;
1002 DDrConsole_PrintF("Thrownby %i!!!!", Target->thrownBy);
1003 DDrStartupMessage("Thrownby %i!!!!", Target->thrownBy);
1004 }
1005 }
1006 }
1007 }
1008 }
1009 }
1010
1011 }
1012 }
1013 }
1014
1015 return ONgGameState;
1016}
1017
1018int EventPlusArgs[EV_MAX + 1][2] =
1019{
1020 {EV_RESPAWN, 1},
1021 {EV_DISCONNECT, 1},
1022 {EV_DOOR_OPEN, 1},
1023 {EV_MAX, 0},
1024};
1025
1026int FLrEvent_GetNumArgs( int eventIndex )
1027{
1028 return EventPlusArgs[1][eventIndex];
1029
1030}
1031
1032char * FLrHook_DoorOpen( DoorObject *inDoor, Character *Char)
1033{
1034 if(server_started)
1035 {
1036 FLsPublic_Event( EV_DOOR_OPEN, &inDoor->Door.ID );
1037 }
1038 return (inDoor->Door.class);
1039}
Note: See TracBrowser for help on using the repository browser.