source: Daodan/MSVC/Flatline.c@ 578

Last change on this file since 578 was 578, checked in by gumby, 14 years ago
File size: 28.4 KB
RevLine 
[578]1#include "Flatline.h"
2#include "Oni_Character.h"
3#include "Flatline_Server.h"
4//#include <sys/time.h>
5#include <time.h>
6uint32_t last1 = 0; uint32_t last2 = 0;
7player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
8player_info * PlayerList[MAX_CONNECTIONS] = {0};
9const char * Rejection_Messages[][255] = {
10 {"Server is full"},
11 {"-2"},
12 {"-3"},
13 {"-4"},
14 {"-5"},
15};
16
17#define BETTER_SYNC
18
19void DoRareSync( short Player, sockaddr_in * sender )
20{
21 flatline_packet sync = {0};
22
23 if (Player > max_connections || !PlayerList[ Player ] ) return;
24
25
26// DDrConsole_PrintF( "Sending sync data for player %i, new index %u", Player, PlayerList[ Player ]->rare_sync_index);
27 sender->sin_addr.S_un.S_addr = htonl(sender->sin_addr.S_un.S_addr);
28 sync.id = RARE_SYNC_DATA;
29 sprintf( sync.rare_sync_data.Class, TMrInstance_GetInstanceName( PlayerList[ Player ]->Chr->ONCC ) );
30 //using ->Inventory instead of ->Chr->Inventory to keep the index and Inventory in sync, just in case.
31 memcpy( &(sync.rare_sync_data.Inventory), &(PlayerList[ Player ]->Inventory), sizeof(Inventory) );
32 //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
33 sync.rare_sync_data.Inventory.Weapons[0] = NULL;
34 sync.rare_sync_data.Inventory.Weapons[1] = NULL;
35 sync.rare_sync_data.Inventory.Weapons[2] = NULL;
36 sync.rare_sync_data.PlayerNum = Player;
37 sync.rare_sync_data.index = PlayerList[ Player ]->rare_sync_index;
38 NetTCPServer_Send( sender, (char*)&sync, sizeof(rare_sync_data) + FLATLINE_HEADER );
39}
40
41bool FLrServer_PacketCallback(char* data, int datalen, int from)
42{
43 int i, j;
44 bool found_player = 0;
45 flatline_packet * packet = (flatline_packet*)data;
46 static int recieved = 0;
47 sockaddr_in sender;
48 sender.sin_family = AF_INET;
49 sender.sin_port = htons(27777);
50 sender.sin_addr = *((struct in_addr*)(int*)&from);
51
52
53 //packet->data[datalen] = '\0';
54
55 //DDrConsole_PrintF("Packet \r%d recieved from %i", ++recieved, from);
56
57
58
59 //if data[0] != CONNECT_SEND, search in playerlist for ip address
60
61
62
63
64 switch(packet->id) {
65 flatline_packet connect_recv;
66 player_info * playah;
67 //rewrite this when we get TCP support.
68 //rewrite this before we get TCP support*
69 //the way of seeing if there is room for players sucks.
70 case CONNECT_SEND:
71 ;
72
73 connect_recv.id = CONNECT_REPLY;
74
75 //if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
76 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
77 playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
78 DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
79 if(!((int)playah > -5 && (int)playah <= 0)) {
80 flatline_packet new_char = {0};
81 CharacterObject* Char;
82 connect_recv.connect_reply.goodtogo = 1;
83 connect_recv.connect_reply.player_slot = playah->list_slot;
84 DDrConsole_PrintF("Slot: %i", playah->list_slot);
85
86 //sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
87 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
88 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
89 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
90 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
91 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
92 Sleep(100);
93
94 new_char.id = NEW_PLAYER;
95 Char = &new_char.new_player.Character;
96 memset(Char, 0, sizeof(CharacterObject));
97 Char->Header.Type = 'CHAR';
98 Char->OSD.Options = chr_dontaim;
99 for(j = 0; j < max_connections; j++) {
100 if(PlayerList[j] != 0) {
101 new_char.new_player.Playernumber = j;
102 sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
103
104 sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
105 DDrConsole_PrintF("Class %s", Char->OSD.Class );
106
107 sprintf(Char->OSD.Class, "konoko_generic");
108 NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
109 }
110
111 }
112 }
113 else {
114 //fix the error messages...
115 DDrConsole_PrintF("Server is full. :(");
116 connect_recv.connect_reply.goodtogo = 0;
117 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
118 memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
119 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));
120
121 }
122
123
124 break;
125 case CONNECT_REPLY:
126 break; //do nothing...a server shouldn't recieve this type of packet.
127 case MESSAGE:
128 for(i = 0; i < MAX_PLAYERS; i++) {
129 //DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
130 if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
131 found_player = 1;
132 break;
133 }
134 }
135 if(found_player == 0) return true;
136 else {
137 char message_buffer[512] = {0};
138 flatline_packet message;
139 int message_size;
140 data[datalen] = 0;
141
142 DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
143 sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
144
145 message.id = MESSAGE;
146 message_size = sprintf(message.data, "%s", message_buffer);
147 COrMessage_Print(message_buffer, "chat", 0);
148 UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
149 break;
150 }
151 case CHANGE_NAME:
152 ; //wtf, needed or i get an error.
153 DDrConsole_PrintF("Changing Name to: %s", packet->data);
154 for(i = 0; i < MAX_PLAYERS; i++) {
155 if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
156 found_player = 1;
157 break;
158 }
159 }
160 if(found_player == 0) return true;
161 else {
162 bool name_exists = 0;
163 for(j = 0; j < MAX_PLAYERS; j++) {
164 if(!strcmp(packet->data, Players[j].name)) {
165 name_exists = 1;
166 break;
167 }
168 }
169 if(!name_exists) {
170 char message_buffer[1024];
171 sprintf(message_buffer,"%s changed their name to %s", Players[i].name, packet->data);
172 COrMessage_Print(message_buffer, "name_change", 0);
173 memcpy(Players[i].name, packet->data, 256);
174
175 }
176 break;
177 }
178 case PLAYER_INPUT:
179
180 for(i = 0; i < max_connections; i++) {
181 if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
182 found_player = 1;
183 break;
184 }
185 }
186
187 if(found_player == 0) return true;
188 else {
189 input_struct * packet_input = &packet->input_struct;
190
191
192 PlayerList[i]->Actions1 = packet_input->Actions1;
193 PlayerList[i]->Actions2 = packet_input->Actions2;
194 PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
195 PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
196 PlayerList[i]->LastInputTime = packet_input->Time;
197
198 break;
199 }
200 case RARE_SYNC_DATA_REQUEST:
201 DoRareSync( packet->sync_request , &sender);
202 break;
203 default:
204 DDrConsole_PrintF("Warning, recieved badly formed packet!");
205 break;
206 }
207 return true;
208}
209
210bool FLrServer_Run()
211{
212 // Get the local hostname
213 char szHostName[255];
214 struct hostent *host_entry;
215 gethostname(szHostName, 255);
216
217 host_entry=gethostbyname(szHostName);
218 DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
219 return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
220}
221
222short TRrAnimation_GetType(char* anim)
223{
224 return *(short*)(anim + 0x15A);
225}
226
227void ONrCharacter_SetAnimationInternal(Character* Char, ActiveCharacter* AChar,
228 short inFromState, short inNextAnimType, const void *TRAM)
229{
230 ONCC *ONCC = Char->ONCC;
231 void *TRAC = ONCC->TRAC;
232 short index = Char->Number;
233 short animType;
234
235 if (TRAM == 0) return;
236
237 animType = TRrAnimation_GetType(TRAM);
238
239 AChar->Animation = TRAM;
240 AChar->Frame = 0;
241 AChar->AnimationFromState = inFromState;
242 AChar->AnimationType = animType;
243
244 AChar->NextAnimationType= inNextAnimType;
245 AChar->AnimationToState = TRrAnimation_GetTo(TRAM);
246
247 return;
248}
249
250
251 RGBA green = {0, 0xFF, 0, 0};
252 RGBA red = {0, 0, 0xFF, 0};
253 RGBA grey = {0x80,0x80,0x80,0x80};
254
255//FLrClient_Run
256//Looping function that waits for packets from the server.
257
258int client_slot = 0;
259bool FLrClient_Run(flatline_packet* packet)
260{
261
262 char data[1400];
263 uint16_t len;
264 int j;
265 int sent_bytes;
266 client_connected = 0;
267
268
269 //starts the connection
270 DDrConsole_PrintF("Connecting to server %s on socket %i", inet_ntoa(address.sin_addr), client_sock);
271 sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
272 if(sent_bytes == SOCKET_ERROR) {
273 NetCatchError();
274 }
275 //loops once per second waiting for a reply.
276 for(j = 0; j < CONNECTION_TIMEOUT; j++) {
277 while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){
278 packet = (flatline_packet*)data;
279 if(packet->id == CONNECT_REPLY) {
280 if(packet->connect_reply.goodtogo){
281 client_connected = 1;
282
283 client_slot = ((connect_reply*)packet->data)->player_slot;
284
285 PlayerList[client_slot] = Players+client_slot;
286 PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter;
287
288 DDrConsole_PrintColored("Connection successful!",0,green, grey);
289
290 //disable local input.
291 DDrPatch_NOOP(0x004FA929, 5 + 6 + 5);
292
293 //DDrConsole_PrintF("Slot %i", ((connect_reply*)packet)->player_slot);
294 break;
295 }
296 else {
297 DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message);
298 return false;
299 break;
300 }
301 }
302 }
303 if(client_connected) break;
304 DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j);
305 Sleep(1000);
306 }
307 //the client timed out without recieving an error message.
308 if(!client_connected) {
309 DDrConsole_PrintColored("Connection timed out.",0,red, grey);
310 return false;
311 }
312 else
313 {
314 ActiveCharacter * Active;
315 flatline_packet packet;
316//#define SPAM_INPUT
317#ifdef SPAM_INPUT
318 struct timeval lasttime;
319 struct timeval thistime;
320 gettimeofday(&lasttime, 0);
321#endif
322 while(1) {
323#ifdef SPAM_INPUT
324 gettimeofday(&thistime, 0);
325
326 //DDrConsole_PrintF("%i.%i | %i.%i | %i.%i",lasttime.tv_sec, lasttime.tv_usec, thistime.tv_sec, thistime.tv_usec,
327 // thistime.tv_sec - lasttime.tv_sec, thistime.tv_usec - lasttime.tv_usec);
328 //checks to see if enough time has passed since the last input update (by default once every 10ms)
329 if(
330 ((thistime.tv_sec > lasttime.tv_sec) && ((thistime.tv_usec + 1000000 - lasttime.tv_usec ) > update_rate * 1000) )
331 || ((thistime.tv_sec == lasttime.tv_sec) && ((thistime.tv_usec - lasttime.tv_usec ) > update_rate * 1000))
332 ) {
333
334 flatline_packet input_packet;
335 lasttime.tv_usec = ++thistime.tv_usec; //in case recieving packets takes less than 1 ms.
336
337 input_packet.id = PLAYER_INPUT;
338
339 if( ((GameState*)(ONgGameState))->Input.Current.Actions1 != last1 || ((GameState*)(ONgGameState))->Input.Current.Actions2 != last2) {
340 last1 =((GameState*)(ONgGameState))->Input.Current.Actions1;
341 last2 =((GameState*)(ONgGameState))->Input.Current.Actions2;
342 }
343
344 ((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
345 ((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
346 ((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
347 ((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
348 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
349 //if(sent_bytes == SOCKET_ERROR) NetCatchError();
350 }
351#endif
352 if(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, &packet, &len)) {
353 //packet = (flatline_packet*)data;
354 //DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id);
355 switch(packet.id) {
356 case MESSAGE:
357 COrMessage_Print(packet.data, "chat", 0);
358 break;
359 case CONNECT_SEND:
360 ;if(1) {
361 flatline_packet connect_recv;
362 memcpy(&connect_recv.connect_reply.message,"This isn't a server!", sizeof("This isn't a server!"));
363 NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!"));
364 }
365 case CONNECT_REPLY:
366 break; //extra packet or something.
367 case NEW_PLAYER:
368 ;if(1) { //haxhaxhax
369 CharacterObject* Char = &(packet.new_player.Character);
370 uint32_t chr_index = 0;
371 Character* PC;
372 DDrConsole_PrintF("%i | %i", packet.new_player.Playernumber ,client_slot);
373 //Char->OSD.Options = 0;
374 if(packet.new_player.Playernumber == client_slot) {
375 PlayerList[packet.new_player.Playernumber] = &Players[0];
376 PC = (ONgGameState->PlayerCharacter);
377 Players[0].Chr = PC;
378
379 }
380 else {
381 ONrGameState_NewCharacter(Char, NULL, NULL, &chr_index);
382 ONgGameState->CharacterStorage[chr_index].charType = 0;
383 PlayerList[packet.new_player.Playernumber] = &Players[chr_index];
384 Players[chr_index].Chr = &(ONgGameState->CharacterStorage[chr_index]);
385 Players[chr_index].Chr->Flags &= 0xFFBFFFFF;
386 Players[chr_index].spawnnumber = chr_index;
387 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) ;
388 }
389 //Players[((new_player*)(packet.data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet.data))->Character), NULL, NULL, 0);
390 break;
391 }
392 case PLAYER_DATA:
393 if(1) { //haxhaxhax
394 player_data* pd = &packet.player_data;
395 uint16_t i = pd->PlayerNum;
396 GameInput * Active_Input;
397 pd = (void*)packet.data;
398
399 //DDrConsole_PrintF("Got data for Player %i, %x", i, PlayerList[i]);
400 if (i > max_connections) break;
401 if( !PlayerList[i] ) break;
402 //PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
403
404 PlayerList[i]->Actions1 = pd->Inputs.Actions1;
405 PlayerList[i]->Actions2 = pd->Inputs.Actions2;
406 PlayerList[i]->MouseDeltaX = pd->Inputs.MouseDeltaX;
407 PlayerList[i]->MouseDeltaY = pd->Inputs.MouseDeltaY;
408 memcpy( &(PlayerList[i]->player_data), pd, sizeof(player_data) );
409
410 if( !server_started && pd->rare_sync_index > PlayerList[i]->rare_sync_index )
411 {
412 int sent_bytes;
413 flatline_packet sync_request = {0};
414 sync_request.id = RARE_SYNC_DATA_REQUEST;
415 sync_request.sync_request = i;
416 DDrConsole_PrintF( "Requesting sync data for player %i, old index %u", i, PlayerList[i]->rare_sync_index);
417 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&sync_request, FLATLINE_HEADER + sizeof(int) );
418 }
419
420
421
422
423 break;
424 }
425 case RARE_SYNC_DATA:
426 if(1) {
427 sl_arg hax[2];
428 int dontuse;
429 uint16_t i = packet.rare_sync_data.PlayerNum;
430
431 if (i > max_connections) break;
432 if( !PlayerList[i] ) break;
433
434 //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
435 packet.rare_sync_data.Inventory.Weapons[0] = NULL;
436 packet.rare_sync_data.Inventory.Weapons[1] = NULL;
437 packet.rare_sync_data.Inventory.Weapons[2] = NULL;
438// TMrInstance_GetDataPtr( 'ONCC', packet.rare_sync_data.Class, PlayerList[ i ]->Chr->ONCC );
439
440 //add the target character
441 hax[0].type = sl_int32;
442 hax[0].value_int32 = PlayerList[ packet.rare_sync_data.PlayerNum ]->spawnnumber;
443
444 //add the new class
445 //fix this later so we cant buffer overflow :O
446 hax[1].type = sl_str32;
447 hax[1].value_str32 = packet.rare_sync_data.Class;
448
449 //we are directly calling a bsl function instead of using the normal method for two reasons
450 //1. it has all the checking built in
451 iSetCharacterClass( 0, 2, hax, &dontuse, &dontuse, hax );
452 //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);
453 memcpy( &(PlayerList[ i ]->Chr->Inventory), &(packet.rare_sync_data.Inventory), sizeof(Inventory ));
454
455 PlayerList[i]->rare_sync_index = packet.rare_sync_data.index;
456 }
457 break;
458
459 default:
460 DDrConsole_PrintF("Warning, recieved badly formed packet!");
461 break;
462 }
463 }
464 else {
465 Sleep(1);
466 }
467 }
468 }
469 return true;
470}
471
472//wtf, this needs cleaned up...
473player_info *FLr_FindEmptySlot() {
474 int j;
475 for(j = 0; j < MAX_PLAYERS; j++) {
476 if (Players[j].ip == 0) {
477 return &Players[j];
478 }
479 }
480 return 0;
481}
482
483extern uint16_t max_connections;
484uint16_t FLr_FindEmptyListSlot() {
485 int j;
486 for(j = 0; j < max_connections; j++) {
487 if (PlayerList[j] == 0) {
488 return j;
489 }
490 }
491 return -1;
492}
493 typedef struct
494 {
495 uint16_t x;
496 uint16_t y;
497
498 } IMtPoint2D;
499static flatline_packet cache_input = {0};
500extern void* TSrTest;
501void * ONICALL FLrInput_Update_Keys(void)
502{
503 uint16_t i;
504 /*DDrConsole_PrintF("Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x",
505 ONgGameState->Input.Current.Actions1, ONgGameState->Input.Current.Actions2,
506 ONgGameState->Input.Start.Actions1,ONgGameState->Input.Start.Actions2,
507 ONgGameState->Input.Stop.Actions1, ONgGameState->Input.Stop.Actions2,
508 ONgGameState->Input.Stopped.Actions2, ONgGameState->Input.Stopped.Actions2
509 );
510 */
511 ActiveCharacter * Active_Player = ONgGameState->ActiveCharacters;
512 Active_Player->PhyContext->Rotation;
513 Active_Player->PhyContext->Position;
514 ONgGameState->PlayerCharacter->Position;
515
516
517
518 /*
519 if( ONgGameState->Input.MouseDeltaX != 0 || ONgGameState->Input.MouseDeltaY != 0 ||
520 ONgGameState->Input.field_8 != 0 || ONgGameState->Input.field_C != 0 )
521
522 DDrConsole_PrintF("%f %f | %f %f",
523 ONgGameState->Input.MouseDeltaX , ONgGameState->Input.MouseDeltaY,
524 ONgGameState->Input.field_8, ONgGameState->Input.field_C);
525
526 */
527 //if sprint timer is equal to 0, display 0
528 //else if sprint timer is equal to -1, display -1
529 //else display difference
530 //good thing this is just quick an dirty debug stuff :)
531
532 //basically it seems that if the difference is bigger than 15 frames, you cant dash. : /
533
534#ifndef SPAM_INPUT
535 if(client_connected)
536 {
537 int sent_bytes;
538 flatline_packet input_packet = {0};
539 input_packet.id = PLAYER_INPUT;
540 input_packet.input_struct.Time = ONgGameState->GameTime;
541 input_packet.input_struct.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
542 input_packet.input_struct.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
543 input_packet.input_struct.MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
544 input_packet.input_struct.MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
545
546 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
547
548 //return ONgGameState;
549 }
550#endif
551 //Testing drawing text to the screen...this failed. Will need to get it working eventually.
552 if( TSrTest )
553 {
554// OniRectangle TextRect = { 128, 128, 256, 256 };
555 IMtPoint2D Point = {50, 50};
556 //TSrContext_DrawText(TSrTest, "Testing woohoo", 255, 0, &Point);
557 TSrContext_DrawText(TSrTest, "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW", 255, 0, &Point);
558
559 }
560 if(!(server_started || client_connected)) return ONgGameState;
561
562 for(i = 0; i < max_connections; i++) {
563 ActiveCharacter * Active_Player;
564 Character* Player;
565 GameInput * Active_Input;
566 if(PlayerList[i] == 0) continue;
567
568 //is this right?
569 Player = PlayerList[i]->Chr;
570 Active_Player = (void*)ONrGetActiveCharacter( PlayerList[i]->Chr);
571
572 if(Active_Player == 0) continue;
573 Active_Input = &(Active_Player->Input);
574 if(server_started) {
575 player_data * data;
576 flatline_packet data_out = {0};
577
578 //if( PlayerList[i]->Chr->Health == 0) PlayerList[i]->Chr->Health = PlayerList[i]->Chr->MaxHealth;
579
580 data_out.id = PLAYER_DATA;
581 data = (void*)&(data_out.data);
582 data->PlayerNum = i;
583 data->Health = PlayerList[i]->Chr->Health;
584 data->MaxHealth = PlayerList[i]->Chr->MaxHealth;
585 data->Position = PlayerList[i]->Chr->Position;
586 data->Facing = PlayerList[i]->Chr->Facing;
587 data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
588 data->Position = Active_Player->PhyContext->Position;
589 memcpy(data->Animation, TMrInstance_GetInstanceName(Active_Player->Animation), 31);
590 data->Frame = Active_Player->Frame;
591
592 if(Active_Player->targetThrow)
593 {
594 data->throw_data.throwing = Active_Player->throwing;
595 memcpy(data->throw_data.throwName, TMrInstance_GetInstanceName(Active_Player->targetThrow), 31);
596 data->throw_data.throwFrame = ONrGetActiveCharacter(Active_Player->targetThrow)->Frame;
597
598 }
599
600
601
602
603 if( PlayerList[i]->OldClass != PlayerList[i]->Chr->ONCC || memcmp( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) ) )
604 {
605 PlayerList[i]->OldClass = PlayerList[i]->Chr->ONCC;
606 memcpy( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) );
607 PlayerList[i]->rare_sync_index++;
608
609 }
610
611 data->rare_sync_index = PlayerList[i]->rare_sync_index;
612
613
614 if(i == 0) {
615 data->Inputs.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
616 data->Inputs.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
617 data->Inputs.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
618 data->Inputs.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
619 }
620 else{
621 data->Inputs.Actions1 = PlayerList[i]->Actions1;
622 data->Inputs.Actions2 = PlayerList[i]->Actions2;
623 data->Inputs.MouseDeltaX = PlayerList[i]->MouseDeltaX;
624 data->Inputs.MouseDeltaY = PlayerList[i]->MouseDeltaY;
625 }
626 memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
627
628 UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
629 }
630
631 if( (server_started && i !=0) || (!server_started/* && i != client_slot*/) )
632 {
633 //this just made sync even worse...
634#ifdef JITTER_FIX
635 input_struct * New_Input = &PlayerList[i]->MouseDeltaX;
636 input_struct * Cache_Input = &PlayerList[i]->CacheInput;
637 Active_Input->Stop.Actions1 = ~Cache_Input->Actions1 & Active_Input->Current.Actions1;
638 Active_Input->Stop.Actions2 = ~Cache_Input->Actions2 & Active_Input->Current.Actions2;
639 Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & Cache_Input->Actions1;
640 Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & Cache_Input->Actions2;
641 Active_Input->Current.Actions1 = Cache_Input->Actions1;
642 Active_Input->Current.Actions2 = Cache_Input->Actions2;
643 Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
644 Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
645 Active_Input->MouseDeltaX = Cache_Input->MouseDeltaX;
646 Active_Input->MouseDeltaY = Cache_Input->MouseDeltaY;
647 memcpy( Cache_Input, New_Input, sizeof(input_struct));
648#else
649
650 Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
651 Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
652 Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
653 Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
654
655 Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
656 Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
657 Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
658 Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
659 Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
660 Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
661 //DDrConsole_PrintF("Timer: %i", (Active_Player->SprintTimer != 0) ? (Active_Player->SprintTimer == -1) ? -1 : (ONgGameState->GameTime - Active_Player->SprintTimer) : 0);
662
663 //DDrConsole_PrintF("1E8 %u", ONgGameState->PlayerCharacter->field_1E8);
664/*
665 DDrConsole_PrintF("T %u | Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x",
666 PlayerList[i]->LastInputTime,
667 Active_Input->Current.Actions1, Active_Input->Current.Actions2,
668 Active_Input->Start.Actions1,Active_Input->Start.Actions2,
669 Active_Input->Stop.Actions1, Active_Input->Stop.Actions2,
670 Active_Input->Stopped.Actions1, Active_Input->Stopped.Actions2
671 );
672 */
673
674
675#endif
676
677#ifdef BETTER_SYNC
678 if( !server_started && PlayerList[i]->player_data.Health != 0) {
679 void* OldAnimation;
680 void* Animation;
681 player_data* pd = &PlayerList[i]->player_data;
682 Player->Health = PlayerList[i]->player_data.Health;
683 PlayerList[i]->Chr->MaxHealth = PlayerList[i]->player_data.MaxHealth;
684
685 PlayerList[i]->Chr->Facing = PlayerList[i]->player_data.Facing;
686 PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->player_data.DesiredFacing;
687
688 PlayerList[i]->Actions1 = PlayerList[i]->player_data.Inputs.Actions1;
689 PlayerList[i]->Actions2 = PlayerList[i]->player_data.Inputs.Actions2;
690 PlayerList[i]->MouseDeltaX = PlayerList[i]->player_data.Inputs.MouseDeltaX;
691 PlayerList[i]->MouseDeltaY = PlayerList[i]->player_data.Inputs.MouseDeltaY;
692 Active_Player->PhyContext->Position = PlayerList[i]->player_data.Position;
693 OldAnimation = Active_Player->Animation;
694
695 if (!(Player->Flags & ONcCharacterFlag_BeingThrown) &&
696 (pd->Animation != 0))
697 {
698 // get a pointer to the animation
699
700 TMrInstance_GetDataPtr(
701 'TRAM',
702 pd->Animation,
703 &Animation);
704 if (Animation != OldAnimation)
705 {
706 short num_frames;
707 bool updateAnimation = true;
708
709 // if the character is dead, make sure this animation is appropriate for death
710 /*
711 if (Player->Flags & ONcCharacterFlag_Dead)
712 {
713 short curToState = TRrAnimation_GetTo(Active_Player->Animation);
714 short newToState = TRrAnimation_GetTo(animation);
715
716 // if we are currently heading towards fallen and the new animation would not
717 // then this is a better animation to run when we are dead
718 if ((ONrAnimState_IsFallen(curToState)) &&
719 (!ONrAnimState_IsFallen(newToState)))
720 {
721 updateAnimation = false;
722 }
723 }
724 */
725 if ((updateAnimation) && (Active_Player->Animation == Animation))
726 {
727 int oldFrame = Active_Player->Frame;
728 int newFrame = pd->Frame;
729
730 if (abs(oldFrame - newFrame) < 2)
731 {
732 updateAnimation = false;
733 }
734 }
735
736 if (updateAnimation)
737 {
738 // set the characters animation
739 /* ONrCharacter_SetAnimationInternal(Player,
740 Active_Player,
741 Active_Player->AnimationToState,
742 0,
743 Animation);
744 ONrCharacter_NewAnimationHook(Player, Active_Player);*/
745 //Player->Flags |= 0x00000010;
746 ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(Animation), Animation, 0);
747 }
748
749 num_frames = TRrAnimation_GetDuration(Active_Player->Animation);
750
751 if (pd->Frame == num_frames)
752 {
753 Active_Player->Frame = num_frames - 1;
754 //Active_Player->Frame = 0;
755 }
756 else
757 {
758 Active_Player->Frame = pd->Frame;
759 }
760 }
761 }
762
763 if (PlayerList[i]->player_data.throw_data.throwName[0] != 0)
764 {
765 if ((pd->throw_data.throwing != 0xFFFF) &&
766 (pd->throw_data.throwing != Active_Player->throwing) &&
767 (pd->throw_data.throwFrame < 10))
768 {
769 void *throw_animation;
770 ActiveCharacter* Target;
771 // get the animation
772
773 TMrInstance_GetDataPtr(
774 'TRAM',
775 pd->throw_data.throwName,
776 &throw_animation);
777 //if (error) return;
778
779 // set the throw target
780 Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[pd->throw_data.throwing];
781 Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
782 if ((Target->Animation != throw_animation) &&
783 (OldAnimation != Animation) &&
784 !(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
785 {
786 // set the throw variables
787 Active_Player->targetThrow = throw_animation;
788 Active_Player->throwing = pd->throw_data.throwing;
789
790 // run the throw
791 ONrCharacter_NewAnimationHook(Player, Active_Player);
792
793 if (Active_Player->ThrowTargetCharacter)
794 {
795 Target->Frame += 2;
796 Target->thrownBy = Player->Number;
797 }
798 }
799 }
800 }
801
802 }
803#endif
804
805 }
806 }
807
808 return ONgGameState;
809}
Note: See TracBrowser for help on using the repository browser.