source: Daodan/MSVC/Flatline.c @ 583

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

last update before big rewrite

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