2012-01-19 07:44:59 -06:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
2012-01-19 14:10:05 -06:00
|
|
|
#include <vector>
|
2012-01-19 11:59:00 -06:00
|
|
|
#include <time.h>
|
2012-01-19 14:10:05 -06:00
|
|
|
|
2012-01-19 07:44:59 -06:00
|
|
|
#include "Config.h"
|
|
|
|
#include "Client.h"
|
2012-01-24 18:57:39 -06:00
|
|
|
#include "MD5.h"
|
2012-01-19 07:44:59 -06:00
|
|
|
#include "Graphics.h"
|
|
|
|
|
2012-01-19 14:10:05 -06:00
|
|
|
#include "interface/Point.h"
|
|
|
|
|
|
|
|
#include "search/Save.h"
|
|
|
|
|
|
|
|
#include "cajun/reader.h"
|
|
|
|
#include "cajun/writer.h"
|
|
|
|
#include "cajun/elements.h"
|
|
|
|
|
2012-01-19 07:44:59 -06:00
|
|
|
Client::Client()
|
|
|
|
{
|
|
|
|
int i = 0;
|
2012-01-24 17:33:32 -06:00
|
|
|
http_init(NULL);
|
2012-01-19 11:59:00 -06:00
|
|
|
for(i = 0; i < THUMB_CACHE_SIZE; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
thumbnailCache[i] = NULL;
|
|
|
|
}
|
2012-01-19 11:59:00 -06:00
|
|
|
for(i = 0; i < IMGCONNS; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
activeThumbRequests[i] = NULL;
|
|
|
|
activeThumbRequestTimes[i] = 0;
|
2012-01-19 11:59:00 -06:00
|
|
|
activeThumbRequestCompleteTimes[i] = 0;
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Client::~Client()
|
|
|
|
{
|
2012-01-21 07:19:10 -06:00
|
|
|
ClearThumbnailRequests();
|
2012-01-19 07:44:59 -06:00
|
|
|
http_done();
|
|
|
|
}
|
|
|
|
|
2012-01-24 14:19:19 -06:00
|
|
|
LoginStatus Client::Login(string username, string password)
|
|
|
|
{
|
2012-01-24 18:57:39 -06:00
|
|
|
lastError = "";
|
2012-01-24 14:19:19 -06:00
|
|
|
std::stringstream urlStream;
|
2012-01-24 18:57:39 -06:00
|
|
|
std::stringstream hashStream;
|
|
|
|
unsigned char cHashData[16];
|
|
|
|
|
|
|
|
//Build hash of username + password
|
|
|
|
struct md5_context md5;
|
|
|
|
md5_init(&md5);
|
|
|
|
md5_update(&md5, (unsigned char *)username.c_str(), username.length());
|
|
|
|
md5_update(&md5, (unsigned char *)"-", 1);
|
|
|
|
md5_update(&md5, (unsigned char *)password.c_str(), password.length());
|
|
|
|
md5_final(cHashData, &md5);
|
|
|
|
//Make sure hash is Hex
|
|
|
|
//char * cHashHex = (char *)malloc(33);
|
|
|
|
for(int i = 0; i < 16; i++)
|
|
|
|
{
|
|
|
|
hashStream << hexChars[cHashData[i]>>4] << hexChars[cHashData[i]&15];
|
|
|
|
//cHashHex[i*2] = hex[cHashData[i]>>4];
|
|
|
|
//cHashHex[i*2+1] = hex[cHashData[i]&15];
|
|
|
|
}
|
|
|
|
//cHashHex[32] = 0;
|
|
|
|
|
2012-01-24 14:19:19 -06:00
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
2012-01-24 18:57:39 -06:00
|
|
|
char * postNames[] = { "Username", "Hash", NULL };
|
|
|
|
char * postDatas[] = { (char*)username.c_str(), (char*)hashStream.str().c_str() };
|
|
|
|
int postLengths[] = { username.length(), hashStream.str().length() };
|
|
|
|
data = http_multipart_post("http://" SERVER "/Login.json", postNames, postDatas, postLengths, NULL, NULL, NULL, &dataStatus, &dataLength);
|
|
|
|
//data = http_auth_get("http://" SERVER "/Login.json", (char*)username.c_str(), (char*)password.c_str(), NULL, &dataStatus, &dataLength);
|
2012-01-24 14:19:19 -06:00
|
|
|
std::cout << data << std::endl;
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
2012-01-24 18:57:39 -06:00
|
|
|
try
|
2012-01-24 14:19:19 -06:00
|
|
|
{
|
2012-01-24 18:57:39 -06:00
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
json::Number tempStatus = objDocument["Status"];
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
if(tempStatus.Value() == 1)
|
|
|
|
{
|
|
|
|
return LoginOkay;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
json::String tempError = objDocument["Error"];
|
|
|
|
lastError = tempError.Value();
|
|
|
|
return LoginError;
|
|
|
|
}
|
2012-01-24 14:19:19 -06:00
|
|
|
}
|
2012-01-24 18:57:39 -06:00
|
|
|
catch (json::Exception &e)
|
2012-01-24 14:19:19 -06:00
|
|
|
{
|
2012-01-24 18:57:39 -06:00
|
|
|
lastError = "Server responded with crap";
|
2012-01-24 14:19:19 -06:00
|
|
|
return LoginError;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
return LoginError;
|
|
|
|
}
|
|
|
|
|
2012-01-23 16:53:57 -06:00
|
|
|
Save * Client::GetSave(int saveID, int saveDate)
|
|
|
|
{
|
|
|
|
lastError = "";
|
|
|
|
std::stringstream urlStream;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID;
|
|
|
|
if(saveDate)
|
|
|
|
{
|
|
|
|
urlStream << "&Date=" << saveDate;
|
|
|
|
}
|
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
//Save(int _id, int _votesUp, int _votesDown, string _userName, string _name, string description_, string date_, bool published_):
|
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
json::Number tempID = objDocument["ID"];
|
|
|
|
json::Number tempScoreUp = objDocument["ScoreUp"];
|
|
|
|
json::Number tempScoreDown = objDocument["ScoreDown"];
|
|
|
|
json::String tempUsername = objDocument["Username"];
|
|
|
|
json::String tempName = objDocument["Name"];
|
|
|
|
json::String tempDescription = objDocument["Description"];
|
|
|
|
json::String tempDate = objDocument["Date"];
|
|
|
|
json::Boolean tempPublished = objDocument["Published"];
|
|
|
|
return new Save(
|
|
|
|
tempID.Value(),
|
|
|
|
tempScoreUp.Value(),
|
|
|
|
tempScoreDown.Value(),
|
|
|
|
tempUsername.Value(),
|
|
|
|
tempName.Value(),
|
|
|
|
tempDescription.Value(),
|
|
|
|
tempDate.Value(),
|
|
|
|
tempPublished.Value()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thumbnail * Client::GetPreview(int saveID, int saveDate)
|
|
|
|
{
|
|
|
|
std::stringstream urlStream;
|
|
|
|
urlStream << "http://" << SERVER << "/Get.api?Op=thumblarge&ID=" << saveID;
|
|
|
|
if(saveDate)
|
|
|
|
{
|
|
|
|
urlStream << "&Date=" << saveDate;
|
|
|
|
}
|
|
|
|
pixel * thumbData;
|
|
|
|
char * data;
|
|
|
|
int status, data_size, imgw, imgh;
|
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &status, &data_size);
|
|
|
|
if (status == 200 && data)
|
|
|
|
{
|
|
|
|
thumbData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh);
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
if(thumbData)
|
|
|
|
{
|
|
|
|
return new Thumbnail(saveID, saveDate, thumbData, ui::Point(imgw, imgh));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
return new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-21 12:51:28 -06:00
|
|
|
std::vector<Save*> * Client::SearchSaves(int start, int count, string query, string sort, int & resultCount)
|
2012-01-19 14:10:05 -06:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-01-21 12:51:28 -06:00
|
|
|
resultCount = 0;
|
2012-01-20 18:17:42 -06:00
|
|
|
std::vector<Save*> * saveArray = new std::vector<Save*>();
|
2012-01-19 14:10:05 -06:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << cout;
|
|
|
|
if(query.length() || sort.length())
|
|
|
|
{
|
|
|
|
urlStream << "&Search_Query=";
|
|
|
|
if(query.length())
|
|
|
|
urlStream << query;
|
2012-01-21 12:51:28 -06:00
|
|
|
if(sort == "date")
|
2012-01-19 14:10:05 -06:00
|
|
|
{
|
|
|
|
if(query.length())
|
|
|
|
urlStream << " ";
|
|
|
|
urlStream << "sort:" << sort;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2012-01-23 16:53:57 -06:00
|
|
|
std::istringstream dataStream(data);
|
2012-01-19 14:10:05 -06:00
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
2012-01-21 12:51:28 -06:00
|
|
|
json::Number tempCount = objDocument["Count"];
|
|
|
|
resultCount = tempCount.Value();
|
2012-01-19 14:10:05 -06:00
|
|
|
json::Array savesArray = objDocument["Saves"];
|
|
|
|
for(int j = 0; j < savesArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::Number tempID = savesArray[j]["ID"];
|
|
|
|
json::Number tempScoreUp = savesArray[j]["ScoreUp"];
|
|
|
|
json::Number tempScoreDown = savesArray[j]["ScoreDown"];
|
|
|
|
json::String tempUsername = savesArray[j]["Username"];
|
|
|
|
json::String tempName = savesArray[j]["Name"];
|
2012-01-20 18:17:42 -06:00
|
|
|
saveArray->push_back(
|
|
|
|
new Save(
|
2012-01-19 14:10:05 -06:00
|
|
|
tempID.Value(),
|
|
|
|
tempScoreUp.Value(),
|
|
|
|
tempScoreDown.Value(),
|
|
|
|
tempUsername.Value(),
|
|
|
|
tempName.Value()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return saveArray;
|
|
|
|
}
|
|
|
|
|
2012-01-19 07:44:59 -06:00
|
|
|
void Client::ClearThumbnailRequests()
|
|
|
|
{
|
2012-01-19 11:59:00 -06:00
|
|
|
for(int i = 0; i < IMGCONNS; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
if(activeThumbRequests[i])
|
|
|
|
{
|
|
|
|
http_async_req_close(activeThumbRequests[i]);
|
|
|
|
activeThumbRequests[i] = NULL;
|
2012-01-19 11:59:00 -06:00
|
|
|
activeThumbRequestTimes[i] = 0;
|
|
|
|
activeThumbRequestCompleteTimes[i] = 0;
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Thumbnail * Client::GetThumbnail(int saveID, int saveDate)
|
|
|
|
{
|
|
|
|
std::stringstream urlStream;
|
|
|
|
std::stringstream idStream;
|
2012-01-19 11:59:00 -06:00
|
|
|
int i = 0, currentTime = time(NULL);
|
|
|
|
//Check active requests for any "forgotten" requests
|
|
|
|
for(i = 0; i < IMGCONNS; i++)
|
|
|
|
{
|
|
|
|
//If the request is active, and we've recieved a response
|
|
|
|
if(activeThumbRequests[i] && http_async_req_status(activeThumbRequests[i]))
|
|
|
|
{
|
|
|
|
//If we haven't already, mark the request as completed
|
|
|
|
if(!activeThumbRequestCompleteTimes[i])
|
|
|
|
{
|
|
|
|
activeThumbRequestCompleteTimes[i] = time(NULL);
|
|
|
|
}
|
2012-01-21 12:51:28 -06:00
|
|
|
else if(activeThumbRequestCompleteTimes[i] < (currentTime-2)) //Otherwise, if it completed more than 2 seconds ago, destroy it.
|
2012-01-19 11:59:00 -06:00
|
|
|
{
|
|
|
|
http_async_req_close(activeThumbRequests[i]);
|
|
|
|
activeThumbRequests[i] = NULL;
|
|
|
|
activeThumbRequestTimes[i] = 0;
|
|
|
|
activeThumbRequestCompleteTimes[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(i = 0; i < THUMB_CACHE_SIZE; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
if(thumbnailCache[i] && thumbnailCache[i]->ID == saveID && thumbnailCache[i]->Datestamp == saveDate)
|
|
|
|
return thumbnailCache[i];
|
|
|
|
}
|
|
|
|
urlStream << "http://" << SERVER << "/Get.api?Op=thumbsmall&ID=" << saveID;
|
|
|
|
if(saveDate)
|
|
|
|
{
|
|
|
|
urlStream << "&Date=" << saveDate;
|
|
|
|
}
|
|
|
|
idStream << saveID << ":" << saveDate;
|
|
|
|
std::string idString = idStream.str();
|
|
|
|
bool found = false;
|
2012-01-19 11:59:00 -06:00
|
|
|
for(i = 0; i < IMGCONNS; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
if(activeThumbRequests[i] && activeThumbRequestIDs[i] == idString)
|
|
|
|
{
|
|
|
|
found = true;
|
|
|
|
if(http_async_req_status(activeThumbRequests[i]))
|
|
|
|
{
|
|
|
|
pixel * thumbData;
|
|
|
|
char * data;
|
|
|
|
int status, data_size, imgw, imgh;
|
|
|
|
data = http_async_req_stop(activeThumbRequests[i], &status, &data_size);
|
2012-01-21 12:51:28 -06:00
|
|
|
free(activeThumbRequests[i]);
|
2012-01-19 07:44:59 -06:00
|
|
|
activeThumbRequests[i] = NULL;
|
|
|
|
if (status == 200 && data)
|
|
|
|
{
|
|
|
|
thumbData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh);
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
2012-01-19 11:59:00 -06:00
|
|
|
thumbnailCacheNextID %= THUMB_CACHE_SIZE;
|
2012-01-19 07:44:59 -06:00
|
|
|
if(thumbnailCache[thumbnailCacheNextID])
|
|
|
|
{
|
|
|
|
delete thumbnailCache[thumbnailCacheNextID];
|
|
|
|
}
|
|
|
|
if(thumbData)
|
|
|
|
{
|
|
|
|
thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, thumbData, ui::Point(imgw, imgh));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128));
|
|
|
|
}
|
|
|
|
return thumbnailCache[thumbnailCacheNextID++];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
2012-01-19 11:59:00 -06:00
|
|
|
thumbnailCacheNextID %= THUMB_CACHE_SIZE;
|
2012-01-19 07:44:59 -06:00
|
|
|
if(thumbnailCache[thumbnailCacheNextID])
|
|
|
|
{
|
|
|
|
delete thumbnailCache[thumbnailCacheNextID];
|
|
|
|
}
|
|
|
|
thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128));
|
|
|
|
return thumbnailCache[thumbnailCacheNextID++];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!found)
|
|
|
|
{
|
2012-01-19 11:59:00 -06:00
|
|
|
for(i = 0; i < IMGCONNS; i++)
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
if(!activeThumbRequests[i])
|
|
|
|
{
|
|
|
|
activeThumbRequests[i] = http_async_req_start(NULL, (char *)urlStream.str().c_str(), NULL, 0, 1);
|
2012-01-19 11:59:00 -06:00
|
|
|
activeThumbRequestTimes[i] = currentTime;
|
|
|
|
activeThumbRequestCompleteTimes[i] = 0;
|
2012-01-19 07:44:59 -06:00
|
|
|
activeThumbRequestIDs[i] = idString;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//http_async_req_start(http, urlStream.str().c_str(), NULL, 0, 1);
|
|
|
|
return NULL;
|
|
|
|
}
|