openmohaa/code/gamespy/GP/gpiInfo.c
2023-02-04 21:00:01 +01:00

1286 lines
31 KiB
C

/*
gpiInfo.c
GameSpy Presence SDK
Dan "Mr. Pants" Schoenblum
Copyright 1999-2007 GameSpy Industries, Inc
devsupport@gamespy.com
***********************************************************************
Please see the GameSpy Presence SDK documentation for more information
**********************************************************************/
//INCLUDES
//////////
#include "gpi.h"
//FUNCTIONS
///////////
static GPIBool
gpiIsValidDate(
int day,
int month,
int year
)
{
// Check for a blank.
/////////////////////
if((day == 0) && (month == 0) && (year == 0))
return GPITrue;
// Check for negatives.
///////////////////////
if((day < 0) || (month < 0) || (year < 0))
return GPIFalse;
// Validate the day of the month.
/////////////////////////////////
switch(month)
{
// No month.
////////////
case 0:
// Can't specify a day without a month.
///////////////////////////////////////
if(day != 0)
return GPIFalse;
break;
// 31-day month.
////////////////
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(day > 31)
return GPIFalse;
break;
// 30-day month.
////////////////
case 4:
case 6:
case 9:
case 11:
if(day > 30)
return GPIFalse;
break;
// 28/29-day month.
///////////////////
case 2:
// Leap year?
/////////////
if((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0))
{
if(day > 29)
return GPIFalse;
}
else
{
if(day > 28)
return GPIFalse;
}
break;
// Invalid month.
/////////////////
default:
return GPIFalse;
}
// Check that the date is in the valid range.
// 01.01.1900 - 06.06.2079
// PANTS|02.14.2000
/////////////////////////////////////////////
if(year < 1900)
return GPIFalse;
if(year > 2079)
return GPIFalse;
if(year == 2079)
{
if(month > 6)
return GPIFalse;
if((month == 6) && (day > 6))
return GPIFalse;
}
return GPITrue;
}
static GPResult
gpiDateToInt(
GPConnection * connection,
int * date,
int day,
int month,
int year
)
{
int temp;
// Pack the day/month/year into an int.
// 31-22: day
// 23-16: month
// 15-00: year
///////////////////////////////////////
// Error check.
///////////////
assert(gpiIsValidDate(day, month, year));
if(!gpiIsValidDate(day, month, year))
Error(connection, GP_PARAMETER_ERROR, "Invalid date.");
// Pack!
////////
temp = 0;
temp |= (day << 24);
temp |= (month << 16);
temp |= year;
// Set it.
//////////
*date = temp;
return GP_NO_ERROR;
}
static GPResult
gpiIntToDate(
GPConnection * connection,
int date,
int * day,
int * month,
int * year
)
{
int d;
int m;
int y;
// Unpack the int into a day/month/year.
// 31-22: day
// 23-16: month
// 15-00: year
////////////////////////////////////////
// Split up the date.
/////////////////////
d = ((date >> 24) & 0xFF);
m = ((date >> 16) & 0xFF);
y = (date & 0xFFFF);
// Error check.
///////////////
assert(gpiIsValidDate(d, m, y));
if(!gpiIsValidDate(d, m, y))
Error(connection, GP_PARAMETER_ERROR, "Invalid date.");
// It's all good.
/////////////////
*day = d;
*month = m;
*year = y;
return GP_NO_ERROR;
}
void
gpiInfoCacheToArg(
const GPIInfoCache * cache,
GPGetInfoResponseArg * arg
)
{
#ifndef GSI_UNICODE
// Copy....
///////////
if(cache->nick)
strzcpy(arg->nick, cache->nick, GP_NICK_LEN);
else
arg->nick[0] = '\0';
if(cache->uniquenick)
strzcpy(arg->uniquenick, cache->uniquenick, GP_UNIQUENICK_LEN);
else
arg->uniquenick[0] = '\0';
if(cache->email)
strzcpy(arg->email, cache->email, GP_EMAIL_LEN);
else
arg->email[0] = '\0';
if(cache->firstname)
strzcpy(arg->firstname, cache->firstname, GP_FIRSTNAME_LEN);
else
arg->firstname[0] = '\0';
if(cache->lastname)
strzcpy(arg->lastname, cache->lastname, GP_LASTNAME_LEN);
else
arg->lastname[0] = '\0';
if(cache->homepage)
strzcpy(arg->homepage, cache->homepage, GP_HOMEPAGE_LEN);
else
arg->homepage[0] = '\0';
arg->icquin = cache->icquin;
strzcpy(arg->zipcode, cache->zipcode, GP_ZIPCODE_LEN);
strzcpy(arg->countrycode, cache->countrycode, GP_COUNTRYCODE_LEN);
arg->longitude = cache->longitude;
arg->latitude = cache->latitude;
if(cache->place)
strzcpy(arg->place, cache->place, GP_PLACE_LEN);
else
arg->place[0] = '\0';
arg->birthday = cache->birthday;
arg->birthmonth = cache->birthmonth;
arg->birthyear = cache->birthyear;
arg->sex = (GPEnum)cache->sex;
arg->publicmask = (GPEnum)cache->publicmask;
if(cache->aimname)
strzcpy(arg->aimname, cache->aimname, GP_AIMNAME_LEN);
else
arg->aimname[0] = '\0';
#else
// Copy....
///////////
if(cache->nick)
UTF8ToUCS2StringLen(cache->nick, arg->nick, GP_NICK_LEN);
else
arg->nick[0] = '\0';
if(cache->uniquenick)
UTF8ToUCS2StringLen(cache->uniquenick, arg->uniquenick, GP_UNIQUENICK_LEN);
else
arg->uniquenick[0] = '\0';
if(cache->email)
UTF8ToUCS2StringLen(cache->email, arg->email, GP_EMAIL_LEN);
else
arg->email[0] = '\0';
if(cache->firstname)
UTF8ToUCS2StringLen(cache->firstname, arg->firstname, GP_FIRSTNAME_LEN);
else
arg->firstname[0] = '\0';
if(cache->lastname)
UTF8ToUCS2StringLen(cache->lastname, arg->lastname, GP_LASTNAME_LEN);
else
arg->lastname[0] = '\0';
if(cache->homepage)
UTF8ToUCS2StringLen(cache->homepage, arg->homepage, GP_HOMEPAGE_LEN);
else
arg->homepage[0] = '\0';
UTF8ToUCS2StringLen(cache->zipcode, arg->zipcode, GP_ZIPCODE_LEN);
UTF8ToUCS2StringLen(cache->countrycode, arg->countrycode, GP_COUNTRYCODE_LEN);
if(cache->place)
UTF8ToUCS2StringLen(cache->place, arg->place, GP_PLACE_LEN);
else
arg->place[0] = '\0';
if(cache->aimname)
UTF8ToUCS2StringLen(cache->aimname, arg->aimname, GP_AIMNAME_LEN);
else
arg->aimname[0] = '\0';
#endif
// Non string members
arg->icquin = cache->icquin;
arg->longitude = cache->longitude;
arg->latitude = cache->latitude;
arg->birthday = cache->birthday;
arg->birthmonth = cache->birthmonth;
arg->birthyear = cache->birthyear;
arg->sex = (GPEnum)cache->sex;
arg->publicmask = (GPEnum)cache->publicmask;
arg->pic = cache->pic;
arg->occupationid = cache->occupationid;
arg->industryid = cache->industryid;
arg->incomeid = cache->incomeid;
arg->marriedid = cache->marriedid;
arg->childcount = cache->childcount;
arg->interests1 = cache->interests1;
arg->ownership1 = cache->ownership1;
arg->conntypeid = cache->conntypeid;
}
GPResult
gpiProcessGetInfo(
GPConnection * connection,
GPIOperation * operation,
const char * input
)
{
GPIInfoCache infoCache;
char buffer[64];
int profileid;
GPIProfile * profile;
GPIConnection * iconnection = (GPIConnection*)*connection;
GPICallback callback;
GPIPeer * peer;
char nick[GP_NICK_LEN];
char uniquenick[GP_UNIQUENICK_LEN];
char email[GP_EMAIL_LEN];
char firstname[GP_FIRSTNAME_LEN];
char lastname[GP_LASTNAME_LEN];
char homepage[GP_HOMEPAGE_LEN];
char aimname[GP_AIMNAME_LEN];
GPIBool saveSig;
// Check for an error.
//////////////////////
if(gpiCheckForError(connection, input, GPITrue))
return GP_SERVER_ERROR;
// This should be \pi\.
///////////////////////
if(strncmp(input, "\\pi\\", 4) != 0)
CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
// Get the profile id.
//////////////////////
if(!gpiValueForKey(input, "\\profileid\\", buffer, sizeof(buffer)))
CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
profileid = atoi(buffer);
assert(profileid > 0);
// Get the profile - we might not have a profile object.
////////////////////////////////////////////////////////
gpiGetProfile(connection, (GPProfile)profileid, &profile);
// Setup the info cache.
////////////////////////
memset(&infoCache, 0, sizeof(GPIInfoCache));
infoCache.nick = nick;
infoCache.uniquenick = uniquenick;
infoCache.email = email;
infoCache.firstname = firstname;
infoCache.lastname = lastname;
infoCache.homepage = homepage;
infoCache.aimname = aimname;
// Parse the info.
//////////////////
if(!gpiValueForKey(input, "\\nick\\", infoCache.nick, GP_NICK_LEN))
infoCache.nick[0] = '\0';
if(!gpiValueForKey(input, "\\uniquenick\\", infoCache.uniquenick, GP_UNIQUENICK_LEN))
infoCache.uniquenick[0] = '\0';
if(!gpiValueForKey(input, "\\email\\", infoCache.email, GP_EMAIL_LEN))
infoCache.email[0] = '\0';
if(!gpiValueForKey(input, "\\firstname\\", infoCache.firstname, GP_FIRSTNAME_LEN))
infoCache.firstname[0] = '\0';
if(!gpiValueForKey(input, "\\lastname\\", infoCache.lastname, GP_LASTNAME_LEN))
infoCache.lastname[0] = '\0';
if(!gpiValueForKey(input, "\\icquin\\", buffer, sizeof(buffer)))
infoCache.icquin = -1;
else
infoCache.icquin = atoi(buffer);
if(!gpiValueForKey(input, "\\homepage\\", infoCache.homepage, GP_HOMEPAGE_LEN))
infoCache.homepage[0] = '\0';
if(!gpiValueForKey(input, "\\zipcode\\", infoCache.zipcode, sizeof(infoCache.zipcode)))
infoCache.zipcode[0] = '\0';
if(!gpiValueForKey(input, "\\countrycode\\", infoCache.countrycode, sizeof(infoCache.countrycode)))
infoCache.countrycode[0] = '\0';
if(!gpiValueForKey(input, "\\lon\\", buffer, sizeof(buffer)))
infoCache.longitude = 0;
else
infoCache.longitude = (float)atof(buffer);
if(!gpiValueForKey(input, "\\lat\\", buffer, sizeof(buffer)))
infoCache.latitude = 0;
else
infoCache.latitude = (float)atof(buffer);
if(!gpiValueForKey(input, "\\loc\\", infoCache.place, GP_PLACE_LEN))
infoCache.place[0] = '\0';
if(!gpiValueForKey(input, "\\birthday\\", buffer, sizeof(buffer)))
{
infoCache.birthday = 0;
infoCache.birthmonth = 0;
infoCache.birthyear = 0;
}
else
{
CHECK_RESULT(gpiIntToDate(connection, atoi(buffer), &infoCache.birthday, &infoCache.birthmonth, &infoCache.birthyear));
}
if(!gpiValueForKey(input, "\\sex\\", buffer, sizeof(buffer)))
infoCache.sex = GP_PAT;
else if(buffer[0] == '0')
infoCache.sex = GP_MALE;
else if(buffer[0] == '1')
infoCache.sex = GP_FEMALE;
else
infoCache.sex = GP_PAT;
if(!gpiValueForKey(input, "\\pmask\\", buffer, sizeof(buffer)))
infoCache.publicmask = 0xFFFFFFFF;
else
infoCache.publicmask = atoi(buffer);
if(!gpiValueForKey(input, "\\aim\\", infoCache.aimname, GP_AIMNAME_LEN))
infoCache.aimname[0] = '\0';
if(!gpiValueForKey(input, "\\pic\\", buffer, sizeof(buffer)))
infoCache.pic = 0;
else
infoCache.pic = atoi(buffer);
if(!gpiValueForKey(input, "\\occ\\", buffer, sizeof(buffer)))
infoCache.occupationid = 0;
else
infoCache.occupationid = atoi(buffer);
if(!gpiValueForKey(input, "\\ind\\", buffer, sizeof(buffer)))
infoCache.industryid = 0;
else
infoCache.industryid = atoi(buffer);
if(!gpiValueForKey(input, "\\inc\\", buffer, sizeof(buffer)))
infoCache.incomeid = 0;
else
infoCache.incomeid = atoi(buffer);
if(!gpiValueForKey(input, "\\mar\\", buffer, sizeof(buffer)))
infoCache.marriedid = 0;
else
infoCache.marriedid = atoi(buffer);
if(!gpiValueForKey(input, "\\chc\\", buffer, sizeof(buffer)))
infoCache.childcount = 0;
else
infoCache.childcount = atoi(buffer);
if(!gpiValueForKey(input, "\\i1\\", buffer, sizeof(buffer)))
infoCache.interests1 = 0;
else
infoCache.interests1 = atoi(buffer);
if(!gpiValueForKey(input, "\\o1\\", buffer, sizeof(buffer)))
infoCache.ownership1 = 0;
else
infoCache.ownership1 = atoi(buffer);
if(!gpiValueForKey(input, "\\conn\\", buffer, sizeof(buffer)))
infoCache.conntypeid = 0;
else
infoCache.conntypeid = atoi(buffer);
// Get the peer sig.
////////////////////
if(!gpiValueForKey(input, "\\sig\\", buffer, sizeof(buffer)))
CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
saveSig = iconnection->infoCaching;
// Is there a pending peer connection looking for a sig?
////////////////////////////////////////////////////////
for(peer = iconnection->peerList ; peer != NULL ; peer = peer->pnext)
{
// Is it the same profile?
//////////////////////////
if(peer->profile == profileid)
{
// Is it getting the sig?
/////////////////////////
if(peer->state == GPI_PEER_GETTING_SIG)
{
// We need to make sure there's an actual profile object.
/////////////////////////////////////////////////////////
if(!profile)
profile = gpiProfileListAdd(connection, profileid);
// It got it.
/////////////
peer->state = GPI_PEER_GOT_SIG;
saveSig = GPITrue;
}
}
}
// Cache info?
//////////////
if(!profile && iconnection->infoCaching)
profile = gpiProfileListAdd(connection, profileid);
// Set the peer sig.
////////////////////
if(saveSig)
{
freeclear(profile->peerSig);
profile->peerSig = goastrdup(buffer);
}
// Caching info?
////////////////
if(iconnection->infoCaching)
gpiSetInfoCache(connection, profile, &infoCache);
// Call the callback.
/////////////////////
callback = operation->callback;
if(callback.callback != NULL)
{
GPGetInfoResponseArg * arg;
arg = (GPGetInfoResponseArg *)gsimalloc(sizeof(GPGetInfoResponseArg));
if(arg == NULL)
Error(connection, GP_MEMORY_ERROR, "Out of memory.");
gpiInfoCacheToArg(&infoCache, arg);
arg->result = GP_NO_ERROR;
arg->profile = (GPProfile)profileid;
CHECK_RESULT(gpiAddCallback(connection, callback, arg, operation, 0));
}
// This operation is complete.
//////////////////////////////
gpiRemoveOperation(connection, operation);
return GP_NO_ERROR;
}
GPResult
gpiAddLocalInfo(
GPConnection * connection,
GPIBuffer * buffer
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
// Add updatepro info.
//////////////////////
if(iconnection->updateproBuffer.len > 0)
{
gpiAppendStringToBuffer(connection, buffer, "\\updatepro\\\\sesskey\\");
gpiAppendIntToBuffer(connection, buffer, iconnection->sessKey);
gpiAppendStringToBuffer(connection, buffer, iconnection->updateproBuffer.buffer);
gpiAppendStringToBuffer(connection, buffer, "\\partnerid\\");
gpiAppendIntToBuffer(connection, buffer, iconnection->partnerID);
gpiAppendStringToBuffer(connection, buffer, "\\final\\");
iconnection->updateproBuffer.len = 0;
}
// Add updateui info.
//////////////////////
if(iconnection->updateuiBuffer.len > 0)
{
gpiAppendStringToBuffer(connection, buffer, "\\updateui\\\\sesskey\\");
gpiAppendIntToBuffer(connection, buffer, iconnection->sessKey);
gpiAppendStringToBuffer(connection, buffer, iconnection->updateuiBuffer.buffer);
gpiAppendStringToBuffer(connection, buffer, "\\final\\");
iconnection->updateuiBuffer.len = 0;
}
return GP_NO_ERROR;
}
static GPResult
gpiSendLocalInfo(
GPConnection * connection,
const char * info,
const char * value
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
CHECK_RESULT(gpiAppendStringToBuffer(connection, &iconnection->updateproBuffer, info));
CHECK_RESULT(gpiAppendStringToBuffer(connection, &iconnection->updateproBuffer, value));
return GP_NO_ERROR;
}
static GPResult
gpiSendUserInfo(
GPConnection * connection,
const char * info,
const char * value
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
CHECK_RESULT(gpiAppendStringToBuffer(connection, &iconnection->updateuiBuffer, info));
CHECK_RESULT(gpiAppendStringToBuffer(connection, &iconnection->updateuiBuffer, value));
return GP_NO_ERROR;
}
GPResult
gpiSetInfoi(
GPConnection * connection,
GPEnum info,
int value
)
{
char intValue[16];
// Check the info param.
////////////////////////
switch(info)
{
case GP_ZIPCODE:
// Error check.
///////////////
if(value < 0)
Error(connection, GP_PARAMETER_ERROR, "Invalid zipcode.");
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\zipcode\\", intValue));
break;
case GP_SEX:
// Check the sex type.
//////////////////////
switch(value)
{
case GP_MALE:
CHECK_RESULT(gpiSendLocalInfo(connection, "\\sex\\", "0"));
break;
case GP_FEMALE:
CHECK_RESULT(gpiSendLocalInfo(connection, "\\sex\\", "1"));
break;
case GP_PAT:
CHECK_RESULT(gpiSendLocalInfo(connection, "\\sex\\", "2"));
break;
default:
Error(connection, GP_PARAMETER_ERROR, "Invalid sex.");
}
break;
case GP_ICQUIN:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\icquin\\", intValue));
break;
case GP_CPUBRANDID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\cpubrandid\\", intValue));
break;
case GP_CPUSPEED:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\cpuspeed\\", intValue));
break;
case GP_MEMORY:
// Divide by 16.
////////////////
value /= 16;
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\memory\\", intValue));
break;
case GP_VIDEOCARD1RAM:
// Divide by 4.
///////////////
value /= 4;
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\videocard1ram\\", intValue));
break;
case GP_VIDEOCARD2RAM:
// Divide by 4.
///////////////
value /= 4;
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\videocard2ram\\", intValue));
break;
case GP_CONNECTIONID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\connectionid\\", intValue));
break;
case GP_CONNECTIONSPEED:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\connectionspeed\\", intValue));
break;
case GP_HASNETWORK:
// A boolean.
/////////////
if(value)
value = 1;
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendUserInfo(connection, "\\hasnetwork\\", intValue));
break;
case GP_PIC:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\pic\\", intValue));
break;
case GP_OCCUPATIONID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\occ\\", intValue));
break;
case GP_INDUSTRYID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\ind\\", intValue));
break;
case GP_INCOMEID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\inc\\", intValue));
break;
case GP_MARRIEDID:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\mar\\", intValue));
break;
case GP_CHILDCOUNT:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\chc\\", intValue));
break;
case GP_INTERESTS1:
// Convert it to a string.
//////////////////////////
sprintf(intValue,"%d",value);
// Send it to the server.
/////////////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\i1\\", intValue));
break;
default:
Error(connection, GP_PARAMETER_ERROR, "Invalid info.");
}
return GP_NO_ERROR;
}
GPResult
gpiSetInfos(
GPConnection * connection,
GPEnum info,
const char * value
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
char buffer[256];
char sex;
//password encryption stuff
char passwordenc[GP_PASSWORDENC_LEN];
// Error check.
///////////////
if(value == NULL)
Error(connection, GP_PARAMETER_ERROR, "Invalid value.");
// Check the info param.
////////////////////////
switch(info)
{
case GP_NICK:
if(!value[0])
Error(connection, GP_PARAMETER_ERROR, "Invalid value.");
strzcpy(buffer, value, GP_NICK_LEN);
strzcpy(iconnection->nick, buffer, GP_NICK_LEN);
#ifdef GSI_UNICODE
UTF8ToUCS2StringLen(iconnection->nick, iconnection->nick_W, GP_NICK_LEN); // update the UCS2 version
#endif
CHECK_RESULT(gpiSendLocalInfo(connection, "\\nick\\", buffer));
break;
case GP_UNIQUENICK:
if(!value[0])
Error(connection, GP_PARAMETER_ERROR, "Invalid value.");
strzcpy(buffer, value, GP_UNIQUENICK_LEN);
strzcpy(iconnection->uniquenick, buffer, GP_UNIQUENICK_LEN);
#ifdef GSI_UNICODE
UTF8ToUCS2StringLen(iconnection->uniquenick, iconnection->uniquenick_W, GP_UNIQUENICK_LEN);
#endif
CHECK_RESULT(gpiSendLocalInfo(connection, "\\uniquenick\\", buffer));
break;
case GP_EMAIL:
if(!value[0])
Error(connection, GP_PARAMETER_ERROR, "Invalid value.");
strzcpy(buffer, value, GP_EMAIL_LEN);
_strlwr(buffer);
strzcpy(iconnection->email, buffer, GP_EMAIL_LEN);
#ifdef GSI_UNICODE
UTF8ToUCS2StringLen(iconnection->email, iconnection->email_W, GP_EMAIL_LEN);
#endif
CHECK_RESULT(gpiSendUserInfo(connection, "\\email\\", buffer));
break;
case GP_PASSWORD:
if(!value[0])
Error(connection, GP_PARAMETER_ERROR, "Invalid value.");
strzcpy(buffer, value, GP_PASSWORD_LEN);
strzcpy(iconnection->password, buffer, GP_PASSWORD_LEN);
#ifdef GSI_UNICODE
UTF8ToUCS2StringLen(iconnection->password, iconnection->password_W, GP_PASSWORD_LEN);
#endif
gpiEncodeString(iconnection->password, passwordenc);
CHECK_RESULT(gpiSendUserInfo(connection, "\\passwordenc\\", passwordenc));
break;
case GP_FIRSTNAME:
strzcpy(buffer, value, GP_FIRSTNAME_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\firstname\\", buffer));
break;
case GP_LASTNAME:
strzcpy(buffer, value, GP_LASTNAME_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\lastname\\", buffer));
break;
case GP_HOMEPAGE:
strzcpy(buffer, value, GP_HOMEPAGE_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\homepage\\", buffer));
break;
case GP_ZIPCODE:
strzcpy(buffer, value, GP_ZIPCODE_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\zipcode\\", buffer));
break;
case GP_COUNTRYCODE:
// Error check.
///////////////
if(strlen(value) != 2)
Error(connection, GP_PARAMETER_ERROR, "Invalid countrycode.");
strzcpy(buffer, value, GP_COUNTRYCODE_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\countrycode\\", buffer));
break;
case GP_SEX:
sex = (char)toupper(value[0]);
if(sex == 'M')
strcpy(buffer, "0");
else if(sex == 'F')
strcpy(buffer, "1");
else
strcpy(buffer, "2");
CHECK_RESULT(gpiSendLocalInfo(connection, "\\sex\\", buffer));
break;
case GP_ICQUIN:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\icquin\\", buffer));
break;
case GP_CPUSPEED:
CHECK_RESULT(gpiSetInfoi(connection, GP_CPUSPEED, atoi(value)));
break;
case GP_MEMORY:
CHECK_RESULT(gpiSetInfoi(connection, GP_MEMORY, atoi(value)));
break;
case GP_VIDEOCARD1STRING:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\videocard1string\\", buffer));
break;
case GP_VIDEOCARD1RAM:
CHECK_RESULT(gpiSetInfoi(connection, GP_VIDEOCARD1RAM, atoi(value)));
break;
case GP_VIDEOCARD2STRING:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\videocard2string\\", buffer));
break;
case GP_VIDEOCARD2RAM:
CHECK_RESULT(gpiSetInfoi(connection, GP_VIDEOCARD2RAM, atoi(value)));
break;
case GP_CONNECTIONSPEED:
CHECK_RESULT(gpiSetInfoi(connection, GP_CONNECTIONSPEED, atoi(value)));
break;
case GP_HASNETWORK:
CHECK_RESULT(gpiSetInfoi(connection, GP_HASNETWORK, atoi(value)));
break;
case GP_OSSTRING:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\osstring\\", buffer));
break;
case GP_AIMNAME:
strzcpy(buffer, value, GP_AIMNAME_LEN);
CHECK_RESULT(gpiSendLocalInfo(connection, "\\aim\\", buffer));
break;
case GP_PIC:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\pic\\", buffer));
break;
case GP_OCCUPATIONID:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\occ\\", buffer));
break;
case GP_INDUSTRYID:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\ind\\", buffer));
break;
case GP_INCOMEID:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\inc\\", buffer));
break;
case GP_MARRIEDID:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\mar\\", buffer));
break;
case GP_CHILDCOUNT:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\chc\\", buffer));
break;
case GP_INTERESTS1:
strzcpy(buffer, value, sizeof(buffer));
CHECK_RESULT(gpiSendLocalInfo(connection, "\\i1\\", buffer));
break;
default:
Error(connection, GP_PARAMETER_ERROR, "Invalid info.");
}
return GP_NO_ERROR;
}
GPResult
gpiSetInfod(
GPConnection * connection,
GPEnum info,
int day,
int month,
int year
)
{
int date;
char intValue[16];
// Birthday is the only date supported.
///////////////////////////////////////
if(info != GP_BIRTHDAY)
Error(connection, GP_PARAMETER_ERROR, "Invalid info.");
// Convert the date into our internal format.
/////////////////////////////////////////////
CHECK_RESULT(gpiDateToInt(connection, &date, day, month, year));
// Convert the int to a string.
///////////////////////////////
sprintf(intValue,"%d",date);
// Send the date.
/////////////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\birthday\\", intValue));
return GP_NO_ERROR;
}
GPResult
gpiSetInfoMask(
GPConnection * connection,
GPEnum mask
)
{
char buffer[16];
// Convert the mask to a string.
////////////////////////////////
sprintf(buffer,"%d",mask);
// Send it.
///////////
CHECK_RESULT(gpiSendLocalInfo(connection, "\\publicmask\\", buffer));
return GP_NO_ERROR;
}
GPResult
gpiSendGetInfo(
GPConnection * connection,
int profileid,
int operationid
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\getprofile\\\\sesskey\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\profileid\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, profileid);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\id\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, operationid);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
return GP_NO_ERROR;
}
GPResult
gpiGetInfo(
GPConnection * connection,
GPProfile profile,
GPEnum checkCache,
GPEnum blocking,
GPCallback callback,
void * param
)
{
GPIProfile * pProfile;
GPIConnection * iconnection = (GPIConnection*)*connection;
GPIOperation * operation = NULL;
GPIBool useCache;
GPResult result;
int id;
// Check checkCache.
////////////////////
useCache = (checkCache == GP_CHECK_CACHE) ? GPITrue:GPIFalse;
// Check the info cache state.
//////////////////////////////
if(!iconnection->infoCaching)
useCache = GPIFalse;
// Check for using cached info.
///////////////////////////////
if(callback && useCache && gpiGetProfile(connection, profile, &pProfile) && pProfile->cache)
{
GPICallback gpiCallback;
GPGetInfoResponseArg * arg;
arg = (GPGetInfoResponseArg *)gsimalloc(sizeof(GPGetInfoResponseArg));
if(arg == NULL)
Error(connection, GP_MEMORY_ERROR, "Out of memory.");
gpiInfoCacheToArg(pProfile->cache, arg);
arg->result = GP_NO_ERROR;
arg->profile = profile;
gpiCallback.callback = callback;
gpiCallback.param = param;
// Add a dummy operation.
/////////////////////////
CHECK_RESULT(gpiAddOperation(connection, GPI_GET_INFO, NULL, &operation, GP_BLOCKING, callback, param));
id = operation->id;
// Add the callback.
////////////////////
CHECK_RESULT(gpiAddCallback(connection, gpiCallback, arg, operation, 0));
// Remove the dummy operation.
//////////////////////////////
gpiRemoveOperation(connection, operation);
}
else
{
// Add the operation.
/////////////////////
CHECK_RESULT(gpiAddOperation(connection, GPI_GET_INFO, NULL, &operation, blocking, callback, param));
id = operation->id;
// Send a request for info.
///////////////////////////
result = gpiSendGetInfo(connection, profile, operation->id);
CHECK_RESULT(result);
}
// Process it if blocking.
//////////////////////////
if(blocking)
{
result = gpiProcess(connection, id);
CHECK_RESULT(result);
}
return GP_NO_ERROR;
}
GPResult
gpiGetInfoNoWait(
GPConnection * connection,
GPProfile profile,
GPGetInfoResponseArg * arg
)
{
GPIProfile * pProfile;
GPIConnection * iconnection = (GPIConnection*)*connection;
// Check the info cache state.
//////////////////////////////
if(!iconnection->infoCaching)
return GP_NETWORK_ERROR;
// Check to see if we have the info cached.
///////////////////////////////////////////
if(!gpiGetProfile(connection, profile, &pProfile) || !pProfile->cache)
return GP_NETWORK_ERROR;
// Fill in the arg.
///////////////////
gpiInfoCacheToArg(pProfile->cache, arg);
arg->result = GP_NO_ERROR;
arg->profile = profile;
return GP_NO_ERROR;
}
GPIBool
gpiSetInfoCache(
GPConnection * connection,
pGPIProfile profile,
const GPIInfoCache * cache
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
// Check if we're caching info.
///////////////////////////////
if(!iconnection->infoCaching)
return GPITrue;
// Free any old cached info.
////////////////////////////
gpiFreeInfoCache(profile);
// Allocate the new info.
/////////////////////////
profile->cache = (GPIInfoCache *)gsimalloc(sizeof(GPIInfoCache));
// Copy in the new info.
////////////////////////
if(profile->cache)
{
*profile->cache = *cache;
profile->cache->nick = goastrdup(cache->nick);
profile->cache->uniquenick = goastrdup(cache->uniquenick);
profile->cache->email = goastrdup(cache->email);
profile->cache->firstname = goastrdup(cache->firstname);
profile->cache->lastname = goastrdup(cache->lastname);
profile->cache->homepage = goastrdup(cache->homepage);
profile->cache->aimname = goastrdup(cache->aimname);
}
return (profile->cache != NULL) ? GPITrue:GPIFalse;
}
void
gpiFreeInfoCache(
pGPIProfile profile
)
{
if(!profile->cache)
return;
freeclear(profile->cache->nick);
freeclear(profile->cache->uniquenick);
freeclear(profile->cache->email);
freeclear(profile->cache->firstname);
freeclear(profile->cache->lastname);
freeclear(profile->cache->homepage);
freeclear(profile->cache->aimname);
freeclear(profile->cache);
}