source: Daodan/MSVC/Flatline.c @ 582

Last change on this file since 582 was 582, checked in by gumby, 12 years ago

Hangs on death, but netcode is improved.

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