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-04-02 11:01:28 -05:00
|
|
|
#include <iomanip>
|
2012-01-19 11:59:00 -06:00
|
|
|
#include <time.h>
|
2012-04-19 09:22:18 -05:00
|
|
|
#include <stdio.h>
|
2012-06-21 19:04:55 -05:00
|
|
|
#include <deque>
|
2012-08-12 16:32:57 -05:00
|
|
|
#include <fstream>
|
2012-10-01 21:00:57 -05:00
|
|
|
#include <dirent.h>
|
2012-01-19 14:10:05 -06:00
|
|
|
|
2012-08-10 09:41:39 -05:00
|
|
|
#ifdef MACOSX
|
|
|
|
#include <mach-o/dyld.h>
|
|
|
|
#include <ApplicationServices/ApplicationServices.h>
|
|
|
|
#endif
|
|
|
|
|
2012-07-29 11:14:14 -05:00
|
|
|
#ifdef WIN
|
2012-08-10 09:41:39 -05:00
|
|
|
#include <shlobj.h>
|
|
|
|
#include <shlwapi.h>
|
|
|
|
#include <windows.h>
|
2012-04-02 11:01:28 -05:00
|
|
|
#include <direct.h>
|
|
|
|
#else
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2012-01-19 07:44:59 -06:00
|
|
|
#include "Config.h"
|
2012-08-12 09:15:47 -05:00
|
|
|
#include "Format.h"
|
2012-01-19 07:44:59 -06:00
|
|
|
#include "Client.h"
|
2012-01-24 18:57:39 -06:00
|
|
|
#include "MD5.h"
|
2012-07-06 10:06:26 -05:00
|
|
|
#include "graphics/Graphics.h"
|
2012-02-01 15:20:27 -06:00
|
|
|
#include "Misc.h"
|
2012-08-12 16:32:57 -05:00
|
|
|
#include "Update.h"
|
|
|
|
#include "HTTP.h"
|
2012-01-19 07:44:59 -06:00
|
|
|
|
2012-07-31 13:49:08 -05:00
|
|
|
#include "simulation/SaveRenderer.h"
|
2012-01-19 14:10:05 -06:00
|
|
|
#include "interface/Point.h"
|
2012-06-07 08:23:26 -05:00
|
|
|
#include "client/SaveInfo.h"
|
2012-08-12 16:32:57 -05:00
|
|
|
#include "client/SaveFile.h"
|
|
|
|
#include "client/GameSave.h"
|
2013-03-16 12:45:18 -05:00
|
|
|
#include "client/UserInfo.h"
|
2012-08-12 16:32:57 -05:00
|
|
|
#include "search/Thumbnail.h"
|
|
|
|
#include "preview/Comment.h"
|
2012-06-20 07:40:18 -05:00
|
|
|
#include "ClientListener.h"
|
2013-03-14 06:30:24 -05:00
|
|
|
#include "requestbroker/RequestBroker.h"
|
2013-03-16 12:45:18 -05:00
|
|
|
#include "requestbroker/APIRequest.h"
|
|
|
|
#include "requestbroker/APIResultParser.h"
|
2012-06-21 19:44:30 -05:00
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
#include "cajun/reader.h"
|
|
|
|
#include "cajun/writer.h"
|
|
|
|
|
2012-07-27 14:06:17 -05:00
|
|
|
extern "C"
|
|
|
|
{
|
2012-07-29 11:14:14 -05:00
|
|
|
#if defined(WIN) && !defined(__GNUC__)
|
2012-07-27 14:06:17 -05:00
|
|
|
#include <io.h>
|
|
|
|
#else
|
|
|
|
#include <dirent.h>
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-01-28 13:56:13 -06:00
|
|
|
Client::Client():
|
2012-06-20 07:40:18 -05:00
|
|
|
authUser(0, ""),
|
2012-08-08 12:34:37 -05:00
|
|
|
updateAvailable(false),
|
2012-08-17 11:02:02 -05:00
|
|
|
versionCheckRequest(NULL),
|
|
|
|
messageOfTheDay("")
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
|
|
|
int i = 0;
|
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
|
|
|
}
|
2012-01-31 12:49:14 -06:00
|
|
|
|
|
|
|
//Read config
|
|
|
|
std::ifstream configFile;
|
2012-08-12 16:32:57 -05:00
|
|
|
configFile.open("powder.pref", std::ios::binary);
|
2012-01-31 12:49:14 -06:00
|
|
|
if(configFile)
|
|
|
|
{
|
|
|
|
int fsize = configFile.tellg();
|
|
|
|
configFile.seekg(0, std::ios::end);
|
2012-04-19 19:45:43 -05:00
|
|
|
fsize = configFile.tellg() - (std::streampos)fsize;
|
2012-08-12 16:32:57 -05:00
|
|
|
configFile.seekg(0, std::ios::beg);
|
2012-01-31 12:49:14 -06:00
|
|
|
if(fsize)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2012-08-14 12:14:06 -05:00
|
|
|
json::Reader::Read(configDocument, configFile);
|
2012-01-31 12:49:14 -06:00
|
|
|
authUser.ID = ((json::Number)(configDocument["User"]["ID"])).Value();
|
|
|
|
authUser.SessionID = ((json::String)(configDocument["User"]["SessionID"])).Value();
|
|
|
|
authUser.SessionKey = ((json::String)(configDocument["User"]["SessionKey"])).Value();
|
|
|
|
authUser.Username = ((json::String)(configDocument["User"]["Username"])).Value();
|
2012-04-14 13:00:24 -05:00
|
|
|
|
|
|
|
std::string userElevation = ((json::String)(configDocument["User"]["Elevation"])).Value();
|
|
|
|
if(userElevation == "Admin")
|
2012-08-12 16:32:57 -05:00
|
|
|
authUser.UserElevation = User::ElevationAdmin;
|
2012-04-14 13:00:24 -05:00
|
|
|
else if(userElevation == "Mod")
|
2012-08-12 16:32:57 -05:00
|
|
|
authUser.UserElevation = User::ElevationModerator;
|
2012-04-14 13:00:24 -05:00
|
|
|
else
|
2012-08-12 16:32:57 -05:00
|
|
|
authUser.UserElevation = User::ElevationNone;
|
2012-01-31 12:49:14 -06:00
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
authUser = User(0, "");
|
2012-08-14 12:14:06 -05:00
|
|
|
std::cerr << "Error: Could not read data from prefs: " << e.what() << std::endl;
|
2012-01-31 12:49:14 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
configFile.close();
|
|
|
|
}
|
2012-08-08 12:34:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void Client::Initialise(std::string proxyString)
|
|
|
|
{
|
2012-01-31 12:49:14 -06:00
|
|
|
|
2012-06-21 19:44:30 -05:00
|
|
|
if(GetPrefBool("version.update", false)==true)
|
|
|
|
{
|
|
|
|
SetPref("version.update", false);
|
|
|
|
update_finish();
|
|
|
|
}
|
|
|
|
|
2012-01-31 12:49:14 -06:00
|
|
|
if(proxyString.length())
|
2013-03-12 16:29:27 -05:00
|
|
|
http_init((char*)proxyString.c_str());
|
2012-01-31 12:49:14 -06:00
|
|
|
else
|
|
|
|
http_init(NULL);
|
2012-04-02 11:01:28 -05:00
|
|
|
|
|
|
|
//Read stamps library
|
|
|
|
std::ifstream stampsLib;
|
2012-08-12 16:32:57 -05:00
|
|
|
stampsLib.open(STAMPS_DIR PATH_SEP "stamps.def", std::ios::binary);
|
2012-10-01 07:36:56 -05:00
|
|
|
while(!stampsLib.eof())
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
|
|
|
char data[11];
|
|
|
|
memset(data, 0, 11);
|
2012-10-01 07:36:56 -05:00
|
|
|
stampsLib.read(data, 10);
|
2012-04-02 11:01:28 -05:00
|
|
|
if(!data[0])
|
|
|
|
break;
|
|
|
|
stampIDs.push_back(data);
|
|
|
|
}
|
|
|
|
stampsLib.close();
|
2012-06-20 07:40:18 -05:00
|
|
|
|
|
|
|
//Begin version check
|
2012-11-26 04:34:17 -06:00
|
|
|
versionCheckRequest = http_async_req_start(NULL, SERVER "/Startup.json", NULL, 0, 0);
|
2012-08-12 09:15:47 -05:00
|
|
|
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
2013-03-10 21:08:00 -05:00
|
|
|
std::string idTempString = format::NumberToString<int>(authUser.ID);
|
|
|
|
char *id = new char[idTempString.length() + 1];
|
|
|
|
std::strcpy (id, idTempString.c_str());
|
|
|
|
char *session = new char[authUser.SessionID.length() + 1];
|
|
|
|
std::strcpy (session, authUser.SessionID.c_str());
|
|
|
|
http_auth_headers(versionCheckRequest, id, NULL, session);
|
|
|
|
delete[] id;
|
|
|
|
delete[] session;
|
2012-08-12 09:15:47 -05:00
|
|
|
}
|
2012-06-20 07:40:18 -05:00
|
|
|
}
|
|
|
|
|
2012-08-10 09:41:39 -05:00
|
|
|
bool Client::DoInstallation()
|
|
|
|
{
|
|
|
|
#if defined(WIN)
|
|
|
|
int returnval;
|
|
|
|
LONG rresult;
|
|
|
|
HKEY newkey;
|
|
|
|
char *currentfilename = exe_name();
|
|
|
|
char *iconname = NULL;
|
|
|
|
char *opencommand = NULL;
|
2012-12-15 10:56:55 -06:00
|
|
|
char *protocolcommand = NULL;
|
2012-08-10 09:41:39 -05:00
|
|
|
//char AppDataPath[MAX_PATH];
|
|
|
|
char *AppDataPath = NULL;
|
|
|
|
iconname = (char*)malloc(strlen(currentfilename)+6);
|
|
|
|
sprintf(iconname, "%s,-102", currentfilename);
|
|
|
|
|
|
|
|
//Create Roaming application data folder
|
|
|
|
/*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath)))
|
|
|
|
{
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}*/
|
|
|
|
|
2012-08-24 13:03:20 -05:00
|
|
|
AppDataPath = _getcwd(NULL, 0);
|
2012-08-10 09:41:39 -05:00
|
|
|
|
|
|
|
//Move Game executable into application data folder
|
|
|
|
//TODO: Implement
|
|
|
|
|
|
|
|
opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
|
2012-12-15 10:56:55 -06:00
|
|
|
protocolcommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
|
2012-08-10 09:41:39 -05:00
|
|
|
/*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))<MAX_PATH)
|
|
|
|
{
|
|
|
|
strappend(AppDataPath, APPDATA_SUBDIR);
|
|
|
|
_mkdir(AppDataPath);
|
|
|
|
strappend(AppDataPath, "\\Powder Toy");
|
|
|
|
_mkdir(AppDataPath);
|
|
|
|
} else {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}*/
|
|
|
|
sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath);
|
2012-12-15 10:56:55 -06:00
|
|
|
sprintf(protocolcommand, "\"%s\" ddir \"%s\" ptsave \"%%1\"", currentfilename, AppDataPath);
|
|
|
|
|
|
|
|
//Create protocol entry
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\ptsave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, (LPCSTR)"URL Protocol", 0, REG_SZ, (LPBYTE)"", strlen("")+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
//Set Protocol DefaultIcon
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\ptsave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
//Set Protocol Launch command
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\ptsave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)protocolcommand, strlen(protocolcommand)+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
2012-08-10 09:41:39 -05:00
|
|
|
|
|
|
|
//Create extension entry
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
//Create program entry
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
//Set DefaultIcon
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
//Set Launch command
|
|
|
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1);
|
|
|
|
if (rresult != ERROR_SUCCESS) {
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
returnval = 0;
|
|
|
|
goto finalise;
|
|
|
|
}
|
|
|
|
RegCloseKey(newkey);
|
|
|
|
|
|
|
|
returnval = 1;
|
|
|
|
finalise:
|
|
|
|
|
|
|
|
if(iconname) free(iconname);
|
|
|
|
if(opencommand) free(opencommand);
|
2012-12-15 10:56:55 -06:00
|
|
|
if(protocolcommand) free(protocolcommand);
|
2012-08-10 09:41:39 -05:00
|
|
|
if(currentfilename) free(currentfilename);
|
|
|
|
|
|
|
|
return returnval;
|
|
|
|
#elif defined(LIN)
|
|
|
|
#include "icondoc.h"
|
|
|
|
|
|
|
|
char *currentfilename = exe_name();
|
|
|
|
FILE *f;
|
|
|
|
char *mimedata =
|
|
|
|
"<?xml version=\"1.0\"?>\n"
|
|
|
|
" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
|
|
|
|
" <mime-type type=\"application/vnd.powdertoy.save\">\n"
|
|
|
|
" <comment>Powder Toy save</comment>\n"
|
|
|
|
" <glob pattern=\"*.cps\"/>\n"
|
|
|
|
" <glob pattern=\"*.stm\"/>\n"
|
|
|
|
" </mime-type>\n"
|
|
|
|
"</mime-info>\n";
|
|
|
|
f = fopen("powdertoy-save.xml", "wb");
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
fwrite(mimedata, 1, strlen(mimedata), f);
|
|
|
|
fclose(f);
|
|
|
|
|
2012-08-14 06:36:04 -05:00
|
|
|
char *protocolfiledata_tmp =
|
|
|
|
"[Desktop Entry]\n"
|
|
|
|
"Type=Application\n"
|
|
|
|
"Name=Powder Toy\n"
|
|
|
|
"Comment=Physics sandbox game\n"
|
|
|
|
"MimeType=x-scheme-handler/ptsave;\n"
|
|
|
|
"NoDisplay=true\n";
|
|
|
|
char *protocolfiledata = (char *)malloc(strlen(protocolfiledata_tmp)+strlen(currentfilename)+100);
|
|
|
|
strcpy(protocolfiledata, protocolfiledata_tmp);
|
|
|
|
strappend(protocolfiledata, "Exec=");
|
|
|
|
strappend(protocolfiledata, currentfilename);
|
|
|
|
strappend(protocolfiledata, " ptsave %u\n");
|
|
|
|
f = fopen("powdertoy-tpt-ptsave.desktop", "wb");
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
fwrite(protocolfiledata, 1, strlen(protocolfiledata), f);
|
|
|
|
fclose(f);
|
|
|
|
system("xdg-desktop-menu install powdertoy-tpt-ptsave.desktop");
|
|
|
|
|
2012-08-10 09:41:39 -05:00
|
|
|
char *desktopfiledata_tmp =
|
|
|
|
"[Desktop Entry]\n"
|
|
|
|
"Type=Application\n"
|
|
|
|
"Name=Powder Toy\n"
|
|
|
|
"Comment=Physics sandbox game\n"
|
|
|
|
"MimeType=application/vnd.powdertoy.save;\n"
|
|
|
|
"NoDisplay=true\n";
|
|
|
|
char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100);
|
|
|
|
strcpy(desktopfiledata, desktopfiledata_tmp);
|
|
|
|
strappend(desktopfiledata, "Exec=");
|
|
|
|
strappend(desktopfiledata, currentfilename);
|
|
|
|
strappend(desktopfiledata, " open %f\n");
|
|
|
|
f = fopen("powdertoy-tpt.desktop", "wb");
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
fwrite(desktopfiledata, 1, strlen(desktopfiledata), f);
|
|
|
|
fclose(f);
|
|
|
|
system("xdg-mime install powdertoy-save.xml");
|
|
|
|
system("xdg-desktop-menu install powdertoy-tpt.desktop");
|
|
|
|
f = fopen("powdertoy-save-32.png", "wb");
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f);
|
|
|
|
fclose(f);
|
|
|
|
f = fopen("powdertoy-save-16.png", "wb");
|
|
|
|
if (!f)
|
|
|
|
return 0;
|
|
|
|
fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f);
|
|
|
|
fclose(f);
|
|
|
|
system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save");
|
|
|
|
system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save");
|
|
|
|
system("xdg-icon-resource forceupdate");
|
|
|
|
system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save");
|
2012-08-14 06:36:04 -05:00
|
|
|
system("xdg-mime default powdertoy-tpt-ptsave.desktop x-scheme-handler/ptsave");
|
2012-08-10 09:41:39 -05:00
|
|
|
unlink("powdertoy-save-32.png");
|
|
|
|
unlink("powdertoy-save-16.png");
|
|
|
|
unlink("powdertoy-save.xml");
|
|
|
|
unlink("powdertoy-tpt.desktop");
|
2012-08-14 06:36:50 -05:00
|
|
|
unlink("powdertoy-tpt-ptsave.desktop");
|
2012-08-10 09:41:39 -05:00
|
|
|
return true;
|
|
|
|
#elif defined MACOSX
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-08-08 12:34:37 -05:00
|
|
|
void Client::SetProxy(std::string proxy)
|
|
|
|
{
|
|
|
|
http_done();
|
|
|
|
if(proxy.length())
|
2013-03-12 16:29:27 -05:00
|
|
|
http_init((char*)proxy.c_str());
|
2012-08-08 12:34:37 -05:00
|
|
|
else
|
|
|
|
http_init(NULL);
|
|
|
|
}
|
|
|
|
|
2012-07-27 14:06:17 -05:00
|
|
|
std::vector<std::string> Client::DirectorySearch(std::string directory, std::string search, std::string extension)
|
|
|
|
{
|
|
|
|
std::vector<std::string> extensions;
|
|
|
|
extensions.push_back(extension);
|
2013-03-08 21:31:08 -06:00
|
|
|
for (std::string::iterator iter = search.begin(); iter != search.end(); ++iter)
|
|
|
|
*iter = toupper(*iter);
|
2012-07-27 14:06:17 -05:00
|
|
|
return DirectorySearch(directory, search, extensions);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> Client::DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions)
|
|
|
|
{
|
|
|
|
//Get full file listing
|
2012-11-18 12:02:28 -06:00
|
|
|
//Normalise directory string, ensure / or \ is present
|
|
|
|
if(*directory.rbegin() != '/' && *directory.rbegin() != '\\')
|
|
|
|
directory += PATH_SEP;
|
2012-07-27 14:06:17 -05:00
|
|
|
std::vector<std::string> directoryList;
|
2012-07-29 11:14:14 -05:00
|
|
|
#if defined(WIN) && !defined(__GNUC__)
|
2012-07-27 14:06:17 -05:00
|
|
|
//Windows
|
|
|
|
struct _finddata_t currentFile;
|
|
|
|
intptr_t findFileHandle;
|
|
|
|
std::string fileMatch = directory + "*.*";
|
|
|
|
findFileHandle = _findfirst(fileMatch.c_str(), ¤tFile);
|
|
|
|
if (findFileHandle == -1L)
|
|
|
|
{
|
2012-12-16 10:41:30 -06:00
|
|
|
printf("Unable to open directory: %s\n", directory.c_str());
|
2012-07-27 14:06:17 -05:00
|
|
|
return std::vector<std::string>();
|
|
|
|
}
|
|
|
|
do
|
|
|
|
{
|
|
|
|
std::string currentFileName = std::string(currentFile.name);
|
|
|
|
if(currentFileName.length()>4)
|
|
|
|
directoryList.push_back(directory+currentFileName);
|
|
|
|
}
|
|
|
|
while (_findnext(findFileHandle, ¤tFile) == 0);
|
|
|
|
_findclose(findFileHandle);
|
|
|
|
#else
|
|
|
|
//Linux or MinGW
|
|
|
|
struct dirent * directoryEntry;
|
|
|
|
DIR *directoryHandle = opendir(directory.c_str());
|
|
|
|
if(!directoryHandle)
|
|
|
|
{
|
2012-12-16 10:41:30 -06:00
|
|
|
printf("Unable to open directory: %s\n", directory.c_str());
|
2012-07-27 14:06:17 -05:00
|
|
|
return std::vector<std::string>();
|
|
|
|
}
|
|
|
|
while(directoryEntry = readdir(directoryHandle))
|
|
|
|
{
|
|
|
|
std::string currentFileName = std::string(directoryEntry->d_name);
|
|
|
|
if(currentFileName.length()>4)
|
|
|
|
directoryList.push_back(directory+currentFileName);
|
|
|
|
}
|
|
|
|
closedir(directoryHandle);
|
|
|
|
#endif
|
|
|
|
|
2012-07-28 16:14:38 -05:00
|
|
|
std::vector<std::string> searchResults;
|
|
|
|
for(std::vector<std::string>::iterator iter = directoryList.begin(), end = directoryList.end(); iter != end; ++iter)
|
|
|
|
{
|
2013-03-08 21:31:08 -06:00
|
|
|
std::string filename = *iter, tempfilename = *iter;
|
2012-07-28 16:14:38 -05:00
|
|
|
bool extensionMatch = !extensions.size();
|
|
|
|
for(std::vector<std::string>::iterator extIter = extensions.begin(), extEnd = extensions.end(); extIter != extEnd; ++extIter)
|
|
|
|
{
|
2013-03-08 21:31:08 -06:00
|
|
|
int filenameLength = filename.length()-(*extIter).length();
|
|
|
|
if(filename.find(*extIter, filenameLength) == filenameLength)
|
2012-07-28 16:14:38 -05:00
|
|
|
{
|
|
|
|
extensionMatch = true;
|
2013-03-08 21:31:08 -06:00
|
|
|
tempfilename = filename.substr(0, filenameLength);
|
2012-07-28 16:14:38 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-03-08 21:31:08 -06:00
|
|
|
for (std::string::iterator iter = tempfilename.begin(); iter != tempfilename.end(); ++iter)
|
|
|
|
*iter = toupper(*iter);
|
2012-07-28 16:14:38 -05:00
|
|
|
bool searchMatch = !search.size();
|
2013-03-08 21:31:08 -06:00
|
|
|
if(search.size() && tempfilename.find(search)!=std::string::npos)
|
2012-07-28 16:14:38 -05:00
|
|
|
searchMatch = true;
|
|
|
|
|
|
|
|
if(searchMatch && extensionMatch)
|
|
|
|
searchResults.push_back(filename);
|
|
|
|
}
|
|
|
|
|
2012-07-27 14:06:17 -05:00
|
|
|
//Filter results
|
2012-07-28 16:14:38 -05:00
|
|
|
return searchResults;
|
2012-07-27 14:06:17 -05:00
|
|
|
}
|
|
|
|
|
2012-10-19 18:17:15 -05:00
|
|
|
int Client::MakeDirectory(const char * dirName)
|
|
|
|
{
|
|
|
|
#ifdef WIN
|
|
|
|
return _mkdir(dirName);
|
|
|
|
#else
|
|
|
|
return mkdir(dirName, 0755);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-08-01 16:29:22 -05:00
|
|
|
void Client::WriteFile(std::vector<unsigned char> fileData, std::string filename)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::ofstream fileStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
2012-08-01 16:29:22 -05:00
|
|
|
if(fileStream.is_open())
|
|
|
|
{
|
|
|
|
fileStream.write((char*)&fileData[0], fileData.size());
|
|
|
|
fileStream.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (std::exception & e)
|
|
|
|
{
|
|
|
|
std::cerr << "WriteFile:" << e.what() << std::endl;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Client::FileExists(std::string filename)
|
|
|
|
{
|
|
|
|
bool exists = false;
|
|
|
|
try
|
|
|
|
{
|
2012-08-08 14:05:47 -05:00
|
|
|
std::ifstream fileStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
2012-08-01 16:29:22 -05:00
|
|
|
if(fileStream.is_open())
|
|
|
|
{
|
|
|
|
exists = true;
|
|
|
|
fileStream.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (std::exception & e)
|
|
|
|
{
|
|
|
|
exists = false;
|
|
|
|
}
|
|
|
|
return exists;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::WriteFile(std::vector<char> fileData, std::string filename)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::ofstream fileStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
2012-08-01 16:29:22 -05:00
|
|
|
if(fileStream.is_open())
|
|
|
|
{
|
|
|
|
fileStream.write(&fileData[0], fileData.size());
|
|
|
|
fileStream.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (std::exception & e)
|
|
|
|
{
|
|
|
|
std::cerr << "WriteFile:" << e.what() << std::endl;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-27 14:06:17 -05:00
|
|
|
std::vector<unsigned char> Client::ReadFile(std::string filename)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::ifstream fileStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
2012-07-27 14:06:17 -05:00
|
|
|
if(fileStream.is_open())
|
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
fileStream.seekg(0, std::ios::end);
|
2012-07-27 14:06:17 -05:00
|
|
|
size_t fileSize = fileStream.tellg();
|
|
|
|
fileStream.seekg(0);
|
|
|
|
|
|
|
|
unsigned char * tempData = new unsigned char[fileSize];
|
|
|
|
fileStream.read((char *)tempData, fileSize);
|
|
|
|
fileStream.close();
|
|
|
|
|
|
|
|
std::vector<unsigned char> fileData;
|
|
|
|
fileData.insert(fileData.end(), tempData, tempData+fileSize);
|
|
|
|
delete[] tempData;
|
|
|
|
|
|
|
|
return fileData;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return std::vector<unsigned char>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(std::exception & e)
|
|
|
|
{
|
|
|
|
std::cerr << "Readfile: " << e.what() << std::endl;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-12 09:15:47 -05:00
|
|
|
void Client::SetMessageOfTheDay(std::string message)
|
|
|
|
{
|
|
|
|
messageOfTheDay = message;
|
|
|
|
notifyMessageOfTheDay();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Client::GetMessageOfTheDay()
|
|
|
|
{
|
|
|
|
return messageOfTheDay;
|
|
|
|
}
|
|
|
|
|
2012-12-09 06:05:27 -06:00
|
|
|
void Client::AddServerNotification(std::pair<std::string, std::string> notification)
|
|
|
|
{
|
|
|
|
serverNotifications.push_back(notification);
|
|
|
|
notifyNewNotification(notification);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::pair<std::string, std::string> > Client::GetServerNotifications()
|
|
|
|
{
|
|
|
|
return serverNotifications;
|
|
|
|
}
|
|
|
|
|
2012-06-20 07:40:18 -05:00
|
|
|
void Client::Tick()
|
|
|
|
{
|
2012-07-31 13:49:08 -05:00
|
|
|
//Check thumbnail queue
|
2013-03-10 13:08:34 -05:00
|
|
|
RequestBroker::Ref().FlushThumbQueue();
|
2012-07-31 13:49:08 -05:00
|
|
|
|
2012-06-20 07:40:18 -05:00
|
|
|
//Check status on version check request
|
|
|
|
if(versionCheckRequest && http_async_req_status(versionCheckRequest))
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
int dataLength;
|
|
|
|
char * data = http_async_req_stop(versionCheckRequest, &status, &dataLength);
|
|
|
|
versionCheckRequest = NULL;
|
|
|
|
|
|
|
|
if(status != 200)
|
|
|
|
{
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
2012-08-12 09:15:47 -05:00
|
|
|
//Check session
|
|
|
|
json::Boolean sessionStatus = objDocument["Session"];
|
|
|
|
if(!sessionStatus.Value())
|
|
|
|
{
|
2012-12-08 19:25:05 -06:00
|
|
|
SetAuthUser(User(0, ""));
|
2012-08-12 09:15:47 -05:00
|
|
|
}
|
|
|
|
|
2012-12-09 06:05:27 -06:00
|
|
|
//Notifications from server
|
|
|
|
json::Array notificationsArray = objDocument["Notifications"];
|
|
|
|
for(int j = 0; j < notificationsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::String notificationLink = notificationsArray[j]["Link"];
|
|
|
|
json::String notificationText = notificationsArray[j]["Text"];
|
|
|
|
|
|
|
|
std::pair<std::string, std::string> item = std::pair<std::string, std::string>(notificationText.Value(), notificationLink.Value());
|
|
|
|
AddServerNotification(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-12 09:15:47 -05:00
|
|
|
//MOTD
|
|
|
|
json::String messageOfTheDay = objDocument["MessageOfTheDay"];
|
|
|
|
this->messageOfTheDay = messageOfTheDay.Value();
|
|
|
|
notifyMessageOfTheDay();
|
|
|
|
|
2013-02-14 22:31:31 -06:00
|
|
|
#ifndef IGNORE_UPDATES
|
2012-08-12 09:15:47 -05:00
|
|
|
//Check for updates
|
|
|
|
json::Object versions = objDocument["Updates"];
|
|
|
|
|
|
|
|
json::Object stableVersion = versions["Stable"];
|
|
|
|
json::Object betaVersion = versions["Beta"];
|
|
|
|
json::Object snapshotVersion = versions["Snapshot"];
|
2012-06-20 07:40:18 -05:00
|
|
|
|
|
|
|
json::Number stableMajor = stableVersion["Major"];
|
|
|
|
json::Number stableMinor = stableVersion["Minor"];
|
|
|
|
json::Number stableBuild = stableVersion["Build"];
|
2012-06-22 13:04:38 -05:00
|
|
|
json::String stableFile = stableVersion["File"];
|
2012-06-20 07:40:18 -05:00
|
|
|
|
|
|
|
json::Number betaMajor = betaVersion["Major"];
|
|
|
|
json::Number betaMinor = betaVersion["Minor"];
|
|
|
|
json::Number betaBuild = betaVersion["Build"];
|
2012-06-22 13:04:38 -05:00
|
|
|
json::String betaFile = betaVersion["File"];
|
|
|
|
|
2012-07-22 12:51:05 -05:00
|
|
|
json::Number snapshotSnapshot = snapshotVersion["Snapshot"];
|
2012-06-22 13:04:38 -05:00
|
|
|
json::String snapshotFile = snapshotVersion["File"];
|
|
|
|
|
|
|
|
if(stableMajor.Value()>SAVE_VERSION || (stableMinor.Value()>MINOR_VERSION && stableMajor.Value()==SAVE_VERSION) || stableBuild.Value()>BUILD_NUM)
|
|
|
|
{
|
|
|
|
updateAvailable = true;
|
|
|
|
updateInfo = UpdateInfo(stableMajor.Value(), stableMinor.Value(), stableBuild.Value(), stableFile.Value(), UpdateInfo::Stable);
|
|
|
|
}
|
2012-06-20 07:40:18 -05:00
|
|
|
|
|
|
|
#ifdef BETA
|
2012-06-22 13:04:38 -05:00
|
|
|
if(betaMajor.Value()>SAVE_VERSION || (betaMinor.Value()>MINOR_VERSION && betaMajor.Value()==SAVE_VERSION) || betaBuild.Value()>BUILD_NUM)
|
2012-06-20 07:40:18 -05:00
|
|
|
{
|
|
|
|
updateAvailable = true;
|
2012-06-22 13:04:38 -05:00
|
|
|
updateInfo = UpdateInfo(betaMajor.Value(), betaMinor.Value(), betaBuild.Value(), betaFile.Value(), UpdateInfo::Beta);
|
2012-06-20 07:40:18 -05:00
|
|
|
}
|
2012-06-22 13:04:38 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef SNAPSHOT
|
2012-07-22 12:51:05 -05:00
|
|
|
if(snapshotSnapshot.Value() > SNAPSHOT_ID)
|
2012-06-20 07:40:18 -05:00
|
|
|
{
|
|
|
|
updateAvailable = true;
|
2012-07-22 12:51:05 -05:00
|
|
|
updateInfo = UpdateInfo(snapshotSnapshot.Value(), snapshotFile.Value(), UpdateInfo::Snapshot);
|
2012-06-20 07:40:18 -05:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(updateAvailable)
|
|
|
|
{
|
|
|
|
notifyUpdateAvailable();
|
|
|
|
}
|
2012-11-18 11:43:11 -06:00
|
|
|
#endif
|
2012-06-20 07:40:18 -05:00
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
//Do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-22 13:04:38 -05:00
|
|
|
UpdateInfo Client::GetUpdateInfo()
|
|
|
|
{
|
|
|
|
return updateInfo;
|
|
|
|
}
|
|
|
|
|
2012-06-20 07:40:18 -05:00
|
|
|
void Client::notifyUpdateAvailable()
|
|
|
|
{
|
|
|
|
for (std::vector<ClientListener*>::iterator iterator = listeners.begin(), end = listeners.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
(*iterator)->NotifyUpdateAvailable(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-12 09:15:47 -05:00
|
|
|
void Client::notifyMessageOfTheDay()
|
|
|
|
{
|
|
|
|
for (std::vector<ClientListener*>::iterator iterator = listeners.begin(), end = listeners.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
(*iterator)->NotifyMessageOfTheDay(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-17 13:14:05 -05:00
|
|
|
void Client::notifyAuthUserChanged()
|
|
|
|
{
|
|
|
|
for (std::vector<ClientListener*>::iterator iterator = listeners.begin(), end = listeners.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
(*iterator)->NotifyAuthUserChanged(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-09 06:05:27 -06:00
|
|
|
void Client::notifyNewNotification(std::pair<std::string, std::string> notification)
|
|
|
|
{
|
|
|
|
for (std::vector<ClientListener*>::iterator iterator = listeners.begin(), end = listeners.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
(*iterator)->NotifyNewNotification(this, notification);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-20 07:40:18 -05:00
|
|
|
void Client::AddListener(ClientListener * listener)
|
|
|
|
{
|
|
|
|
listeners.push_back(listener);
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
|
2012-07-17 13:14:05 -05:00
|
|
|
void Client::RemoveListener(ClientListener * listener)
|
|
|
|
{
|
|
|
|
for (std::vector<ClientListener*>::iterator iterator = listeners.begin(), end = listeners.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
if((*iterator) == listener)
|
|
|
|
{
|
|
|
|
listeners.erase(iterator);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-18 06:44:07 -05:00
|
|
|
void Client::WritePrefs()
|
2012-01-19 07:44:59 -06:00
|
|
|
{
|
2012-01-31 12:49:14 -06:00
|
|
|
std::ofstream configFile;
|
2012-08-12 16:32:57 -05:00
|
|
|
configFile.open("powder.pref", std::ios::trunc);
|
2012-01-31 12:49:14 -06:00
|
|
|
if(configFile)
|
|
|
|
{
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
configDocument["User"]["ID"] = json::Number(authUser.ID);
|
|
|
|
configDocument["User"]["SessionID"] = json::String(authUser.SessionID);
|
|
|
|
configDocument["User"]["SessionKey"] = json::String(authUser.SessionKey);
|
|
|
|
configDocument["User"]["Username"] = json::String(authUser.Username);
|
2012-08-12 16:32:57 -05:00
|
|
|
if(authUser.UserElevation == User::ElevationAdmin)
|
2012-04-14 13:00:24 -05:00
|
|
|
configDocument["User"]["Elevation"] = json::String("Admin");
|
2012-08-12 16:32:57 -05:00
|
|
|
else if(authUser.UserElevation == User::ElevationModerator)
|
2012-04-14 13:00:24 -05:00
|
|
|
configDocument["User"]["Elevation"] = json::String("Mod");
|
|
|
|
else
|
|
|
|
configDocument["User"]["Elevation"] = json::String("None");
|
2012-01-31 12:49:14 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
configDocument["User"] = json::Null();
|
|
|
|
}
|
|
|
|
json::Writer::Write(configDocument, configFile);
|
|
|
|
configFile.close();
|
|
|
|
}
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
|
2012-08-18 06:44:07 -05:00
|
|
|
void Client::Shutdown()
|
|
|
|
{
|
2013-03-10 13:08:34 -05:00
|
|
|
RequestBroker::Ref().Shutdown();
|
2012-08-18 06:44:07 -05:00
|
|
|
ClearThumbnailRequests();
|
|
|
|
http_done();
|
|
|
|
|
|
|
|
//Save config
|
|
|
|
WritePrefs();
|
|
|
|
}
|
|
|
|
|
2012-06-21 19:04:55 -05:00
|
|
|
Client::~Client()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-01-31 12:49:14 -06:00
|
|
|
|
2012-01-28 13:56:13 -06:00
|
|
|
void Client::SetAuthUser(User user)
|
|
|
|
{
|
|
|
|
authUser = user;
|
2012-07-17 13:14:05 -05:00
|
|
|
notifyAuthUserChanged();
|
2012-01-28 13:56:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
User Client::GetAuthUser()
|
|
|
|
{
|
|
|
|
return authUser;
|
|
|
|
}
|
|
|
|
|
2012-08-01 16:29:22 -05:00
|
|
|
RequestStatus Client::UploadSave(SaveInfo & save)
|
2012-01-29 18:40:28 -06:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-06-07 08:23:26 -05:00
|
|
|
int gameDataLength;
|
|
|
|
char * gameData = NULL;
|
2012-01-29 18:40:28 -06:00
|
|
|
int dataStatus;
|
|
|
|
char * data;
|
|
|
|
int dataLength = 0;
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
2012-08-01 16:29:22 -05:00
|
|
|
if(!save.GetGameSave())
|
2012-06-07 08:23:26 -05:00
|
|
|
{
|
|
|
|
lastError = "Empty game save";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
2012-08-01 16:29:22 -05:00
|
|
|
save.SetID(0);
|
2012-06-07 08:23:26 -05:00
|
|
|
|
2012-08-01 16:29:22 -05:00
|
|
|
gameData = save.GetGameSave()->Serialise(gameDataLength);
|
2012-06-07 08:23:26 -05:00
|
|
|
|
|
|
|
if(!gameData)
|
|
|
|
{
|
|
|
|
lastError = "Cannot upload game save";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-09-30 14:10:11 -05:00
|
|
|
char *saveName = new char[save.GetName().length() + 1];
|
2013-03-10 21:08:00 -05:00
|
|
|
std::strcpy (saveName, save.GetName().c_str());
|
2012-09-30 14:10:11 -05:00
|
|
|
char *saveDescription = new char[save.GetDescription().length() + 1];
|
2013-03-10 21:08:00 -05:00
|
|
|
std::strcpy (saveDescription, save.GetDescription().c_str());
|
|
|
|
char *userid = new char[userIDStream.str().length() + 1];
|
|
|
|
std::strcpy (userid, userIDStream.str().c_str());
|
|
|
|
char *session = new char[authUser.SessionID.length() + 1];
|
|
|
|
std::strcpy (session, authUser.SessionID.c_str());
|
2012-09-30 14:10:11 -05:00
|
|
|
|
2012-01-29 18:40:28 -06:00
|
|
|
char * postNames[] = { "Name", "Description", "Data:save.bin", "Publish", NULL };
|
2012-09-30 14:10:11 -05:00
|
|
|
char * postDatas[] = { saveName, saveDescription, gameData, (char *)(save.GetPublished()?"Public":"Private") };
|
2012-08-01 16:29:22 -05:00
|
|
|
int postLengths[] = { save.GetName().length(), save.GetDescription().length(), gameDataLength, save.GetPublished()?6:7 };
|
2012-01-29 18:40:28 -06:00
|
|
|
//std::cout << postNames[0] << " " << postDatas[0] << " " << postLengths[0] << std::endl;
|
2013-03-10 21:08:00 -05:00
|
|
|
data = http_multipart_post("http://" SERVER "/Save.api", postNames, postDatas, postLengths, userid, NULL, session, &dataStatus, &dataLength);
|
2012-09-30 14:10:11 -05:00
|
|
|
|
|
|
|
delete[] saveDescription;
|
|
|
|
delete[] saveName;
|
2013-03-10 21:08:00 -05:00
|
|
|
delete[] userid;
|
|
|
|
delete[] session;
|
2012-01-29 18:40:28 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(data && dataStatus == 200)
|
|
|
|
{
|
|
|
|
if(strncmp((const char *)data, "OK", 2)!=0)
|
|
|
|
{
|
2013-02-24 13:12:48 -06:00
|
|
|
if(gameData) delete[] gameData;
|
2012-01-29 18:40:28 -06:00
|
|
|
lastError = std::string((const char *)data);
|
2012-09-30 14:10:11 -05:00
|
|
|
free(data);
|
2012-01-29 18:40:28 -06:00
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int tempID;
|
|
|
|
std::stringstream saveIDStream((char *)(data+3));
|
|
|
|
saveIDStream >> tempID;
|
|
|
|
if(!tempID)
|
|
|
|
{
|
|
|
|
lastError = "Server did not return Save ID";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-08-01 16:29:22 -05:00
|
|
|
save.SetID(tempID);
|
2012-01-29 18:40:28 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
free(data);
|
2013-02-24 13:12:48 -06:00
|
|
|
if(gameData) delete[] gameData;
|
2012-01-29 18:40:28 -06:00
|
|
|
return RequestOkay;
|
|
|
|
}
|
|
|
|
else if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
2013-02-24 13:12:48 -06:00
|
|
|
if(gameData) delete[] gameData;
|
2012-01-29 18:40:28 -06:00
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-12-18 11:20:52 -06:00
|
|
|
void Client::MoveStampToFront(std::string stampID)
|
|
|
|
{
|
|
|
|
for (std::list<std::string>::iterator iterator = stampIDs.begin(), end = stampIDs.end(); iterator != end; ++iterator)
|
|
|
|
{
|
|
|
|
if((*iterator) == stampID)
|
|
|
|
{
|
|
|
|
stampIDs.erase(iterator);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stampIDs.push_front(stampID);
|
|
|
|
updateStamps();
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
SaveFile * Client::GetStamp(std::string stampID)
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
2012-08-21 07:30:30 -05:00
|
|
|
std::string stampFile = std::string(STAMPS_DIR PATH_SEP + stampID + ".stm");
|
|
|
|
if(FileExists(stampFile))
|
|
|
|
{
|
|
|
|
SaveFile * file = new SaveFile(stampID);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
GameSave * tempSave = new GameSave(ReadFile(stampFile));
|
|
|
|
file->SetGameSave(tempSave);
|
|
|
|
}
|
|
|
|
catch (ParseException & e)
|
|
|
|
{
|
|
|
|
std::cerr << "Client: Invalid stamp file, " << stampID << " " << std::string(e.what()) << std::endl;
|
|
|
|
}
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-04-02 11:01:28 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::DeleteStamp(std::string stampID)
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
for (std::list<std::string>::iterator iterator = stampIDs.begin(), end = stampIDs.end(); iterator != end; ++iterator)
|
2012-04-19 09:22:18 -05:00
|
|
|
{
|
2012-06-10 13:52:24 -05:00
|
|
|
if((*iterator) == stampID)
|
2012-04-19 09:22:18 -05:00
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
std::stringstream stampFilename;
|
2012-07-21 07:09:59 -05:00
|
|
|
stampFilename << STAMPS_DIR;
|
|
|
|
stampFilename << PATH_SEP;
|
|
|
|
stampFilename << stampID;
|
|
|
|
stampFilename << ".stm";
|
|
|
|
remove(stampFilename.str().c_str());
|
2012-06-10 13:52:24 -05:00
|
|
|
stampIDs.erase(iterator);
|
2012-04-19 09:22:18 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2012-10-05 09:46:42 -05:00
|
|
|
|
|
|
|
updateStamps();
|
2012-04-02 11:01:28 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::string Client::AddStamp(GameSave * saveData)
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
|
|
|
unsigned t=(unsigned)time(NULL);
|
|
|
|
if (lastStampTime!=t)
|
|
|
|
{
|
|
|
|
lastStampTime=t;
|
|
|
|
lastStampName=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lastStampName++;
|
|
|
|
std::stringstream saveID;
|
|
|
|
//sprintf(saveID, "%08x%02x", lastStampTime, lastStampName);
|
|
|
|
saveID
|
|
|
|
<< std::setw(8) << std::setfill('0') << std::hex << lastStampTime
|
|
|
|
<< std::setw(2) << std::setfill('0') << std::hex << lastStampName;
|
|
|
|
|
2012-10-19 18:17:15 -05:00
|
|
|
MakeDirectory(STAMPS_DIR);
|
2012-04-02 11:01:28 -05:00
|
|
|
|
2012-06-07 08:23:26 -05:00
|
|
|
int gameDataLength;
|
|
|
|
char * gameData = saveData->Serialise(gameDataLength);
|
|
|
|
|
2012-04-02 11:01:28 -05:00
|
|
|
std::ofstream stampStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
stampStream.open(std::string(STAMPS_DIR PATH_SEP + saveID.str()+".stm").c_str(), std::ios::binary);
|
2012-06-07 08:23:26 -05:00
|
|
|
stampStream.write((const char *)gameData, gameDataLength);
|
2012-04-02 11:01:28 -05:00
|
|
|
stampStream.close();
|
|
|
|
|
2013-03-10 22:21:28 -05:00
|
|
|
delete gameData;
|
2012-08-21 07:30:30 -05:00
|
|
|
|
2012-06-10 13:52:24 -05:00
|
|
|
stampIDs.push_front(saveID.str());
|
2012-04-02 11:01:28 -05:00
|
|
|
|
|
|
|
updateStamps();
|
|
|
|
|
|
|
|
return saveID.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::updateStamps()
|
|
|
|
{
|
2012-10-19 18:17:15 -05:00
|
|
|
MakeDirectory(STAMPS_DIR);
|
2012-04-02 11:01:28 -05:00
|
|
|
|
|
|
|
std::ofstream stampsStream;
|
2012-08-12 16:32:57 -05:00
|
|
|
stampsStream.open(std::string(STAMPS_DIR PATH_SEP "stamps.def").c_str(), std::ios::binary);
|
|
|
|
for (std::list<std::string>::const_iterator iterator = stampIDs.begin(), end = stampIDs.end(); iterator != end; ++iterator)
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
2012-06-10 13:52:24 -05:00
|
|
|
stampsStream.write((*iterator).c_str(), 10);
|
2012-04-02 11:01:28 -05:00
|
|
|
}
|
|
|
|
stampsStream.write("\0", 1);
|
|
|
|
stampsStream.close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-05 09:46:42 -05:00
|
|
|
void Client::RescanStamps()
|
2012-10-01 21:00:57 -05:00
|
|
|
{
|
|
|
|
DIR * directory;
|
|
|
|
struct dirent * entry;
|
|
|
|
directory = opendir("stamps");
|
|
|
|
if (directory != NULL)
|
|
|
|
{
|
|
|
|
stampIDs.clear();
|
|
|
|
while (entry = readdir(directory))
|
|
|
|
{
|
2012-10-05 09:46:42 -05:00
|
|
|
if(strncmp(entry->d_name, "..", 3) && strncmp(entry->d_name, ".", 2) && strstr(entry->d_name, ".stm") && strlen(entry->d_name) == 14)
|
2012-10-01 21:00:57 -05:00
|
|
|
{
|
|
|
|
char stampname[11];
|
|
|
|
strncpy(stampname, entry->d_name, 10);
|
|
|
|
stampIDs.push_front(stampname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(directory);
|
|
|
|
updateStamps();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 13:52:24 -05:00
|
|
|
int Client::GetStampsCount()
|
2012-04-02 11:01:28 -05:00
|
|
|
{
|
2012-06-10 13:52:24 -05:00
|
|
|
return stampIDs.size();
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> Client::GetStamps(int start, int count)
|
2012-06-10 13:52:24 -05:00
|
|
|
{
|
2012-06-10 13:53:46 -05:00
|
|
|
if(start+count > stampIDs.size()) {
|
|
|
|
if(start > stampIDs.size())
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<std::string>();
|
2012-06-10 13:53:46 -05:00
|
|
|
count = stampIDs.size()-start;
|
|
|
|
}
|
2012-06-10 13:52:24 -05:00
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> stampRange;
|
2012-06-10 13:52:24 -05:00
|
|
|
int index = 0;
|
2012-08-12 16:32:57 -05:00
|
|
|
for (std::list<std::string>::const_iterator iterator = stampIDs.begin(), end = stampIDs.end(); iterator != end; ++iterator, ++index) {
|
2012-06-10 13:52:24 -05:00
|
|
|
if(index>=start && index < start+count)
|
|
|
|
stampRange.push_back(*iterator);
|
|
|
|
}
|
|
|
|
return stampRange;
|
2012-04-02 11:01:28 -05:00
|
|
|
}
|
|
|
|
|
2012-01-28 13:56:13 -06:00
|
|
|
RequestStatus Client::ExecVote(int saveID, int direction)
|
|
|
|
{
|
|
|
|
lastError = "";
|
|
|
|
int dataStatus;
|
|
|
|
char * data;
|
|
|
|
int dataLength = 0;
|
|
|
|
std::stringstream idStream;
|
|
|
|
idStream << saveID;
|
2012-08-14 07:06:10 -05:00
|
|
|
|
2012-01-28 13:56:13 -06:00
|
|
|
if(authUser.ID)
|
|
|
|
{
|
2013-03-10 22:21:28 -05:00
|
|
|
char * directionText = (char*)(direction==1?"Up":"Down");
|
2013-03-10 21:08:00 -05:00
|
|
|
std::string saveIDText = format::NumberToString<int>(saveID);
|
|
|
|
std::string userIDText = format::NumberToString<int>(authUser.ID);
|
|
|
|
|
|
|
|
char *id = new char[saveIDText.length() + 1];
|
|
|
|
std::strcpy (id, saveIDText.c_str());
|
|
|
|
char *userid = new char[userIDText.length() + 1];
|
|
|
|
std::strcpy (userid, userIDText.c_str());
|
|
|
|
char *session = new char[authUser.SessionID.length() + 1];
|
|
|
|
std::strcpy (session, authUser.SessionID.c_str());
|
|
|
|
|
2012-01-28 13:56:13 -06:00
|
|
|
char * postNames[] = { "ID", "Action", NULL };
|
2013-03-10 21:08:00 -05:00
|
|
|
char * postDatas[] = { id, directionText };
|
|
|
|
int postLengths[] = { saveIDText.length(), strlen(directionText) };
|
2012-01-28 13:56:13 -06:00
|
|
|
//std::cout << postNames[0] << " " << postDatas[0] << " " << postLengths[0] << std::endl;
|
2013-03-10 21:08:00 -05:00
|
|
|
data = http_multipart_post("http://" SERVER "/Vote.api", postNames, postDatas, postLengths, userid, NULL, session, &dataStatus, &dataLength);
|
|
|
|
|
|
|
|
delete[] id;
|
|
|
|
delete[] userid;
|
|
|
|
delete[] session;
|
2012-01-28 13:56:13 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(data && dataStatus == 200)
|
|
|
|
{
|
|
|
|
if(strncmp((const char *)data, "OK", 2)!=0)
|
|
|
|
{
|
|
|
|
lastError = std::string((const char *)data);
|
2012-09-30 14:10:11 -05:00
|
|
|
free(data);
|
2012-01-28 13:56:13 -06:00
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
}
|
|
|
|
else if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-01-25 19:13:33 -06:00
|
|
|
unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength)
|
|
|
|
{
|
2012-01-26 10:18:43 -06:00
|
|
|
lastError = "";
|
|
|
|
int dataStatus;
|
|
|
|
unsigned char * data;
|
2012-01-25 19:13:33 -06:00
|
|
|
dataLength = 0;
|
2012-01-26 10:18:43 -06:00
|
|
|
std::stringstream urlStream;
|
|
|
|
if(saveDate)
|
|
|
|
{
|
|
|
|
urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps";
|
|
|
|
}
|
2012-05-15 12:13:17 -05:00
|
|
|
|
2013-03-10 21:08:00 -05:00
|
|
|
char *url = new char[urlStream.str().length() + 1];
|
|
|
|
std::strcpy (url, urlStream.str().c_str());
|
|
|
|
data = (unsigned char *)http_simple_get(url, &dataStatus, &dataLength);
|
|
|
|
delete[] url;
|
|
|
|
|
2012-01-26 10:18:43 -06:00
|
|
|
if(data && dataStatus == 200)
|
|
|
|
{
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
else if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
2012-01-25 19:13:33 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-08-08 15:32:10 -05:00
|
|
|
std::vector<unsigned char> Client::GetSaveData(int saveID, int saveDate)
|
|
|
|
{
|
|
|
|
int dataSize;
|
|
|
|
unsigned char * data = GetSaveData(saveID, saveDate, dataSize);
|
|
|
|
|
|
|
|
std::vector<unsigned char> saveData(data, data+dataSize);
|
|
|
|
|
|
|
|
delete[] data;
|
|
|
|
return saveData;
|
|
|
|
}
|
|
|
|
|
2013-03-16 12:45:18 -05:00
|
|
|
RequestBroker::Request * Client::GetUserInfoAsync(std::string username)
|
2013-03-10 13:08:34 -05:00
|
|
|
{
|
2013-03-16 12:45:18 -05:00
|
|
|
class UserInfoParser: public APIResultParser
|
2013-03-10 13:08:34 -05:00
|
|
|
{
|
2013-03-16 12:45:18 -05:00
|
|
|
virtual void * ProcessResponse(unsigned char * data, int dataLength)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream((char*)data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
json::Object tempUser = objDocument["User"];
|
|
|
|
|
|
|
|
json::Number userIDTemp = tempUser["ID"];
|
|
|
|
json::String usernameTemp = tempUser["Username"];
|
|
|
|
json::String bioTemp = tempUser["Biography"];
|
|
|
|
//json::Number ageTemp = tempUser["Age"];
|
|
|
|
|
|
|
|
return new UserInfo(
|
|
|
|
userIDTemp.Value(),
|
|
|
|
0,//ageTemp.Value(),
|
|
|
|
usernameTemp.Value(),
|
|
|
|
bioTemp.Value());
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virtual void Cleanup(void * objectPtr)
|
|
|
|
{
|
|
|
|
delete (UserInfo*)objectPtr;
|
|
|
|
}
|
|
|
|
virtual ~UserInfoParser() { }
|
|
|
|
};
|
|
|
|
return new APIRequest("http://" SERVER "/User.json?Name=" + username, new UserInfoParser());
|
2013-03-10 13:08:34 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
LoginStatus Client::Login(std::string username, std::string password, User & user)
|
2012-01-24 14:19:19 -06:00
|
|
|
{
|
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;
|
2012-01-25 11:21:55 -06:00
|
|
|
char passwordHash[33];
|
|
|
|
char totalHash[33];
|
2012-01-24 18:57:39 -06:00
|
|
|
|
2012-01-25 11:21:55 -06:00
|
|
|
user.ID = 0;
|
|
|
|
user.Username = "";
|
|
|
|
user.SessionID = "";
|
|
|
|
user.SessionKey = "";
|
|
|
|
|
|
|
|
//Doop
|
|
|
|
md5_ascii(passwordHash, (const unsigned char *)password.c_str(), password.length());
|
|
|
|
passwordHash[32] = 0;
|
|
|
|
hashStream << username << "-" << passwordHash;
|
|
|
|
md5_ascii(totalHash, (const unsigned char *)(hashStream.str().c_str()), hashStream.str().length());
|
|
|
|
totalHash[32] = 0;
|
2012-01-24 18:57:39 -06:00
|
|
|
|
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 };
|
2012-01-25 11:21:55 -06:00
|
|
|
char * postDatas[] = { (char*)username.c_str(), totalHash };
|
|
|
|
int postLengths[] = { username.length(), 32 };
|
2012-01-24 18:57:39 -06:00
|
|
|
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
|
|
|
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)
|
|
|
|
{
|
2012-01-25 11:21:55 -06:00
|
|
|
json::Number userIDTemp = objDocument["UserID"];
|
|
|
|
json::String sessionIDTemp = objDocument["SessionID"];
|
|
|
|
json::String sessionKeyTemp = objDocument["SessionKey"];
|
2012-04-14 13:00:24 -05:00
|
|
|
json::String userElevationTemp = objDocument["Elevation"];
|
2012-12-09 06:05:27 -06:00
|
|
|
|
|
|
|
json::Array notificationsArray = objDocument["Notifications"];
|
|
|
|
for(int j = 0; j < notificationsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::String notificationLink = notificationsArray[j]["Link"];
|
|
|
|
json::String notificationText = notificationsArray[j]["Text"];
|
|
|
|
|
|
|
|
std::pair<std::string, std::string> item = std::pair<std::string, std::string>(notificationText.Value(), notificationLink.Value());
|
|
|
|
AddServerNotification(item);
|
|
|
|
}
|
|
|
|
|
2012-01-25 11:21:55 -06:00
|
|
|
user.Username = username;
|
|
|
|
user.ID = userIDTemp.Value();
|
|
|
|
user.SessionID = sessionIDTemp.Value();
|
|
|
|
user.SessionKey = sessionKeyTemp.Value();
|
2012-04-14 13:00:24 -05:00
|
|
|
std::string userElevation = userElevationTemp.Value();
|
|
|
|
if(userElevation == "Admin")
|
2012-08-12 16:32:57 -05:00
|
|
|
user.UserElevation = User::ElevationAdmin;
|
2012-04-14 13:00:24 -05:00
|
|
|
else if(userElevation == "Mod")
|
2012-08-12 16:32:57 -05:00
|
|
|
user.UserElevation = User::ElevationModerator;
|
2012-04-14 13:00:24 -05:00
|
|
|
else
|
2012-08-12 16:32:57 -05:00
|
|
|
user.UserElevation= User::ElevationNone;
|
2012-01-24 18:57:39 -06:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2012-01-25 11:21:55 -06:00
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
2012-01-24 14:19:19 -06:00
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
return LoginError;
|
|
|
|
}
|
|
|
|
|
2012-04-06 18:45:24 -05:00
|
|
|
RequestStatus Client::DeleteSave(int saveID)
|
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-04-06 18:45:24 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
2012-04-14 13:00:24 -05:00
|
|
|
urlStream << "http://" << SERVER << "/Browse/Delete.json?ID=" << saveID << "&Mode=Delete&Key=" << authUser.SessionKey;
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
int status = ((json::Number)objDocument["Status"]).Value();
|
|
|
|
|
|
|
|
if(status!=1)
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
failure:
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-07-18 07:07:33 -05:00
|
|
|
RequestStatus Client::AddComment(int saveID, std::string comment)
|
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-07-18 07:07:33 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Key=" << authUser.SessionKey;
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
|
|
|
|
char * postNames[] = { "Comment", NULL };
|
|
|
|
char * postDatas[] = { (char*)(comment.c_str()) };
|
|
|
|
int postLengths[] = { comment.length() };
|
|
|
|
data = http_multipart_post((char *)urlStream.str().c_str(), postNames, postDatas, postLengths, (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
int status = ((json::Number)objDocument["Status"]).Value();
|
|
|
|
|
|
|
|
if(status!=1)
|
|
|
|
{
|
2012-12-15 22:12:54 -06:00
|
|
|
lastError = ((json::String)objDocument["Error"]).Value();
|
2012-07-18 07:07:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if(status!=1)
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
failure:
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-04-14 13:00:24 -05:00
|
|
|
RequestStatus Client::FavouriteSave(int saveID, bool favourite)
|
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-04-14 13:00:24 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/Favourite.json?ID=" << saveID << "&Key=" << authUser.SessionKey;
|
|
|
|
if(!favourite)
|
|
|
|
urlStream << "&Mode=Remove";
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
int status = ((json::Number)objDocument["Status"]).Value();
|
|
|
|
|
|
|
|
if(status!=1)
|
|
|
|
{
|
|
|
|
lastError = ((json::String)objDocument["Error"]).Value();
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
failure:
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
|
|
|
RequestStatus Client::ReportSave(int saveID, std::string message)
|
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-04-14 13:00:24 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/Report.json?ID=" << saveID << "&Key=" << authUser.SessionKey;
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
|
|
|
|
char * postNames[] = { "Reason", NULL };
|
|
|
|
char * postDatas[] = { (char*)(message.c_str()) };
|
|
|
|
int postLengths[] = { message.length() };
|
|
|
|
data = http_multipart_post((char *)urlStream.str().c_str(), postNames, postDatas, postLengths, (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
int status = ((json::Number)objDocument["Status"]).Value();
|
|
|
|
|
|
|
|
if(status!=1)
|
|
|
|
{
|
|
|
|
lastError = ((json::String)objDocument["Error"]).Value();
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
failure:
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
|
|
|
RequestStatus Client::UnpublishSave(int saveID)
|
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-04-14 13:00:24 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/Delete.json?ID=" << saveID << "&Mode=Unpublish&Key=" << authUser.SessionKey;
|
2012-04-06 18:45:24 -05:00
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Object objDocument;
|
|
|
|
json::Reader::Read(objDocument, dataStream);
|
|
|
|
|
|
|
|
int status = ((json::Number)objDocument["Status"]).Value();
|
|
|
|
|
|
|
|
if(status!=1)
|
2012-12-15 22:12:54 -06:00
|
|
|
{
|
|
|
|
lastError = ((json::String)objDocument["Error"]).Value();
|
2012-04-06 18:45:24 -05:00
|
|
|
goto failure;
|
2012-12-15 22:12:54 -06:00
|
|
|
}
|
2012-04-06 18:45:24 -05:00
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestOkay;
|
|
|
|
failure:
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return RequestFailure;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:23:26 -05:00
|
|
|
SaveInfo * Client::GetSave(int saveID, int saveDate)
|
2012-01-23 16:53:57 -06:00
|
|
|
{
|
|
|
|
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_):
|
2012-01-28 13:56:13 -06:00
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
|
|
|
}
|
2012-01-23 16:53:57 -06:00
|
|
|
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"];
|
2012-01-28 13:56:13 -06:00
|
|
|
json::Number tempMyScore = objDocument["ScoreMine"];
|
2012-01-23 16:53:57 -06:00
|
|
|
json::String tempUsername = objDocument["Username"];
|
|
|
|
json::String tempName = objDocument["Name"];
|
|
|
|
json::String tempDescription = objDocument["Description"];
|
2012-01-25 19:13:33 -06:00
|
|
|
json::Number tempDate = objDocument["Date"];
|
2012-01-23 16:53:57 -06:00
|
|
|
json::Boolean tempPublished = objDocument["Published"];
|
2012-04-14 13:00:24 -05:00
|
|
|
json::Boolean tempFavourite = objDocument["Favourite"];
|
2012-06-22 10:35:32 -05:00
|
|
|
json::Number tempComments = objDocument["Comments"];
|
2012-09-03 07:25:48 -05:00
|
|
|
json::Number tempViews = objDocument["Views"];
|
2012-09-13 16:39:01 -05:00
|
|
|
json::Number tempVersion = objDocument["Version"];
|
2012-03-22 08:50:43 -05:00
|
|
|
|
|
|
|
json::Array tagsArray = objDocument["Tags"];
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> tempTags;
|
2012-03-22 08:50:43 -05:00
|
|
|
|
|
|
|
for(int j = 0; j < tagsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::String tempTag = tagsArray[j];
|
|
|
|
tempTags.push_back(tempTag.Value());
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:23:26 -05:00
|
|
|
SaveInfo * tempSave = new SaveInfo(
|
2012-01-23 16:53:57 -06:00
|
|
|
tempID.Value(),
|
2012-01-25 19:13:33 -06:00
|
|
|
tempDate.Value(),
|
2012-01-23 16:53:57 -06:00
|
|
|
tempScoreUp.Value(),
|
|
|
|
tempScoreDown.Value(),
|
2012-01-28 13:56:13 -06:00
|
|
|
tempMyScore.Value(),
|
2012-01-23 16:53:57 -06:00
|
|
|
tempUsername.Value(),
|
|
|
|
tempName.Value(),
|
|
|
|
tempDescription.Value(),
|
2012-03-22 08:50:43 -05:00
|
|
|
tempPublished.Value(),
|
|
|
|
tempTags
|
2012-01-23 16:53:57 -06:00
|
|
|
);
|
2012-06-22 10:35:32 -05:00
|
|
|
tempSave->Comments = tempComments.Value();
|
2012-04-14 13:00:24 -05:00
|
|
|
tempSave->Favourite = tempFavourite.Value();
|
2012-09-03 07:25:48 -05:00
|
|
|
tempSave->Views = tempViews.Value();
|
2012-09-13 16:39:01 -05:00
|
|
|
tempSave->Version = tempVersion.Value();
|
2013-03-09 21:47:08 -06:00
|
|
|
free(data);
|
2012-04-14 13:00:24 -05:00
|
|
|
return tempSave;
|
2012-01-23 16:53:57 -06:00
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
2013-03-09 21:47:08 -06:00
|
|
|
free(data);
|
2012-01-23 16:53:57 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-09 21:47:08 -06:00
|
|
|
if (data) free(data);
|
2012-01-23 16:53:57 -06:00
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thumbnail * Client::GetPreview(int saveID, int saveDate)
|
|
|
|
{
|
|
|
|
std::stringstream urlStream;
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
2012-01-23 16:53:57 -06:00
|
|
|
if(saveDate)
|
|
|
|
{
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "_" << saveDate;
|
2012-01-23 16:53:57 -06:00
|
|
|
}
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "_large.pti";
|
2012-01-23 16:53:57 -06:00
|
|
|
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));
|
2012-04-03 11:08:56 -05:00
|
|
|
free(thumbData);
|
2012-01-23 16:53:57 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-04-03 11:08:56 -05:00
|
|
|
thumbData = (pixel *)malloc((128*128) * PIXELSIZE);
|
|
|
|
return new Thumbnail(saveID, saveDate, thumbData, ui::Point(128, 128));
|
|
|
|
free(thumbData);
|
2012-01-23 16:53:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(data)
|
|
|
|
{
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
}
|
2012-04-14 13:00:24 -05:00
|
|
|
return new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128));
|
2012-01-23 16:53:57 -06:00
|
|
|
}
|
|
|
|
|
2012-05-31 04:24:44 -05:00
|
|
|
std::vector<SaveComment*> * Client::GetComments(int saveID, int start, int count)
|
2012-02-11 10:08:59 -06:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-05-31 04:24:44 -05:00
|
|
|
std::vector<SaveComment*> * commentArray = new std::vector<SaveComment*>();
|
2012-02-11 10:08:59 -06:00
|
|
|
|
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
2012-06-22 10:35:32 -05:00
|
|
|
urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << start << "&Count=" << count;
|
2012-02-11 10:08:59 -06:00
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
|
|
|
json::Array commentsArray;
|
|
|
|
json::Reader::Read(commentsArray, dataStream);
|
|
|
|
|
|
|
|
for(int j = 0; j < commentsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::Number tempUserID = commentsArray[j]["UserID"];
|
2013-03-14 22:58:09 -05:00
|
|
|
json::String tempUsername = commentsArray[j]["Username"];
|
|
|
|
json::String tempFormattedUsername = commentsArray[j]["FormattedUsername"];
|
2012-02-11 10:08:59 -06:00
|
|
|
json::String tempComment = commentsArray[j]["Text"];
|
|
|
|
commentArray->push_back(
|
2012-05-31 04:24:44 -05:00
|
|
|
new SaveComment(
|
2012-02-11 10:08:59 -06:00
|
|
|
tempUserID.Value(),
|
|
|
|
tempUsername.Value(),
|
2013-03-14 22:58:09 -05:00
|
|
|
tempFormattedUsername.Value(),
|
2012-02-11 10:08:59 -06:00
|
|
|
tempComment.Value()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return commentArray;
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::pair<std::string, int> > * Client::GetTags(int start, int count, std::string query, int & resultCount)
|
2012-08-04 14:55:59 -05:00
|
|
|
{
|
|
|
|
lastError = "";
|
|
|
|
resultCount = 0;
|
|
|
|
std::vector<std::pair<std::string, int> > * tagArray = new std::vector<std::pair<std::string, int> >();
|
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
|
|
|
urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count;
|
|
|
|
if(query.length())
|
|
|
|
{
|
|
|
|
urlStream << "&Search_Query=";
|
|
|
|
if(query.length())
|
|
|
|
urlStream << URLEscape(query);
|
|
|
|
}
|
|
|
|
|
|
|
|
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 tempCount = objDocument["TagTotal"];
|
|
|
|
resultCount = tempCount.Value();
|
|
|
|
json::Array tagsArray = objDocument["Tags"];
|
|
|
|
for(int j = 0; j < tagsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::Number tagCount = tagsArray[j]["Count"];
|
|
|
|
json::String tag = tagsArray[j]["Tag"];
|
2012-12-06 11:34:32 -06:00
|
|
|
tagArray->push_back(std::pair<std::string, int>(tag.Value(), (int)tagCount.Value()));
|
2012-08-04 14:55:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return tagArray;
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<SaveInfo*> * Client::SearchSaves(int start, int count, std::string query, std::string sort, std::string category, int & resultCount)
|
2012-01-19 14:10:05 -06:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-01-21 12:51:28 -06:00
|
|
|
resultCount = 0;
|
2012-06-07 08:23:26 -05:00
|
|
|
std::vector<SaveInfo*> * saveArray = new std::vector<SaveInfo*>();
|
2012-01-19 14:10:05 -06:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data;
|
|
|
|
int dataStatus, dataLength;
|
2012-01-28 13:56:13 -06:00
|
|
|
urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << count;
|
2012-01-19 14:10:05 -06:00
|
|
|
if(query.length() || sort.length())
|
|
|
|
{
|
|
|
|
urlStream << "&Search_Query=";
|
|
|
|
if(query.length())
|
2012-02-01 15:20:27 -06:00
|
|
|
urlStream << URLEscape(query);
|
2012-01-21 12:51:28 -06:00
|
|
|
if(sort == "date")
|
2012-01-19 14:10:05 -06:00
|
|
|
{
|
|
|
|
if(query.length())
|
2012-02-01 15:20:27 -06:00
|
|
|
urlStream << URLEscape(" ");
|
|
|
|
urlStream << URLEscape("sort:") << URLEscape(sort);
|
2012-01-19 14:10:05 -06:00
|
|
|
}
|
|
|
|
}
|
2012-04-14 15:11:54 -05:00
|
|
|
if(category.length())
|
|
|
|
{
|
|
|
|
urlStream << "&Category=" << URLEscape(category);
|
|
|
|
}
|
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
|
|
|
}
|
2012-01-19 14:10:05 -06:00
|
|
|
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"];
|
2012-01-25 19:13:33 -06:00
|
|
|
json::Number tempDate = savesArray[j]["Date"];
|
2012-01-19 14:10:05 -06:00
|
|
|
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-09-13 16:39:01 -05:00
|
|
|
json::Number tempVersion = savesArray[j]["Version"];
|
2012-09-29 15:24:20 -05:00
|
|
|
json::Boolean tempPublished = savesArray[j]["Published"];
|
2012-09-13 16:39:01 -05:00
|
|
|
SaveInfo * tempSaveInfo = new SaveInfo(
|
2012-01-19 14:10:05 -06:00
|
|
|
tempID.Value(),
|
2012-01-25 19:13:33 -06:00
|
|
|
tempDate.Value(),
|
2012-01-19 14:10:05 -06:00
|
|
|
tempScoreUp.Value(),
|
|
|
|
tempScoreDown.Value(),
|
|
|
|
tempUsername.Value(),
|
|
|
|
tempName.Value()
|
2012-09-13 16:39:01 -05:00
|
|
|
);
|
|
|
|
tempSaveInfo->Version = tempVersion.Value();
|
2012-09-29 15:24:20 -05:00
|
|
|
tempSaveInfo->SetPublished(tempPublished);
|
2012-09-13 16:39:01 -05:00
|
|
|
saveArray->push_back(tempSaveInfo);
|
2012-01-19 14:10:05 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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++)
|
|
|
|
{
|
2012-12-15 22:12:54 -06:00
|
|
|
//If the request is active, and we've received a response
|
2012-01-19 11:59:00 -06:00
|
|
|
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];
|
|
|
|
}
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
2012-01-19 07:44:59 -06:00
|
|
|
if(saveDate)
|
|
|
|
{
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "_" << saveDate;
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
2012-01-26 10:18:43 -06:00
|
|
|
urlStream << "_small.pti";
|
2012-01-19 07:44:59 -06:00
|
|
|
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));
|
2012-04-03 11:08:56 -05:00
|
|
|
free(thumbData);
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-04-03 11:08:56 -05:00
|
|
|
thumbData = (pixel *)malloc((128*128) * PIXELSIZE);
|
|
|
|
thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, thumbData, ui::Point(128, 128));
|
|
|
|
free(thumbData);
|
2012-01-19 07:44:59 -06:00
|
|
|
}
|
|
|
|
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];
|
|
|
|
}
|
2012-04-03 11:08:56 -05:00
|
|
|
thumbData = (pixel *)malloc((128*128) * PIXELSIZE);
|
|
|
|
thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, thumbData, ui::Point(128, 128));
|
|
|
|
free(thumbData);
|
2012-01-19 07:44:59 -06:00
|
|
|
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])
|
|
|
|
{
|
2012-11-26 04:34:17 -06:00
|
|
|
activeThumbRequests[i] = http_async_req_start(NULL, (char *)urlStream.str().c_str(), NULL, 0, 0);
|
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;
|
|
|
|
}
|
2012-03-22 17:12:16 -05:00
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * Client::RemoveTag(int saveID, std::string tag)
|
2012-03-22 17:12:16 -05:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-03-22 17:12:16 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
2012-04-14 13:00:24 -05:00
|
|
|
urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=delete&ID=" << saveID << "&Tag=" << tag << "&Key=" << authUser.SessionKey;;
|
2012-03-22 17:12:16 -05:00
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
2012-09-05 13:47:03 -05:00
|
|
|
json::Object responseObject;
|
|
|
|
json::Reader::Read(responseObject, dataStream);
|
2012-03-22 17:12:16 -05:00
|
|
|
|
2012-09-05 13:47:03 -05:00
|
|
|
json::Number status = responseObject["Status"];
|
2012-03-22 17:12:16 -05:00
|
|
|
|
2012-09-05 13:47:03 -05:00
|
|
|
if(status.Value()==0)
|
2012-03-22 17:12:16 -05:00
|
|
|
{
|
2012-09-05 13:47:03 -05:00
|
|
|
json::String error = responseObject["Error"];
|
|
|
|
lastError = error.Value();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
json::Array tagsArray = responseObject["Tags"];
|
|
|
|
|
|
|
|
tags = new std::vector<std::string>();
|
|
|
|
|
|
|
|
for(int j = 0; j < tagsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::String tempTag = tagsArray[j];
|
|
|
|
tags->push_back(tempTag.Value());
|
|
|
|
}
|
2012-03-22 17:12:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return tags;
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * Client::AddTag(int saveID, std::string tag)
|
2012-03-22 17:12:16 -05:00
|
|
|
{
|
|
|
|
lastError = "";
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> * tags = NULL;
|
2012-03-22 17:12:16 -05:00
|
|
|
std::stringstream urlStream;
|
|
|
|
char * data = NULL;
|
|
|
|
int dataStatus, dataLength;
|
2012-04-14 13:00:24 -05:00
|
|
|
urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=add&ID=" << saveID << "&Tag=" << tag << "&Key=" << authUser.SessionKey;
|
2012-03-22 17:12:16 -05:00
|
|
|
if(authUser.ID)
|
|
|
|
{
|
|
|
|
std::stringstream userIDStream;
|
|
|
|
userIDStream << authUser.ID;
|
|
|
|
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = "Not authenticated";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if(dataStatus == 200 && data)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::istringstream dataStream(data);
|
2012-09-05 13:47:03 -05:00
|
|
|
json::Object responseObject;
|
|
|
|
json::Reader::Read(responseObject, dataStream);
|
2012-03-22 17:12:16 -05:00
|
|
|
|
2012-09-05 13:47:03 -05:00
|
|
|
json::Number status = responseObject["Status"];
|
2012-03-22 17:12:16 -05:00
|
|
|
|
2012-09-05 13:47:03 -05:00
|
|
|
if(status.Value()==0)
|
2012-03-22 17:12:16 -05:00
|
|
|
{
|
2012-09-05 13:47:03 -05:00
|
|
|
json::String error = responseObject["Error"];
|
|
|
|
lastError = error.Value();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
json::Array tagsArray = responseObject["Tags"];
|
|
|
|
|
|
|
|
tags = new std::vector<std::string>();
|
|
|
|
|
|
|
|
for(int j = 0; j < tagsArray.Size(); j++)
|
|
|
|
{
|
|
|
|
json::String tempTag = tagsArray[j];
|
|
|
|
tags->push_back(tempTag.Value());
|
|
|
|
}
|
2012-03-22 17:12:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (json::Exception &e)
|
|
|
|
{
|
|
|
|
lastError = "Could not read response";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastError = http_ret_text(dataStatus);
|
|
|
|
}
|
|
|
|
if(data)
|
|
|
|
free(data);
|
|
|
|
return tags;
|
|
|
|
}
|
2012-06-21 19:04:55 -05:00
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> Client::explodePropertyString(std::string property)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> stringArray;
|
|
|
|
std::string current = "";
|
|
|
|
for (std::string::iterator iter = property.begin(); iter != property.end(); ++iter) {
|
2012-06-21 19:04:55 -05:00
|
|
|
if (*iter == '.') {
|
|
|
|
if (current.length() > 0) {
|
|
|
|
stringArray.push_back(current);
|
|
|
|
current = "";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
current += *iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(current.length() > 0)
|
|
|
|
stringArray.push_back(current);
|
|
|
|
return stringArray;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Client::GetPrefString(std::string property, std::string defaultValue)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::String value = GetPref(property);
|
|
|
|
return value.Value();
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
double Client::GetPrefNumber(std::string property, double defaultValue)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Number value = GetPref(property);
|
|
|
|
return value.Value();
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
2012-07-24 07:03:28 -05:00
|
|
|
int Client::GetPrefInteger(std::string property, int defaultValue)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::stringstream defHexInt;
|
|
|
|
defHexInt << std::hex << defaultValue;
|
|
|
|
|
|
|
|
std::string hexString = GetPrefString(property, defHexInt.str());
|
|
|
|
int finalValue = defaultValue;
|
|
|
|
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << hexString;
|
|
|
|
|
|
|
|
hexInt >> std::hex >> finalValue;
|
|
|
|
|
|
|
|
return finalValue;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
catch(std::exception & e)
|
2012-07-24 07:03:28 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
2012-08-05 12:35:12 -05:00
|
|
|
unsigned int Client::GetPrefUInteger(std::string property, unsigned int defaultValue)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::stringstream defHexInt;
|
|
|
|
defHexInt << std::hex << defaultValue;
|
|
|
|
|
|
|
|
std::string hexString = GetPrefString(property, defHexInt.str());
|
|
|
|
unsigned int finalValue = defaultValue;
|
|
|
|
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << hexString;
|
|
|
|
|
|
|
|
hexInt >> std::hex >> finalValue;
|
|
|
|
|
|
|
|
return finalValue;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
catch(std::exception & e)
|
2012-08-05 12:35:12 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> Client::GetPrefStringArray(std::string property)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Array value = GetPref(property);
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> strArray;
|
2012-06-21 19:04:55 -05:00
|
|
|
for(json::Array::iterator iter = value.Begin(); iter != value.End(); ++iter)
|
|
|
|
{
|
2012-07-24 07:03:28 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
json::String cValue = *iter;
|
|
|
|
strArray.push_back(cValue.Value());
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
return strArray;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<std::string>();
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<double> Client::GetPrefNumberArray(std::string property)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Array value = GetPref(property);
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<double> strArray;
|
2012-06-21 19:04:55 -05:00
|
|
|
for(json::Array::iterator iter = value.Begin(); iter != value.End(); ++iter)
|
|
|
|
{
|
2012-07-24 07:03:28 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Number cValue = *iter;
|
|
|
|
strArray.push_back(cValue.Value());
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
return strArray;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<double>();
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<int> Client::GetPrefIntegerArray(std::string property)
|
2012-07-24 07:03:28 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Array value = GetPref(property);
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<int> intArray;
|
2012-07-24 07:03:28 -05:00
|
|
|
for(json::Array::iterator iter = value.Begin(); iter != value.End(); ++iter)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::String cValue = *iter;
|
|
|
|
int finalValue = 0;
|
|
|
|
|
|
|
|
std::string hexString = cValue.Value();
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << hexString;
|
|
|
|
hexInt >> finalValue;
|
|
|
|
|
|
|
|
intArray.push_back(finalValue);
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return intArray;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<int>();
|
2012-07-24 07:03:28 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<unsigned int> Client::GetPrefUIntegerArray(std::string property)
|
2012-08-05 12:35:12 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Array value = GetPref(property);
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<unsigned int> intArray;
|
2012-08-05 12:35:12 -05:00
|
|
|
for(json::Array::iterator iter = value.Begin(); iter != value.End(); ++iter)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::String cValue = *iter;
|
|
|
|
unsigned int finalValue = 0;
|
|
|
|
|
|
|
|
std::string hexString = cValue.Value();
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << hexString;
|
|
|
|
hexInt >> finalValue;
|
|
|
|
|
|
|
|
intArray.push_back(finalValue);
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return intArray;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<unsigned int>();
|
2012-08-05 12:35:12 -05:00
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<bool> Client::GetPrefBoolArray(std::string property)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Array value = GetPref(property);
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<bool> strArray;
|
2012-06-21 19:04:55 -05:00
|
|
|
for(json::Array::iterator iter = value.Begin(); iter != value.End(); ++iter)
|
|
|
|
{
|
2012-07-24 07:03:28 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Boolean cValue = *iter;
|
|
|
|
strArray.push_back(cValue.Value());
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
return strArray;
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-08-12 16:32:57 -05:00
|
|
|
return std::vector<bool>();
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Client::GetPrefBool(std::string property, bool defaultValue)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
json::Boolean value = GetPref(property);
|
|
|
|
return value.Value();
|
|
|
|
}
|
|
|
|
catch (json::Exception & e)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::SetPref(std::string property, std::string value)
|
|
|
|
{
|
|
|
|
json::UnknownElement stringValue = json::String(value);
|
|
|
|
SetPref(property, stringValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::SetPref(std::string property, double value)
|
|
|
|
{
|
|
|
|
json::UnknownElement numberValue = json::Number(value);
|
|
|
|
SetPref(property, numberValue);
|
|
|
|
}
|
|
|
|
|
2012-07-24 07:03:28 -05:00
|
|
|
void Client::SetPref(std::string property, int value)
|
|
|
|
{
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << value;
|
|
|
|
json::UnknownElement intValue = json::String(hexInt.str());
|
|
|
|
SetPref(property, intValue);
|
|
|
|
}
|
|
|
|
|
2012-08-05 12:35:12 -05:00
|
|
|
void Client::SetPref(std::string property, unsigned int value)
|
|
|
|
{
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << value;
|
|
|
|
json::UnknownElement intValue = json::String(hexInt.str());
|
|
|
|
SetPref(property, intValue);
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::SetPref(std::string property, std::vector<std::string> value)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
json::Array newArray;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<std::string>::iterator iter = value.begin(); iter != value.end(); ++iter)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
newArray.Insert(json::String(*iter));
|
|
|
|
}
|
|
|
|
json::UnknownElement newArrayValue = newArray;
|
|
|
|
SetPref(property, newArrayValue);
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::SetPref(std::string property, std::vector<double> value)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
json::Array newArray;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<double>::iterator iter = value.begin(); iter != value.end(); ++iter)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
newArray.Insert(json::Number(*iter));
|
|
|
|
}
|
|
|
|
json::UnknownElement newArrayValue = newArray;
|
|
|
|
SetPref(property, newArrayValue);
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::SetPref(std::string property, std::vector<bool> value)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
json::Array newArray;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<bool>::iterator iter = value.begin(); iter != value.end(); ++iter)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
newArray.Insert(json::Boolean(*iter));
|
|
|
|
}
|
|
|
|
json::UnknownElement newArrayValue = newArray;
|
|
|
|
SetPref(property, newArrayValue);
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::SetPref(std::string property, std::vector<int> value)
|
2012-07-24 07:03:28 -05:00
|
|
|
{
|
|
|
|
json::Array newArray;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<int>::iterator iter = value.begin(); iter != value.end(); ++iter)
|
2012-07-24 07:03:28 -05:00
|
|
|
{
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << *iter;
|
|
|
|
|
|
|
|
newArray.Insert(json::String(hexInt.str()));
|
|
|
|
}
|
|
|
|
json::UnknownElement newArrayValue = newArray;
|
|
|
|
SetPref(property, newArrayValue);
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::SetPref(std::string property, std::vector<unsigned int> value)
|
2012-08-05 12:35:12 -05:00
|
|
|
{
|
|
|
|
json::Array newArray;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<unsigned int>::iterator iter = value.begin(); iter != value.end(); ++iter)
|
2012-08-05 12:35:12 -05:00
|
|
|
{
|
|
|
|
std::stringstream hexInt;
|
|
|
|
hexInt << std::hex << *iter;
|
|
|
|
|
|
|
|
newArray.Insert(json::String(hexInt.str()));
|
|
|
|
}
|
|
|
|
json::UnknownElement newArrayValue = newArray;
|
|
|
|
SetPref(property, newArrayValue);
|
|
|
|
}
|
|
|
|
|
2012-06-21 19:04:55 -05:00
|
|
|
void Client::SetPref(std::string property, bool value)
|
|
|
|
{
|
|
|
|
json::UnknownElement boolValue = json::Boolean(value);
|
|
|
|
SetPref(property, boolValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
json::UnknownElement Client::GetPref(std::string property)
|
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> pTokens = Client::explodePropertyString(property);
|
2012-06-21 19:04:55 -05:00
|
|
|
const json::UnknownElement & configDocumentCopy = configDocument;
|
|
|
|
json::UnknownElement currentRef = configDocumentCopy;
|
2012-08-12 16:32:57 -05:00
|
|
|
for(std::vector<std::string>::iterator iter = pTokens.begin(); iter != pTokens.end(); ++iter)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
2012-07-24 07:03:28 -05:00
|
|
|
currentRef = ((const json::UnknownElement &)currentRef)[*iter];
|
2012-06-21 19:04:55 -05:00
|
|
|
}
|
|
|
|
return currentRef;
|
|
|
|
}
|
|
|
|
|
2012-08-12 16:32:57 -05:00
|
|
|
void Client::setPrefR(std::deque<std::string> tokens, json::UnknownElement & element, json::UnknownElement & value)
|
2012-06-21 19:04:55 -05:00
|
|
|
{
|
|
|
|
if(tokens.size())
|
|
|
|
{
|
|
|
|
std::string token = tokens.front();
|
|
|
|
tokens.pop_front();
|
|
|
|
setPrefR(tokens, element[token], value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
element = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::SetPref(std::string property, json::UnknownElement & value)
|
|
|
|
{
|
2012-08-12 16:32:57 -05:00
|
|
|
std::vector<std::string> pTokens = Client::explodePropertyString(property);
|
|
|
|
std::deque<std::string> dTokens(pTokens.begin(), pTokens.end());
|
|
|
|
std::string token = dTokens.front();
|
2012-06-21 19:04:55 -05:00
|
|
|
dTokens.pop_front();
|
|
|
|
setPrefR(dTokens, configDocument[token], value);
|
|
|
|
}
|