1 /* This file is part of sparrow3d.
2 * Sparrow3d is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 2 of the License, or
5 * (at your option) any later version.
7 * Sparrow3d is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with Foobar. If not, see <http://www.gnu.org/licenses/>
15 * For feedback and questions about my Files and Projects please mail me,
16 * Alexander Matthes (Ziz) , zizsdl_at_googlemail.com */
18 #include "sparrowNet.h"
22 //This is a copy of spReadOneLine sparrowFile. However, I don't want the
23 //extra dependency of libSparrow3d or linking sparrowFile twice.
24 int internal_spNet_spReadOneLine( SDL_RWops* file , char* buffer, int buffer_len)
28 while (pos < buffer_len)
30 if (SDL_RWread( file, &(buffer[pos]), 1, 1 ) <= 0)
32 if ( buffer[pos] == '\n' )
34 if (buffer[pos] != '\r') //fucking windows line break
41 spNetC4ATaskPointer spGlobalC4ATask = NULL;
42 SDL_mutex* spCacheMutex = NULL;
44 spNetC4ATaskPointer createNewC4ATask()
46 spNetC4ATaskPointer task = (spNetC4ATaskPointer)malloc(sizeof(spNetC4ATask));
47 task->statusMutex = SDL_CreateMutex();
49 task->dataPointer = NULL;
53 task->threadStatus = 0;
58 void spNetC4ADeleteTask(spNetC4ATaskPointer task)
60 SDL_DestroyMutex(task->statusMutex);
64 PREFIX void spInitNet()
67 printf("SDLNet_Init: %s\n", SDLNet_GetError());
68 spGlobalC4ATask = createNewC4ATask();
69 spCacheMutex = SDL_CreateMutex();
72 void fill_ip_struct(spNetIPPointer ip)
75 ip->address.ipv4 = ip->sdl_address.host; //bytes are set automaticly, yeah!
76 ip->port = ip->sdl_address.port;
79 PREFIX spNetIP spNetResolve(char* host,Uint16 port)
82 SDLNet_ResolveHost(&(result.sdl_address), host, port);
83 fill_ip_struct(&result);
87 PREFIX char* spNetResolveHost(spNetIP ip,char* host,int host_len)
89 const char* sdlHost = SDLNet_ResolveIP(&(ip.sdl_address));
90 if (strlen(sdlHost) >= host_len)
95 sprintf(host,"%s",sdlHost);
99 PREFIX spNetTCPConnection spNetOpenClientTCP(spNetIP ip)
101 spNetTCPConnection result;
103 result=SDLNet_TCP_Open(&(ip.sdl_address));
105 printf("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
111 PREFIX spNetTCPServer spNetOpenServerTCP(Uint16 port)
114 spNetTCPServer result;
116 if(SDLNet_ResolveHost(&ip,NULL,port)==-1) {
117 printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
120 result=SDLNet_TCP_Open(&ip);
122 printf("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
128 PREFIX spNetTCPConnection spNetAcceptTCP(spNetTCPServer server)
130 return SDLNet_TCP_Accept(server);
133 PREFIX spNetIP spNetGetConnectionIP(spNetTCPConnection connection)
136 temp_ip=SDLNet_TCP_GetPeerAddress(connection);
139 printf("SDLNet_TCP_GetPeerAddress: %s\n", SDLNet_GetError());
140 printf("This may be a server socket.\n");
141 printf("However, the ip may not be valid!\n");
143 result.sdl_address = *temp_ip;
144 fill_ip_struct(&result);
148 PREFIX int spNetSendTCP(spNetTCPConnection connection,void* data,int length)
150 return SDLNet_TCP_Send(connection,data,length);
153 PREFIX int spNetSendHTTP(spNetTCPConnection connection,char* data)
155 return spNetSendTCP(connection,data,strlen(data)+1);
158 typedef struct receivingStruct *receivingPointer;
159 typedef struct receivingStruct {
160 spNetTCPConnection connection;
167 receivingPointer next;
170 int tcpReceiveThread(void* data)
172 receivingPointer tcpData = (receivingPointer)data;
173 int res=spNetReceiveTCP(tcpData->connection,tcpData->data,tcpData->length);
174 SDL_mutexP(tcpData->mutex);
176 tcpData->result = res;
177 SDL_mutexV(tcpData->mutex);
181 int tcpReceiveThread_http(void* data)
183 receivingPointer tcpData = (receivingPointer)data;
184 int res=spNetReceiveHTTP(tcpData->connection,(char*)tcpData->data,tcpData->length);
185 SDL_mutexP(tcpData->mutex);
187 tcpData->result = res;
188 SDL_mutexV(tcpData->mutex);
192 receivingPointer firstReceiving = NULL;
194 SDL_Thread* allreadyReceiving(spNetTCPConnection connection)
196 receivingPointer before = NULL;
197 receivingPointer mom = firstReceiving;
200 if (mom->connection == connection)
202 SDL_mutexP(mom->mutex);
205 SDL_mutexV(mom->mutex); //The Thread lost the interest on this struct
209 SDL_mutexP(before->mutex);
210 before->next = mom->next;
211 SDL_mutexV(before->mutex);
214 firstReceiving = mom->next;
215 SDL_DestroyMutex(mom->mutex);
216 if (mom->result<=0) //connection destroyed!
219 return (SDL_Thread*)(-1);
224 SDL_mutexV(mom->mutex);
233 PREFIX int spNetReceiveTCP(spNetTCPConnection connection,void* data,int length)
235 char* data_pointer = (char*)data;
236 return SDLNet_TCP_Recv(connection,&(data_pointer[0]),length);
239 PREFIX SDL_Thread* spNetReceiveTCPUnblocked(spNetTCPConnection connection,void* data,int length)
242 if (thread = allreadyReceiving(connection))
244 receivingPointer tcpData = (receivingPointer)malloc(sizeof(receivingType));
245 tcpData->connection = connection;
246 tcpData->data = data;
247 tcpData->length = length;
248 tcpData->connection = connection;
250 tcpData->mutex = SDL_CreateMutex();
251 tcpData->next = firstReceiving;
252 firstReceiving = tcpData;
253 tcpData->thread = SDL_CreateThread(tcpReceiveThread,tcpData);
254 return tcpData->thread;
257 PREFIX int spNetReceiveHTTP(spNetTCPConnection connection,char* data,int length)
262 int new_received = spNetReceiveTCP(connection,&(data[received]),length);
263 received+=new_received;
264 length-=new_received;
265 if (new_received == 0)
271 PREFIX SDL_Thread* spNetReceiveHTTPUnblocked(spNetTCPConnection connection,char* data,int length)
274 if (thread = allreadyReceiving(connection))
276 receivingPointer tcpData = (receivingPointer)malloc(sizeof(receivingType));
277 tcpData->connection = connection;
278 tcpData->data = data;
279 tcpData->length = length;
280 tcpData->connection = connection;
282 tcpData->mutex = SDL_CreateMutex();
283 tcpData->next = firstReceiving;
284 firstReceiving = tcpData;
285 tcpData->thread = SDL_CreateThread(tcpReceiveThread_http,tcpData);
286 return tcpData->thread;
289 PREFIX int spNetReceiveStillWaiting(SDL_Thread* thread)
291 receivingPointer before = NULL;
292 receivingPointer mom = firstReceiving;
295 if (mom->thread == thread)
297 SDL_mutexP(mom->mutex);
300 SDL_mutexV(mom->mutex); //The Thread lost the interest on this struct
304 SDL_mutexP(before->mutex);
305 before->next = mom->next;
306 SDL_mutexV(before->mutex);
309 firstReceiving = mom->next;
310 SDL_DestroyMutex(mom->mutex);
314 SDL_mutexV(mom->mutex);
323 PREFIX void spNetCloseTCP(spNetTCPConnection connection)
325 SDLNet_TCP_Close(connection);
328 PREFIX void spQuitNet()
330 spNetC4ADeleteTask(spGlobalC4ATask);
331 spGlobalC4ATask = NULL;
332 SDL_mutexP(spCacheMutex);
333 SDL_DestroyMutex(spCacheMutex);
338 #include "pnd_locate.h"
341 typedef struct getgenericStruct *getgenericPointer;
342 typedef struct getgenericStruct {
343 spNetC4ATaskPointer task;
344 int ( *function )( void* data );
347 typedef struct getgameStruct *getgamePointer;
348 typedef struct getgameStruct {
349 spNetC4ATaskPointer task;
350 int ( *function )( void* data );
351 spNetC4AGamePointer* game;
354 typedef struct getscoreStruct *getscorePointer;
355 typedef struct getscoreStruct {
356 spNetC4ATaskPointer task;
357 int ( *function )( void* data );
358 spNetC4AScorePointer* score;
359 spNetC4AProfilePointer profile;
365 typedef struct commitStruct *commitPointer;
366 typedef struct commitStruct {
367 spNetC4ATaskPointer task;
368 int ( *function )( void* data );
369 spNetC4AProfilePointer profile;
373 spNetC4AScorePointer* scoreList;
376 typedef struct createStruct *createPointer;
377 typedef struct createStruct {
378 spNetC4ATaskPointer task;
379 int ( *function )( void* data );
380 spNetC4AProfilePointer* profile;
388 int spNetC4ACaching = 0;
389 char spCacheFilename[256] = "";
391 //This is usefull for debugging without threading influences:
392 /*#define SDL_CreateThread SDL_CreateThreadWithoutThreading
393 SDL_Thread* SDL_CreateThreadWithoutThreading(int (*fn)(void *),void* data)
400 typedef struct cacheStruct *cachePointer;
401 typedef struct cacheStruct {
409 cachePointer read_cache()
411 SDL_RWops *file = SDL_RWFromFile(spCacheFilename, "rb");
418 cachePointer cache = NULL;
419 cachePointer last = NULL;
422 if (SDL_RWread(file,game,256,1) <= 0)
424 if (SDL_RWread(file,system,256,1) <= 0)
426 if (SDL_RWread(file,prid,256,1) <= 0)
428 if (SDL_RWread(file,&score,sizeof(int),1) <= 0)
430 cachePointer new_cache = (cachePointer)malloc(sizeof(cacheType));
431 memcpy(new_cache->game,game,256);
432 memcpy(new_cache->system,system,256);
433 memcpy(new_cache->prid,prid,256);
434 new_cache->score = score;
435 new_cache->next = NULL;
437 last->next = new_cache;
448 void write_to_cache(char* game,char* system,char* prid,int score,int lock)
451 SDL_mutexP(spCacheMutex);
452 cachePointer cache = NULL;
453 if (spNetC4ACaching != 1)
454 cache = read_cache();
455 //Searching one of game
456 cachePointer mom = cache;
460 if (strcmp(mom->game,game) == 0)
467 if ((spNetC4ACaching == 2 && mom->score < score) ||
468 (spNetC4ACaching == 3 && mom->score > score))
471 SDL_RWops *file = SDL_RWFromFile(spCacheFilename, "r+b");
472 SDL_RWseek(file,nr*(256*3+sizeof(int))+256*3,SEEK_SET);
473 SDL_RWwrite(file,&score,sizeof(int),1);
479 SDL_RWops *file = SDL_RWFromFile(spCacheFilename, "ab");
480 SDL_RWwrite(file,game,256,1);
481 SDL_RWwrite(file,system,256,1);
482 SDL_RWwrite(file,prid,256,1);
483 SDL_RWwrite(file,&score,sizeof(int),1);
493 SDL_mutexV(spCacheMutex);
496 int spNetC4AUberThread(getgenericPointer data)
498 int startTime = SDL_GetTicks();
499 SDL_Thread* thread = SDL_CreateThread(data->function,data);
510 int newTime = SDL_GetTicks();
511 int diff = newTime - startTime;
513 data->task->timeOut -= diff;
514 SDL_mutexP(data->task->statusMutex);
515 int status = data->task->status;
516 SDL_mutexV(data->task->statusMutex);
517 //only 1 second left, lets send a message
518 if (data->task->message == 0 && (status == SP_C4A_CANCELED || data->task->timeOut <= 1000))
519 data->task->message = 1;
520 //time is over. If the message is reset we assume the thread will finish, otherwise...
521 if (data->task->message == 1 && (status == SP_C4A_CANCELED || data->task->timeOut <= 0))
523 //Waiting for the write cache mutex ANYWAY.
524 SDL_mutexP(spCacheMutex);
525 SDL_KillThread(thread);
526 SDL_mutexV(spCacheMutex);
527 data->task->result = 1;
528 SDL_mutexP(data->task->statusMutex);
529 if (data->task->timeOut <= 0)
530 data->task->status = SP_C4A_TIMEOUT;
531 data->task->threadStatus = 0;
532 SDL_mutexV(data->task->statusMutex);
533 int result = data->task->result;
534 data->task->dataPointer = NULL;
538 if (status <= 0) //finished somehow
540 SDL_WaitThread(thread,&(data->task->result));
541 SDL_mutexP(data->task->statusMutex);
542 data->task->threadStatus = 0;
543 SDL_mutexV(data->task->statusMutex);
544 int result = data->task->result;
545 data->task->dataPointer = NULL;
552 char* my_strchr(char* buffer, char c, char ignore)
556 for (i = 0; buffer[i]!=0; i++)
558 if (buffer[i] == ignore)
559 in_ignore = 1-in_ignore;
560 if (!in_ignore && buffer[i] == c)
566 void fill_between_paraphrases(char* buffer, char* dest, int max_size)
569 int in_paraphrases = 0;
570 for (i = 0; buffer[i]!=0; i++)
572 if (buffer[i] == '\"')
574 switch (in_paraphrases)
576 case 0: in_paraphrases = 1; break;
577 case 1: dest[j]=0;return;
594 void internal_CreateDirectoryChain( const char* directories)
597 int len = strlen(directories)+1;
599 char directoriesCopy[len];
601 char* directoriesCopy = (char*)malloc( len * sizeof(char) );
603 memcpy(directoriesCopy,directories,len);
604 //Splitting in subdirectories
605 char* subString = directoriesCopy;
606 char* endOfString = strchr(subString,'/');
607 if (endOfString == NULL)
608 endOfString = strchr(subString,0);
611 char oldChar = endOfString[0];
615 if (CreateDirectory(directoriesCopy,NULL))
618 if (GetLastError() != ERROR_ALREADY_EXISTS)
621 int error = mkdir(directoriesCopy,0777);
622 if (errno == 0 || errno == EEXIST || errno == ENOENT) //thats okay :)
627 endOfString[0] = oldChar;
630 subString = &(endOfString[1]);
631 endOfString = strchr(subString,'/');
632 if (endOfString == NULL)
633 endOfString = strchr(subString,0);
636 free(directoriesCopy);
641 #define PROFILE_FILENAME_MAKRO char *locate_filename = pnd_locate_filename ( "/media/*/pandora/appdata/c4a-mame/:.", "c4a-prof" ); \
642 char filename[256] = "./c4a-prof"; \
643 if (locate_filename) \
644 sprintf(filename,"%s",locate_filename); \
647 locate_filename = pnd_locate_filename ( "/media/*/pandora/:.", "appdata" ); \
648 if (locate_filename) \
650 sprintf(filename,"%s/c4a-mame",locate_filename); \
651 internal_CreateDirectoryChain(filename); \
652 sprintf(filename,"%s/c4a-mame/c4a-prof",locate_filename); \
655 #elif defined GCW || (defined X86CPU && !defined WIN32)
656 #define PROFILE_FILENAME_MAKRO char filename[256]; \
657 sprintf(filename,"%s/.config/compo4all",getenv("HOME"));\
658 internal_CreateDirectoryChain(filename);\
659 sprintf(filename,"%s/.config/compo4all/c4a-prof",getenv("HOME"));
661 #define PROFILE_FILENAME_MAKRO char filename[256] = "./c4a-prof";
664 PREFIX void spNetC4ASetCaching(int value)
666 spNetC4ACaching = value;
669 void set_cache_filename()
671 PROFILE_FILENAME_MAKRO
672 sprintf(spCacheFilename,"%s",filename);
673 sprintf(&spCacheFilename[strlen(spCacheFilename)-4],"cache");
676 PREFIX spNetC4AProfilePointer spNetC4AGetProfile()
678 set_cache_filename();
679 spNetC4AProfilePointer profile = NULL;
680 PROFILE_FILENAME_MAKRO
682 SDL_RWops *file=SDL_RWFromFile(filename,"rb");
685 profile = (spNetC4AProfilePointer)malloc(sizeof(spNetC4AProfile));
687 internal_spNet_spReadOneLine(file,buffer,2048);
688 internal_spNet_spReadOneLine(file,buffer,2048);
689 char* pos = strstr( buffer, "\"longname\":");
691 fill_between_paraphrases( pos, profile->longname, 256);
693 pos = strstr( buffer, "\"shortname\":");
695 fill_between_paraphrases( pos, profile->shortname, 256);
697 pos = strstr( buffer, "\"prid\":");
699 fill_between_paraphrases( pos, profile->prid, 256);
701 pos = strstr( buffer, "\"email\":");
703 fill_between_paraphrases( pos, profile->email, 256);
705 pos = strstr( buffer, "\"password\":");
707 fill_between_paraphrases( pos, profile->password, 256);
712 PREFIX void spNetC4AFreeProfile(spNetC4AProfilePointer profile)
718 int c4a_getgame_thread(void* data)
720 getgamePointer gameData = ((getgamePointer)data);
721 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
722 if (ip.address.ipv4 == SP_INVALID_IP)
724 SDL_mutexP(gameData->task->statusMutex);
725 gameData->task->status = SP_C4A_ERROR;
726 SDL_mutexV(gameData->task->statusMutex);
729 spNetTCPConnection connection = spNetOpenClientTCP(ip);
730 if (connection == NULL)
732 SDL_mutexP(gameData->task->statusMutex);
733 gameData->task->status = SP_C4A_ERROR;
734 SDL_mutexV(gameData->task->statusMutex);
737 char get_string[512] = "GET /curgamelist_1\n\n";
738 if (spNetSendHTTP(connection,get_string) == 0)
740 spNetCloseTCP(connection);
741 SDL_mutexP(gameData->task->statusMutex);
742 gameData->task->status = SP_C4A_ERROR;
743 SDL_mutexV(gameData->task->statusMutex);
746 //skeezix saves the top500. So 100 byte should be enough...
747 //Haha. NOT! minislug had 50950 with a top 500...
750 if ((length = spNetReceiveHTTP(connection,buffer,100000)) == 0)
752 spNetCloseTCP(connection);
753 SDL_mutexP(gameData->task->statusMutex);
754 gameData->task->status = SP_C4A_ERROR;
755 SDL_mutexV(gameData->task->statusMutex);
759 spNetCloseTCP(connection);
760 //Searching the first [
761 char* found = strchr( buffer, '[' );
764 SDL_mutexP(gameData->task->statusMutex);
765 gameData->task->status = SP_C4A_ERROR;
766 SDL_mutexV(gameData->task->statusMutex);
769 //Reading game by game
770 //Searching the starting {
773 char* start = strchr( found, '{' );
776 SDL_mutexP(gameData->task->statusMutex);
777 gameData->task->status = SP_C4A_ERROR;
778 SDL_mutexV(gameData->task->statusMutex);
781 char* end = my_strchr( start, '}', '\"'); //ignore "text}"-parts
784 SDL_mutexP(gameData->task->statusMutex);
785 gameData->task->status = SP_C4A_ERROR;
786 SDL_mutexV(gameData->task->statusMutex);
789 //Creating substring:
791 //Now we search in the substring
792 //Search for the long name:
793 char* pos = strstr( start, "\"longname\":");
796 fill_between_paraphrases( pos, longname, 128);
798 pos = strstr( start, "\"gamename\":");
801 fill_between_paraphrases( pos, shortname, 128);
803 pos = strstr( start, "\"genre\":");
806 fill_between_paraphrases( pos, genre, 128);
808 pos = strstr( start, "\"field\":");
811 fill_between_paraphrases( pos, field, 128);
813 pos = strstr( start, "\"status\":");
816 fill_between_paraphrases( pos, status, 128);
818 //Re"inserting" substring:
820 found = strchr( end, '{' );
822 //Adding the found stuff to the array:
823 spNetC4AGamePointer new_game = (spNetC4AGamePointer)malloc(sizeof(spNetC4AGame));
824 sprintf(new_game->longname,"%s",longname);
825 sprintf(new_game->shortname,"%s",shortname);
826 sprintf(new_game->genre,"%s",genre);
827 if (strcmp(status,"available") == 0)
828 new_game->status = 1;
830 if (strcmp(status,"active") == 0)
831 new_game->status = 2;
833 new_game->status = 0;
834 if (strcmp(field,"arcade") == 0)
837 if (strcmp(field,"indie") == 0)
840 new_game->field = -1;
843 //Searching the next and before element:
844 spNetC4AGamePointer before = NULL;
845 spNetC4AGamePointer next = *(gameData->game);
848 if (strcmp(new_game->longname,next->longname) < 0)
853 if (before == NULL) //new first element!
855 new_game->next = next;
856 (*(gameData->game)) = new_game;
860 before->next = new_game;
861 new_game->next = next;
864 SDL_mutexP(gameData->task->statusMutex);
865 gameData->task->status = SP_C4A_OK;
866 SDL_mutexV(gameData->task->statusMutex);
870 PREFIX int spNetC4AGetGame(spNetC4AGamePointer* gameList,int timeOut)
873 SDL_mutexP(spGlobalC4ATask->statusMutex);
874 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
876 spGlobalC4ATask->status = SP_C4A_PROGRESS;
877 SDL_mutexV(spGlobalC4ATask->statusMutex);
878 //Starting a background thread, which does the fancy stuff
879 getgamePointer data = (getgamePointer)malloc(sizeof(getgameType));
880 data->function = c4a_getgame_thread;
881 data->task = spGlobalC4ATask;
882 data->game = gameList;
883 spGlobalC4ATask->dataPointer = data;
884 spGlobalC4ATask->timeOut = timeOut;
885 spGlobalC4ATask->threadStatus = 1;
887 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
889 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
893 SDL_mutexV(spGlobalC4ATask->statusMutex);
897 PREFIX spNetC4ATaskPointer spNetC4AGetGameParallel(spNetC4AGamePointer* gameList,int timeOut)
900 spNetC4ATaskPointer task = createNewC4ATask();
901 task->status = SP_C4A_PROGRESS;
902 //Starting a background thread, which does the fancy stuff
903 getgamePointer data = (getgamePointer)malloc(sizeof(getgameType));
904 data->function = c4a_getgame_thread;
906 data->game = gameList;
907 task->dataPointer = data;
908 task->timeOut = timeOut;
909 task->threadStatus = 1;
911 task->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
913 task->thread = SDL_CreateThread(spNetC4AUberThread,data);
918 int c4a_getscore_thread(void* data)
920 getscorePointer scoreData = (getscorePointer)data;
921 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
922 if (ip.address.ipv4 == SP_INVALID_IP)
924 SDL_mutexP(scoreData->task->statusMutex);
925 scoreData->task->status = SP_C4A_ERROR;
926 SDL_mutexV(scoreData->task->statusMutex);
929 spNetTCPConnection connection = spNetOpenClientTCP(ip);
930 if (connection == NULL)
932 SDL_mutexP(scoreData->task->statusMutex);
933 scoreData->task->status = SP_C4A_ERROR;
934 SDL_mutexV(scoreData->task->statusMutex);
937 char get_string[512];
938 if (scoreData->year && scoreData->month)
939 sprintf(get_string,"GET /json_1/%s/%i%02i/\n\n",scoreData->game,scoreData->year,scoreData->month);
941 sprintf(get_string,"GET /json_1/%s/all\n\n",scoreData->game);
942 if (spNetSendHTTP(connection,get_string) == 0)
944 spNetCloseTCP(connection);
945 SDL_mutexP(scoreData->task->statusMutex);
946 scoreData->task->status = SP_C4A_ERROR;
947 SDL_mutexV(scoreData->task->statusMutex);
950 //skeezix saves the top500. So 100 byte should be enough...
951 //Haha. NOT! minislug had 50950 with a top 500...
954 if ((length = spNetReceiveHTTP(connection,buffer,100000)) == 0)
956 spNetCloseTCP(connection);
957 SDL_mutexP(scoreData->task->statusMutex);
958 scoreData->task->status = SP_C4A_ERROR;
959 SDL_mutexV(scoreData->task->statusMutex);
963 spNetCloseTCP(connection);
964 //Searching the first [
965 char* found = strchr( buffer, '[' );
968 SDL_mutexP(scoreData->task->statusMutex);
969 scoreData->task->status = SP_C4A_ERROR;
970 SDL_mutexV(scoreData->task->statusMutex);
973 //Reading score by score
974 //Searching the starting {
976 spNetC4AScorePointer lastScore = NULL;
979 char* start = strchr( found, '{' );
982 SDL_mutexP(scoreData->task->statusMutex);
983 scoreData->task->status = SP_C4A_ERROR;
984 SDL_mutexV(scoreData->task->statusMutex);
987 char* end = my_strchr( start, '}', '\"'); //ignore "text}"-parts
990 SDL_mutexP(scoreData->task->statusMutex);
991 scoreData->task->status = SP_C4A_ERROR;
992 SDL_mutexV(scoreData->task->statusMutex);
995 //Creating substring:
997 //Now we search in the substring
998 //Search for the long name:
999 char* pos = strstr( start, "\"longname\":");
1002 fill_between_paraphrases( pos, longname, 128);
1004 pos = strstr( start, "\"shortname\":");
1006 char shortname[128];
1007 fill_between_paraphrases( pos, shortname, 128);
1009 pos = strstr( start, "\"score\":");
1011 int score = atoi(pos);
1013 pos = strstr( start, "\"time\":");
1015 Uint64 commitTime = (Uint64)(atof(pos)); //float becase of bigger numbers
1017 //Re"inserting" substring:
1019 found = strchr( end, '{' );
1021 //Adding the found stuff to the array:
1022 if (longname[0] == 0 || shortname[0] == 0)
1024 if (scoreData->profile && (strcmp(scoreData->profile->longname,longname) != 0 || strcmp(scoreData->profile->shortname,shortname) != 0))
1026 spNetC4AScorePointer new_score = (spNetC4AScorePointer)malloc(sizeof(spNetC4AScore));
1027 sprintf(new_score->longname,"%s",longname);
1028 sprintf(new_score->shortname,"%s",shortname);
1029 new_score->score = score;
1030 new_score->commitTime = commitTime;
1031 new_score->next = NULL;
1032 new_score->rank = rank;
1033 if (lastScore == NULL)
1034 (*(scoreData->score)) = new_score;
1036 lastScore->next = new_score;
1037 lastScore = new_score;
1041 SDL_mutexP(scoreData->task->statusMutex);
1042 scoreData->task->status = SP_C4A_OK;
1043 SDL_mutexV(scoreData->task->statusMutex);
1047 PREFIX void spNetC4ADeleteGames(spNetC4AGamePointer* gameList)
1049 if (gameList == NULL)
1053 spNetC4AGamePointer next = (*gameList)->next;
1059 PREFIX int spNetC4AGetScore(spNetC4AScorePointer* scoreList,spNetC4AProfilePointer profile,char* game,int timeOut)
1061 (*scoreList) = NULL;
1062 SDL_mutexP(spGlobalC4ATask->statusMutex);
1063 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1065 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1066 SDL_mutexV(spGlobalC4ATask->statusMutex);
1067 //Starting a background thread, which does the fancy stuff
1068 getscorePointer data = (getscorePointer)malloc(sizeof(getscoreType));
1069 data->function = c4a_getscore_thread;
1070 data->task = spGlobalC4ATask;
1071 data->score = scoreList;
1072 data->profile = profile;
1075 sprintf(data->game,"%s",game);
1076 spGlobalC4ATask->dataPointer = data;
1077 spGlobalC4ATask->timeOut = timeOut;
1078 spGlobalC4ATask->threadStatus = 1;
1080 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1082 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
1086 SDL_mutexV(spGlobalC4ATask->statusMutex);
1090 PREFIX int spNetC4AGetScoreOfMonth(spNetC4AScorePointer* scoreList,spNetC4AProfilePointer profile,char* game,int year,int month,int timeOut)
1092 (*scoreList) = NULL;
1093 if (month < 1 || month > 12)
1095 SDL_mutexP(spGlobalC4ATask->statusMutex);
1096 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1098 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1099 SDL_mutexV(spGlobalC4ATask->statusMutex);
1100 //Starting a background thread, which does the fancy stuff
1101 getscorePointer data = (getscorePointer)malloc(sizeof(getscoreType));
1102 data->function = c4a_getscore_thread;
1103 data->task = spGlobalC4ATask;
1104 data->score = scoreList;
1105 data->profile = profile;
1107 data->month = month;
1108 sprintf(data->game,"%s",game);
1109 spGlobalC4ATask->dataPointer = data;
1110 spGlobalC4ATask->timeOut = timeOut;
1111 spGlobalC4ATask->threadStatus = 1;
1113 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1115 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
1119 SDL_mutexV(spGlobalC4ATask->statusMutex);
1123 PREFIX spNetC4ATaskPointer spNetC4AGetScoreParallel(spNetC4AScorePointer* scoreList,spNetC4AProfilePointer profile,char* game,int timeOut)
1125 (*scoreList) = NULL;
1126 spNetC4ATaskPointer task = createNewC4ATask();
1127 task->status = SP_C4A_PROGRESS;
1128 //Starting a background thread, which does the fancy stuff
1129 getscorePointer data = (getscorePointer)malloc(sizeof(getscoreType));
1130 data->function = c4a_getscore_thread;
1132 data->score = scoreList;
1133 data->profile = profile;
1136 sprintf(data->game,"%s",game);
1137 task->dataPointer = data;
1138 task->timeOut = timeOut;
1139 task->threadStatus = 1;
1141 task->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1143 task->thread = SDL_CreateThread(spNetC4AUberThread,data);
1148 PREFIX spNetC4ATaskPointer spNetC4AGetScoreOfMonthParallel(spNetC4AScorePointer* scoreList,spNetC4AProfilePointer profile,char* game,int year,int month,int timeOut)
1150 (*scoreList) = NULL;
1151 if (month < 1 || month > 12)
1153 spNetC4ATaskPointer task = createNewC4ATask();
1154 task->status = SP_C4A_PROGRESS;
1155 SDL_mutexV(task->statusMutex);
1156 //Starting a background thread, which does the fancy stuff
1157 getscorePointer data = (getscorePointer)malloc(sizeof(getscoreType));
1158 data->function = c4a_getscore_thread;
1160 data->score = scoreList;
1161 data->profile = profile;
1163 data->month = month;
1164 sprintf(data->game,"%s",game);
1165 task->dataPointer = data;
1166 task->timeOut = timeOut;
1167 task->threadStatus = 1;
1169 task->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1171 task->thread = SDL_CreateThread(spNetC4AUberThread,data);
1176 PREFIX void spNetC4AFilterScore(spNetC4AScorePointer* scoreList)
1178 spNetC4AScorePointer mom = *scoreList;
1179 spNetC4AScorePointer before = NULL;
1183 spNetC4AScorePointer inner = *scoreList;
1184 while (inner != NULL && inner != mom)
1186 if (strcmp(mom->longname,inner->longname) == 0 &&
1187 strcmp(mom->shortname,inner->shortname) == 0)
1189 inner = inner->next;
1191 spNetC4AScorePointer next = mom->next;
1196 before->next = next;
1205 static int do_the_real_c4a_commit(spNetIP ip,commitPointer commitData,char* game,char* system,char* prid,int score)
1207 spNetTCPConnection connection = spNetOpenClientTCP(ip);
1208 if (connection == NULL)
1210 char commit_string[2048];
1211 sprintf(commit_string,"PUT /plugtally_1/scoreonly/%s/%s/%s?score=%i HTTP/1.1\r\nHost: skeezix.wallednetworks.com:13001\r\nAccept: */*\r\nContent-Length: 0\r\nExpect: 100-continue\r\n",game,system,prid,score);
1212 if (spNetSendHTTP(connection,commit_string) == 0)
1214 spNetCloseTCP(connection);
1217 spNetCloseTCP(connection);
1218 //Adding to scoreList ;)
1219 if (commitData->scoreList)
1221 spNetC4AScorePointer new_score = (spNetC4AScorePointer)malloc(sizeof(spNetC4AScore));
1222 sprintf(new_score->longname,"%s",commitData->profile->longname);
1223 sprintf(new_score->shortname,"%s",commitData->profile->shortname);
1224 new_score->score = score;
1225 new_score->commitTime = time(NULL);
1226 new_score->next = (*(commitData->scoreList));
1227 (*(commitData->scoreList)) = new_score;
1234 #include <windows.h>
1238 #include <sys/types.h>
1239 #include <sys/stat.h>
1243 int c4a_commit_thread(void* data)
1245 commitPointer commitData = (commitPointer)data;
1246 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
1247 if (ip.address.ipv4 == SP_INVALID_IP)
1249 if (spNetC4ACaching && commitData->game[0] != 0)
1250 write_to_cache(commitData->game,commitData->system,commitData->profile->prid,commitData->score,1);
1251 SDL_mutexP(commitData->task->statusMutex);
1252 commitData->task->status = SP_C4A_ERROR;
1253 SDL_mutexV(commitData->task->statusMutex);
1256 if (commitData->game[0] != 0)
1258 if (do_the_real_c4a_commit(ip,commitData,commitData->game,commitData->system,commitData->profile->prid,commitData->score))
1260 if (spNetC4ACaching)
1261 write_to_cache(commitData->game,commitData->system,commitData->profile->prid,commitData->score,1);
1262 SDL_mutexP(commitData->task->statusMutex);
1263 commitData->task->status = SP_C4A_ERROR;
1264 SDL_mutexV(commitData->task->statusMutex);
1268 //Checking for stuff in the cache
1269 SDL_mutexP(spCacheMutex);
1270 cachePointer cache = read_cache();
1275 cachePointer next = cache->next;
1276 if (do_the_real_c4a_commit(ip,commitData,cache->game,cache->system,cache->prid,cache->score))
1280 if (commitData->task->message == 1)
1282 commitData->task->message = 2;
1287 DeleteFile(spCacheFilename);
1289 remove(spCacheFilename);
1291 //if cache is still existing, we need to write back the rest of the cache
1294 cachePointer next = cache->next;
1295 write_to_cache(cache->game,cache->system,cache->prid,cache->score,0);
1301 SDL_mutexV(spCacheMutex);
1303 SDL_mutexP(commitData->task->statusMutex);
1304 commitData->task->status = SP_C4A_OK;
1305 SDL_mutexV(commitData->task->statusMutex);
1309 PREFIX int spNetC4AHowManyCached()
1312 SDL_mutexP(spCacheMutex);
1313 SDL_RWops *file = SDL_RWFromFile(spCacheFilename, "rb");
1316 char buffer[256*3+sizeof(int)];
1319 if (SDL_RWread(file,buffer,256*3+sizeof(int),1) <= 0)
1325 SDL_mutexV(spCacheMutex);
1329 int already_in_highscore(spNetC4AScorePointer scoreList,spNetC4AProfilePointer profile,int score)
1331 if (scoreList == NULL)
1335 if (strcmp(scoreList->longname,profile->longname) == 0 &&
1336 strcmp(scoreList->shortname,profile->shortname) == 0 &&
1337 scoreList->score == score)
1339 scoreList = scoreList->next;
1345 #define SET_SYSTEM(system) sprintf(system,"gp2x");
1346 #elif defined(CAANOO)
1347 #define SET_SYSTEM(system) sprintf(system,"caanoo");
1349 #define SET_SYSTEM(system) sprintf(system,"wiz");
1350 #elif defined(DINGUX)
1351 #define SET_SYSTEM(system) sprintf(system,"dingux");
1353 #define SET_SYSTEM(system) sprintf(system,"gcw");
1354 #elif defined(PANDORA)
1355 #define SET_SYSTEM(system) sprintf(system,"pandora");
1356 #elif defined(WIN32)
1357 #define SET_SYSTEM(system) sprintf(system,"win32");
1359 #define SET_SYSTEM(system) sprintf(system,"linux");
1363 PREFIX int spNetC4ACommitScore(spNetC4AProfilePointer profile,char* game,int score,spNetC4AScorePointer* scoreList,int timeOut)
1365 if (profile == NULL && game[0]!=0)
1368 if (scoreList && already_in_highscore(*scoreList,profile,score))
1372 if (already == 0 && spNetC4ACaching)
1376 write_to_cache(game,system,profile->prid,score,1);
1380 SDL_mutexP(spGlobalC4ATask->statusMutex);
1381 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1383 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1384 SDL_mutexV(spGlobalC4ATask->statusMutex);
1385 //Starting a background thread, which does the fancy stuff
1386 commitPointer data = (commitPointer)malloc(sizeof(commitType));
1387 data->task = spGlobalC4ATask;
1388 data->function = c4a_commit_thread;
1389 data->score = score;
1390 data->profile = profile;
1391 data->scoreList = scoreList;
1395 sprintf(data->game,"%s",game);
1396 SET_SYSTEM(data->system);
1397 spGlobalC4ATask->dataPointer = data;
1398 spGlobalC4ATask->timeOut = timeOut;
1399 spGlobalC4ATask->threadStatus = 1;
1401 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1403 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
1407 SDL_mutexV(spGlobalC4ATask->statusMutex);
1411 PREFIX spNetC4ATaskPointer spNetC4ACommitScoreParallel(spNetC4AProfilePointer profile,char* game,int score,spNetC4AScorePointer* scoreList,int timeOut)
1413 if (profile == NULL)
1416 if (scoreList && already_in_highscore(*scoreList,profile,score))
1420 if (already == 0 && spNetC4ACaching)
1424 write_to_cache(game,system,profile->prid,score,1);
1428 spNetC4ATaskPointer task = createNewC4ATask();
1429 task->status = SP_C4A_PROGRESS;
1430 //Starting a background thread, which does the fancy stuff
1431 commitPointer data = (commitPointer)malloc(sizeof(commitType));
1433 data->function = c4a_commit_thread;
1434 data->score = score;
1435 data->profile = profile;
1436 data->scoreList = scoreList;
1440 sprintf(data->game,"%s",game);
1441 SET_SYSTEM(data->system);
1442 task->dataPointer = data;
1443 task->timeOut = timeOut;
1444 task->threadStatus = 1;
1446 task->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1448 task->thread = SDL_CreateThread(spNetC4AUberThread,data);
1453 PREFIX void spNetC4ACopyScoreList(spNetC4AScorePointer* scoreList,spNetC4AScorePointer* newList)
1455 if (scoreList == NULL)
1457 if (newList == NULL)
1459 spNetC4AScorePointer mom = *scoreList;
1460 spNetC4AScorePointer last = NULL;
1463 spNetC4AScorePointer copy_score = (spNetC4AScorePointer)malloc(sizeof(spNetC4AScore));
1464 sprintf(copy_score->longname,"%s",mom->longname);
1465 sprintf(copy_score->shortname,"%s",mom->shortname);
1466 copy_score->score = mom->score;
1467 copy_score->commitTime = mom->commitTime;
1468 copy_score->rank = mom->rank;
1470 last->next = copy_score;
1472 *newList = copy_score;
1482 typedef struct __ScoreNameStruct *__ScoreNamePointer;
1483 typedef struct __ScoreNameStruct {
1485 char shortname[256];
1486 __ScoreNamePointer next;
1489 PREFIX void spNetC4AMakeScoresUnique(spNetC4AScorePointer* scoreList)
1491 if (scoreList == NULL)
1493 spNetC4AScorePointer mom = *scoreList;
1494 spNetC4AScorePointer before = NULL;
1495 __ScoreNamePointer name = NULL;
1496 __ScoreNamePointer searchStart = NULL;
1499 //search mom in name:
1500 __ScoreNamePointer search = searchStart;
1503 if (strcmp(mom->shortname,search->shortname) == 0 &&
1504 strcmp(mom->longname,search->longname) == 0 )
1506 search = search->next;
1508 if (search) //found -> remove
1510 spNetC4AScorePointer next = mom->next;
1511 before->next = next;
1517 __ScoreNamePointer add = (__ScoreNamePointer)malloc(sizeof(__ScoreName));
1518 sprintf(add->longname,"%s",mom->longname);
1519 sprintf(add->shortname,"%s",mom->shortname);
1520 add->next = searchStart;
1528 __ScoreNamePointer next = searchStart->next;
1534 PREFIX void spNetC4ADeleteScores(spNetC4AScorePointer* scoreList)
1536 if (scoreList == NULL)
1540 spNetC4AScorePointer next = (*scoreList)->next;
1542 (*scoreList) = next;
1546 void fill_with_random_hex(char* buffer,int count)
1549 for (i = 0; i < count; i++)
1561 int c4a_create_thread(void* data)
1563 createPointer createData = (createPointer)data;
1564 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
1565 if (ip.address.ipv4 == SP_INVALID_IP)
1567 SDL_mutexP(createData->task->statusMutex);
1568 createData->task->status = SP_C4A_ERROR;
1569 SDL_mutexV(createData->task->statusMutex);
1572 spNetTCPConnection connection = spNetOpenClientTCP(ip);
1573 if (connection == NULL)
1575 SDL_mutexP(createData->task->statusMutex);
1576 createData->task->status = SP_C4A_ERROR;
1577 SDL_mutexV(createData->task->statusMutex);
1580 char create_string[2048];
1583 //generating a new, random prid:
1584 fill_with_random_hex(prid,8);
1586 fill_with_random_hex(&(prid[ 9]),4);
1588 fill_with_random_hex(&(prid[14]),4);
1590 fill_with_random_hex(&(prid[19]),4);
1592 fill_with_random_hex(&(prid[24]),12);
1594 sprintf(create_string,"{\"email\": \"%s\", \"shortname\": \"%s\", \"password\": \"%s\", \"prid\": \"%s\", \"longname\": \"%s\"}",createData->email,createData->shortname,createData->password,prid,createData->longname);
1595 sprintf(buffer,"PUT /setprofile_1 HTTP/1.1\r\nUser-Agent: sparrowNet/1.0\r\nHost: %i.%i.%i.%i:13001\r\nAccept: */*\r\nContent-Length: %i\r\nExpect: 100-continue\r\n\r\n",ip.address.ipv4_bytes[0],ip.address.ipv4_bytes[1],ip.address.ipv4_bytes[2],ip.address.ipv4_bytes[3],strlen(create_string));
1596 if (spNetSendTCP(connection,buffer,strlen(buffer)) == 0)
1598 spNetCloseTCP(connection);
1599 SDL_mutexP(createData->task->statusMutex);
1600 createData->task->status = SP_C4A_ERROR;
1601 SDL_mutexV(createData->task->statusMutex);
1604 if (spNetSendTCP(connection,create_string,strlen(create_string)) == 0)
1606 spNetCloseTCP(connection);
1607 SDL_mutexP(createData->task->statusMutex);
1608 createData->task->status = SP_C4A_ERROR;
1609 SDL_mutexV(createData->task->statusMutex);
1612 spNetCloseTCP(connection);
1613 PROFILE_FILENAME_MAKRO
1614 SDL_RWops *file=SDL_RWFromFile(filename,"wb");
1615 SDL_RWwrite(file,prid,36,1);
1617 SDL_RWwrite(file,&c,1,1);
1618 SDL_RWwrite(file,create_string,strlen(create_string),1);
1620 (*(createData->profile)) = (spNetC4AProfilePointer)malloc(sizeof(spNetC4AProfile));
1621 sprintf((*(createData->profile))->longname,"%s",createData->longname);
1622 sprintf((*(createData->profile))->shortname,"%s",createData->shortname);
1623 sprintf((*(createData->profile))->password,"%s",createData->password);
1624 sprintf((*(createData->profile))->email,"%s",createData->email);
1625 sprintf((*(createData->profile))->prid,"%s",prid);
1626 SDL_mutexP(createData->task->statusMutex);
1627 createData->task->status = SP_C4A_OK;
1628 SDL_mutexV(createData->task->statusMutex);
1632 PREFIX int spNetC4ACreateProfile(spNetC4AProfilePointer* profile, char* longname,char* shortname,char* password,char* email,int timeOut)
1634 if (profile == NULL)
1636 SDL_mutexP(spGlobalC4ATask->statusMutex);
1637 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1639 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1640 SDL_mutexV(spGlobalC4ATask->statusMutex);
1641 //Starting a background thread, which does the fancy stuff
1642 createPointer data = (createPointer)malloc(sizeof(createType));
1643 data->task = spGlobalC4ATask;
1644 data->function = c4a_create_thread;
1645 data->profile = profile;
1646 sprintf(data->longname,"%s",longname);
1647 sprintf(data->shortname,"%s",shortname);
1648 sprintf(data->password,"%s",password);
1649 sprintf(data->email,"%s",email);
1650 spGlobalC4ATask->dataPointer = data;
1651 spGlobalC4ATask->timeOut = timeOut;
1652 spGlobalC4ATask->threadStatus = 1;
1654 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1656 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
1660 SDL_mutexV(spGlobalC4ATask->statusMutex);
1664 int c4a_delete_thread(void* data)
1666 createPointer createData = (createPointer)data;
1667 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
1668 if (ip.address.ipv4 == SP_INVALID_IP)
1670 SDL_mutexP(createData->task->statusMutex);
1671 createData->task->status = SP_C4A_ERROR;
1672 SDL_mutexV(createData->task->statusMutex);
1675 spNetTCPConnection connection = spNetOpenClientTCP(ip);
1676 if (connection == NULL)
1678 SDL_mutexP(createData->task->statusMutex);
1679 createData->task->status = SP_C4A_ERROR;
1680 SDL_mutexV(createData->task->statusMutex);
1683 char create_string[2048];
1685 sprintf(create_string,"{\"email\": \"%s\", \"shortname\": \"%s\", \"password\": \"%s\", \"prid\": \"%s\", \"longname\": \"%s\"}",(*(createData->profile))->email,(*(createData->profile))->shortname,(*(createData->profile))->password,(*(createData->profile))->prid,(*(createData->profile))->longname);
1686 sprintf(buffer,"PUT /delprofile_1 HTTP/1.1\r\nUser-Agent: sparrowNet/1.0\r\nHost: %i.%i.%i.%i:13001\r\nAccept: */*\r\nContent-Length: %i\r\nExpect: 100-continue\r\n\r\n",ip.address.ipv4_bytes[0],ip.address.ipv4_bytes[1],ip.address.ipv4_bytes[2],ip.address.ipv4_bytes[3],strlen(create_string));
1687 if (spNetSendTCP(connection,buffer,strlen(buffer)) == 0)
1689 spNetCloseTCP(connection);
1690 SDL_mutexP(createData->task->statusMutex);
1691 createData->task->status = SP_C4A_ERROR;
1692 SDL_mutexV(createData->task->statusMutex);
1695 if (spNetSendTCP(connection,create_string,strlen(create_string)) == 0)
1697 spNetCloseTCP(connection);
1698 SDL_mutexP(createData->task->statusMutex);
1699 createData->task->status = SP_C4A_ERROR;
1700 SDL_mutexV(createData->task->statusMutex);
1703 spNetCloseTCP(connection);
1704 (*(createData->profile)) = NULL;
1705 if (createData->deleteFile)
1706 spNetC4ADeleteProfileFile();
1707 SDL_mutexP(createData->task->statusMutex);
1708 createData->task->status = SP_C4A_OK;
1709 SDL_mutexV(createData->task->statusMutex);
1713 PREFIX int spNetC4ADeleteAccount(spNetC4AProfilePointer* profile,int deleteFile,int timeOut)
1715 if (profile == NULL)
1717 SDL_mutexP(spGlobalC4ATask->statusMutex);
1718 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1720 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1721 SDL_mutexV(spGlobalC4ATask->statusMutex);
1722 //Starting a background thread, which does the fancy stuff
1723 createPointer data = (createPointer)malloc(sizeof(createType));
1724 data->task = spGlobalC4ATask;
1725 data->function = c4a_delete_thread;
1726 data->profile = profile;
1727 data->deleteFile = deleteFile;
1728 spGlobalC4ATask->dataPointer = data;
1729 spGlobalC4ATask->timeOut = timeOut;
1730 spGlobalC4ATask->threadStatus = 1;
1732 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,c4a_delete_thread);
1734 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,c4a_delete_thread);
1738 SDL_mutexV(spGlobalC4ATask->statusMutex);
1742 PREFIX void spNetC4ADeleteProfileFile()
1744 PROFILE_FILENAME_MAKRO
1745 //Copied from spRemoveFile to avoid dependencies
1747 DeleteFile(filename);
1753 int c4a_edit_thread(void* data)
1755 createPointer createData = (createPointer)data;
1756 spNetIP ip = spNetResolve("skeezix.wallednetworks.com",13001);
1757 if (ip.address.ipv4 == SP_INVALID_IP)
1759 SDL_mutexP(createData->task->statusMutex);
1760 createData->task->status = SP_C4A_ERROR;
1761 SDL_mutexV(createData->task->statusMutex);
1764 spNetTCPConnection connection = spNetOpenClientTCP(ip);
1765 if (connection == NULL)
1767 SDL_mutexP(createData->task->statusMutex);
1768 createData->task->status = SP_C4A_ERROR;
1769 SDL_mutexV(createData->task->statusMutex);
1772 char create_string[2048];
1774 sprintf(create_string,"{\"email\": \"%s\", \"shortname\": \"%s\", \"password\": \"%s\", \"prid\": \"%s\", \"longname\": \"%s\"}",createData->email,createData->shortname,createData->password,(*(createData->profile))->prid,createData->longname);
1775 sprintf(buffer,"PUT /setprofile_1 HTTP/1.1\r\nUser-Agent: sparrowNet/1.0\r\nHost: %i.%i.%i.%i:13001\r\nAccept: */*\r\nContent-Length: %i\r\nExpect: 100-continue\r\n\r\n",ip.address.ipv4_bytes[0],ip.address.ipv4_bytes[1],ip.address.ipv4_bytes[2],ip.address.ipv4_bytes[3],strlen(create_string));
1776 if (spNetSendTCP(connection,buffer,strlen(buffer)) == 0)
1778 spNetCloseTCP(connection);
1779 SDL_mutexP(createData->task->statusMutex);
1780 createData->task->status = SP_C4A_ERROR;
1781 SDL_mutexV(createData->task->statusMutex);
1784 if (spNetSendTCP(connection,create_string,strlen(create_string)) == 0)
1786 spNetCloseTCP(connection);
1787 SDL_mutexP(createData->task->statusMutex);
1788 createData->task->status = SP_C4A_ERROR;
1789 SDL_mutexV(createData->task->statusMutex);
1792 spNetCloseTCP(connection);
1793 PROFILE_FILENAME_MAKRO
1794 SDL_RWops *file=SDL_RWFromFile(filename,"wb");
1795 SDL_RWwrite(file,(*(createData->profile))->prid,strlen((*(createData->profile))->prid),1);
1797 SDL_RWwrite(file,&c,1,1);
1798 SDL_RWwrite(file,create_string,strlen(create_string),1);
1800 sprintf((*(createData->profile))->longname,"%s",createData->longname);
1801 sprintf((*(createData->profile))->shortname,"%s",createData->shortname);
1802 sprintf((*(createData->profile))->password,"%s",createData->password);
1803 sprintf((*(createData->profile))->email,"%s",createData->email);
1804 SDL_mutexP(createData->task->statusMutex);
1805 createData->task->status = SP_C4A_OK;
1806 SDL_mutexV(createData->task->statusMutex);
1810 PREFIX int spNetC4AEditProfile(spNetC4AProfilePointer* profile,char* longname,char* shortname,char* password,char* email,int timeOut)
1812 if (profile == NULL)
1814 SDL_mutexP(spGlobalC4ATask->statusMutex);
1815 if (spGlobalC4ATask->status != SP_C4A_PROGRESS)
1817 spGlobalC4ATask->status = SP_C4A_PROGRESS;
1818 SDL_mutexV(spGlobalC4ATask->statusMutex);
1819 //Starting a background thread, which does the fancy stuff
1820 createPointer data = (createPointer)malloc(sizeof(createType));
1821 data->task = spGlobalC4ATask;
1822 data->function = c4a_edit_thread;
1823 data->profile = profile;
1824 sprintf(data->longname,"%s",longname);
1825 sprintf(data->shortname,"%s",shortname);
1826 sprintf(data->password,"%s",password);
1827 sprintf(data->email,"%s",email);
1828 spGlobalC4ATask->dataPointer = data;
1829 spGlobalC4ATask->timeOut = timeOut;
1830 spGlobalC4ATask->threadStatus = 1;
1832 spGlobalC4ATask->thread = SDL_CreateThread((int (__cdecl *)(void *))spNetC4AUberThread,data);
1834 spGlobalC4ATask->thread = SDL_CreateThread(spNetC4AUberThread,data);
1838 SDL_mutexV(spGlobalC4ATask->statusMutex);
1842 PREFIX int spNetC4AGetStatusParallel(spNetC4ATaskPointer task)
1844 SDL_mutexP(task->statusMutex);
1845 if (task->threadStatus)
1847 SDL_mutexV(task->statusMutex);
1848 return SP_C4A_PROGRESS;
1850 int status = task->status;
1851 SDL_mutexV(task->statusMutex);
1855 PREFIX int spNetC4AGetStatus()
1857 return spNetC4AGetStatusParallel(spGlobalC4ATask);
1860 PREFIX void spNetC4ACancelTaskParallel(spNetC4ATaskPointer task)
1862 SDL_mutexP(task->statusMutex);
1863 if (task->status > 0)
1865 task->status = SP_C4A_CANCELED;
1866 SDL_mutexV(task->statusMutex);
1867 SDL_WaitThread(task->thread,NULL);
1870 SDL_mutexV(task->statusMutex);
1873 PREFIX void spNetC4ACancelTask()
1875 spNetC4ACancelTaskParallel(spGlobalC4ATask);
1878 PREFIX int spNetC4AGetTaskResult()
1880 return spGlobalC4ATask->result;
1883 PREFIX int spNetC4AGetTaskResultParallel(spNetC4ATaskPointer task)
1885 return task->result;
1888 PREFIX int spNetC4AGetTimeOut()
1890 return spGlobalC4ATask->timeOut;
1893 PREFIX int spNetC4AGetTimeOutParallel(spNetC4ATaskPointer task)
1895 return task->timeOut;