source: Daodan/MSVC/Flatline.c@ 581

Last change on this file since 581 was 581, checked in by gumby, 14 years ago

Wow new netcode

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