source: Daodan/MSVC/Flatline.c @ 573

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