source: Daodan/MSVC/Flatline.c @ 581

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

Wow new netcode

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