openmohaa/code/gamespy/Chat/chatCallbacks.c

1655 lines
49 KiB
C
Raw Permalink Normal View History

2023-02-04 21:00:01 +01:00
/*
GameSpy Chat SDK
Dan "Mr. Pants" Schoenblum
dan@gamespy.com
Copyright 1999-2007 GameSpy Industries, Inc
devsupport@gamespy.com
*/
/*************
** INCLUDES **
*************/
#include "chatMain.h"
#include "chatCallbacks.h"
#include "chatChannel.h"
#if defined(_WIN32)
// warning about casting void* to function*
#pragma warning(disable:4055)
#endif
/************
** DEFINES **
************/
#define ASSERT_DATA(data) assert(data != NULL); assert(data->type >= 0); assert(data->type < CALLBACK_NUM); assert(data->callback != NULL); assert(data->callbackParams != NULL); assert(data->ID >= 0);
#define RAW callbackParams->raw
#define REASON callbackParams->reason
#define USER callbackParams->user
#define MESSAGE callbackParams->message
#define TYPE callbackParams->type
#define CHANNEL callbackParams->channel
#define KICKER callbackParams->kicker
#define KICKEE callbackParams->kickee
#define TOPIC callbackParams->topic
#define MODE callbackParams->mode
#define SUCCESS callbackParams->success
#define INDEX callbackParams->index
#define NUM_USERS callbackParams->numUsers
#define NUM_CHANNELS callbackParams->numChannels
#define CHANNELS callbackParams->channels
#define TOPICS callbackParams->topics
#define ENABLED callbackParams->enabled
#define PASSWORD callbackParams->password
#define USERS callbackParams->users
#define MODES callbackParams->modes
#define ADDRESS callbackParams->address
#define WHY callbackParams->why
#define OLD_NICK callbackParams->oldNick
#define NEW_NICK callbackParams->newNick
#define NUM_BANS callbackParams->numBans
#define BANS callbackParams->bans
#define NICK callbackParams->nick
#define NAME callbackParams->name
#define NUM callbackParams->num
#define KEY callbackParams->key
#define KEYS callbackParams->keys
#define VALUE callbackParams->value
#define VALUES callbackParams->values
#define RESULT callbackParams->result
#define NUM_SUGGESTED_NICKS callbackParams->numSuggestedNicks
#define SUGGESTED_NICKS callbackParams->suggestedNicks
#define COPY(param) if(srcParams->param != NULL)\
{\
destParams->param = goastrdup(srcParams->param);\
if(destParams->param == NULL)\
{\
gsifree(destParams);\
gsifree(data.channel);\
/*ERRCON*/ return CHATFalse;\
}\
} else { destParams->param = srcParams->param; } // remove dangling "if" danger
#define COPY_MODE() if(srcParams->mode != NULL)\
{\
destParams->mode = (CHATChannelMode *)gsimalloc(sizeof(CHATChannelMode));\
if(destParams->mode == NULL)\
{\
gsifree(destParams);\
gsifree(data.channel);\
/*ERRCON*/ return CHATFalse;\
}\
memcpy(destParams->mode, srcParams->mode, sizeof(CHATChannelMode));\
} else {} // remove dangling "if" danger
#define COPY_STR_ARRAY(array, num) assert(srcParams->num >= 0);\
if(!srcParams->array)\
destParams->array = NULL;\
else\
{\
destParams->array = (char **)gsimalloc(sizeof(char *) * srcParams->num);\
if(destParams->array == NULL)\
{\
gsifree(destParams);\
gsifree(data.channel);\
/*ERRCON*/ return CHATFalse;\
}\
for(i = 0 ; i < srcParams->num ; i++)\
{\
if(srcParams->array[i] == NULL)\
destParams->array[i] = NULL;\
else\
{\
destParams->array[i] = goastrdup(srcParams->array[i]);\
if(destParams->array[i] == NULL)\
{\
for(i-- ; i >= 0 ; i--)\
gsifree(destParams->array[i]);\
gsifree(destParams->array);\
gsifree(destParams);\
gsifree(data.channel);\
return CHATFalse;\
}\
}\
}\
}
#define COPY_INT_ARRAY(array, num) assert(srcParams->num >= 0);\
if(srcParams->num > 0)\
{\
assert(srcParams->array != NULL);\
len = (int)(sizeof(int) * srcParams->num);\
destParams->array = (int *)gsimalloc((unsigned int)len);\
if(destParams->array == NULL)\
{\
gsifree(destParams);\
gsifree(data.channel);\
/*ERRCON*/ return CHATFalse;\
}\
memcpy(destParams->array, srcParams->array, (unsigned int)len);\
} else {} // remove dangling "if" danger
#define FREE_STRING_ARRAY(array, num) if (num > 0 && array != NULL)\
{\
int i = 0;\
for (; i < num; i++)\
gsifree(array[i]);\
gsifree(array);\
} else {} // remove dangling "if" danger
/**********
** TYPES **
**********/
typedef struct ciCallbackData
{
int type;
void * callback;
void * callbackParams;
void * param;
int ID;
char * channel;
} ciCallbackData;
/**************
** FUNCTIONS **
**************/
static void ciCallbacksArrayElementFreeFn(void * elem)
{
ciCallbackData * data = (ciCallbackData *)elem;
GS_ASSERT(data != NULL);
if (data->channel)
gsifree(data->channel);
}
static void ciFreeCallbackData(ciCallbackData * data)
{
ASSERT_DATA(data);
// Find which type of callback it is.
/////////////////////////////////////
switch(data->type)
{
case CALLBACK_RAW:
{
ciCallbackRawParams * callbackParams = (ciCallbackRawParams *)data->callbackParams;
gsifree(RAW);
break;
}
case CALLBACK_DISCONNECTED:
{
ciCallbackDisconnectedParams * callbackParams = (ciCallbackDisconnectedParams *)data->callbackParams;
gsifree(REASON);
break;
}
case CALLBACK_PRIVATE_MESSAGE:
{
ciCallbackPrivateMessageParams * callbackParams = (ciCallbackPrivateMessageParams *)data->callbackParams;
gsifree(USER);
gsifree(MESSAGE);
break;
}
case CALLBACK_INVITED:
{
ciCallbackInvitedParams * callbackParams = (ciCallbackInvitedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
break;
}
case CALLBACK_CHANNEL_MESSAGE:
{
ciCallbackChannelMessageParams * callbackParams = (ciCallbackChannelMessageParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
gsifree(MESSAGE);
break;
}
case CALLBACK_KICKED:
{
ciCallbackKickedParams * callbackParams = (ciCallbackKickedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
gsifree(REASON);
break;
}
case CALLBACK_USER_JOINED:
{
ciCallbackUserJoinedParams * callbackParams = (ciCallbackUserJoinedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
break;
}
case CALLBACK_USER_PARTED:
{
ciCallbackUserPartedParams * callbackParams = (ciCallbackUserPartedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
gsifree(REASON);
gsifree(KICKER);
break;
}
case CALLBACK_USER_CHANGED_NICK:
{
ciCallbackUserChangedNickParams * callbackParams = (ciCallbackUserChangedNickParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(OLD_NICK);
gsifree(NEW_NICK);
break;
}
case CALLBACK_TOPIC_CHANGED:
{
ciCallbackTopicChangedParams * callbackParams = (ciCallbackTopicChangedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(TOPIC);
break;
}
case CALLBACK_CHANNEL_MODE_CHANGED:
{
ciCallbackChannelModeChangedParams * callbackParams = (ciCallbackChannelModeChangedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(MODE);
break;
}
case CALLBACK_USER_MODE_CHANGED:
{
ciCallbackUserModeChangedParams * callbackParams = (ciCallbackUserModeChangedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
break;
}
case CALLBACK_USER_LIST_UPDATED:
{
ciCallbackUserListUpdatedParams * callbackParams = (ciCallbackUserListUpdatedParams *)data->callbackParams;
gsifree(CHANNEL);
break;
}
case CALLBACK_ENUM_CHANNELS_EACH:
{
ciCallbackEnumChannelsEachParams * callbackParams = (ciCallbackEnumChannelsEachParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(TOPIC);
break;
}
case CALLBACK_ENUM_CHANNELS_ALL:
{
int i;
ciCallbackEnumChannelsAllParams * callbackParams = (ciCallbackEnumChannelsAllParams *)data->callbackParams;
for(i = 0 ; i < NUM_CHANNELS ; i++)
{
gsifree(CHANNELS[i]);
gsifree(TOPICS[i]);
}
gsifree(CHANNELS);
gsifree(TOPICS);
gsifree(NUM_USERS);
break;
}
case CALLBACK_ENTER_CHANNEL:
{
ciCallbackEnterChannelParams * callbackParams = (ciCallbackEnterChannelParams *)data->callbackParams;
gsifree(CHANNEL);
break;
}
case CALLBACK_GET_CHANNEL_TOPIC:
{
ciCallbackGetChannelTopicParams * callbackParams = (ciCallbackGetChannelTopicParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(TOPIC);
break;
}
case CALLBACK_GET_CHANNEL_MODE:
{
ciCallbackGetChannelModeParams * callbackParams = (ciCallbackGetChannelModeParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(MODE);
break;
}
case CALLBACK_GET_UDPRELAY:
{
ciCallbackGetUdpRelayParams * callbackParams = (ciCallbackGetUdpRelayParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(callbackParams->udpIp);
break;
}
case CALLBACK_GET_CHANNEL_PASSWORD:
{
ciCallbackGetChannelPasswordParams * callbackParams = (ciCallbackGetChannelPasswordParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(PASSWORD);
break;
}
case CALLBACK_ENUM_USERS:
{
int i;
ciCallbackEnumUsersParams * callbackParams = (ciCallbackEnumUsersParams *)data->callbackParams;
gsifree(CHANNEL);
for(i = 0 ; i < NUM_USERS ; i++)
gsifree(USERS[i]);
gsifree(USERS);
gsifree(MODES);
break;
}
case CALLBACK_GET_USER_INFO:
{
int i;
ciCallbackGetUserInfoParams * callbackParams = (ciCallbackGetUserInfoParams *)data->callbackParams;
gsifree(NICK);
gsifree(USER);
gsifree(NAME);
gsifree(ADDRESS);
for(i = 0 ; i < NUM_CHANNELS ; i++)
gsifree(CHANNELS[i]);
gsifree(CHANNELS);
break;
}
case CALLBACK_GET_BASIC_USER_INFO:
{
ciCallbackGetBasicUserInfoParams * callbackParams = (ciCallbackGetBasicUserInfoParams *)data->callbackParams;
gsifree(NICK);
gsifree(USER);
gsifree(ADDRESS);
break;
}
case CALLBACK_GET_CHANNEL_BASIC_USER_INFO:
{
ciCallbackGetChannelBasicUserInfoParams * callbackParams = (ciCallbackGetChannelBasicUserInfoParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(NICK);
gsifree(USER);
gsifree(ADDRESS);
break;
}
case CALLBACK_GET_USER_MODE:
{
ciCallbackGetUserModeParams * callbackParams = (ciCallbackGetUserModeParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
break;
}
case CALLBACK_ENUM_CHANNEL_BANS:
{
int i;
ciCallbackEnumChannelBansParams * callbackParams = (ciCallbackEnumChannelBansParams *)data->callbackParams;
gsifree(CHANNEL);
for(i = 0 ; i < NUM_BANS ; i++)
gsifree(BANS[i]);
gsifree(BANS);
break;
}
case CALLBACK_NICK_ERROR:
{
int i;
ciCallbackNickErrorParams * callbackParams = (ciCallbackNickErrorParams *)data->callbackParams;
gsifree(NICK);
for(i = 0 ; i < NUM_SUGGESTED_NICKS; i++)
gsifree(SUGGESTED_NICKS[i]);
gsifree(SUGGESTED_NICKS);
break;
}
case CALLBACK_CHANGE_NICK:
{
ciCallbackChangeNickParams * callbackParams = (ciCallbackChangeNickParams *)data->callbackParams;
gsifree(OLD_NICK);
gsifree(NEW_NICK);
break;
}
case CALLBACK_NEW_USER_LIST:
{
int i;
ciCallbackNewUserListParams * callbackParams = (ciCallbackNewUserListParams *)data->callbackParams;
gsifree(CHANNEL);
for(i = 0 ; i < NUM_USERS ; i++)
gsifree(USERS[i]);
gsifree(USERS);
gsifree(MODES);
break;
}
case CALLBACK_BROADCAST_KEY_CHANGED:
{
ciCallbackBroadcastKeyChangedParams * callbackParams = (ciCallbackBroadcastKeyChangedParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
gsifree(KEY);
gsifree(VALUE);
break;
}
case CALLBACK_GET_GLOBAL_KEYS:
{
int i;
ciCallbackGetGlobalKeysParams * callbackParams = (ciCallbackGetGlobalKeysParams *)data->callbackParams;
gsifree(USER);
for(i = 0 ; i < NUM ; i++)
{
gsifree(KEYS[i]);
if(VALUES)
gsifree(VALUES[i]);
}
gsifree(KEYS);
gsifree(VALUES);
break;
}
case CALLBACK_GET_CHANNEL_KEYS:
{
int i;
ciCallbackGetChannelKeysParams * callbackParams = (ciCallbackGetChannelKeysParams *)data->callbackParams;
gsifree(CHANNEL);
gsifree(USER);
for(i = 0 ; i < NUM ; i++)
{
gsifree(KEYS[i]);
if(VALUES)
gsifree(VALUES[i]);
}
gsifree(KEYS);
gsifree(VALUES);
break;
}
case CALLBACK_AUTHENTICATE_CDKEY:
{
ciCallbackAuthenticateCDKeyParams * callbackParams = (ciCallbackAuthenticateCDKeyParams *)data->callbackParams;
gsifree(MESSAGE);
break;
}
default:
// The type for this callback is messed up.
///////////////////////////////////////////
assert(0);
}
// gsifree the params structure.
/////////////////////////////
gsifree(data->callbackParams);
}
CHATBool ciInitCallbacks(ciConnection * connection)
{
// Setup the darray.
////////////////////
connection->callbackList = ArrayNew(sizeof(ciCallbackData), 128, ciCallbacksArrayElementFreeFn);
if(connection->callbackList == NULL)
return CHATFalse;
return CHATTrue;
}
void ciCleanupCallbacks(CHAT chat)
{
CONNECTION;
// Cleanup.
///////////
if(connection->callbackList != NULL)
{
ciCallbackData * data;
int len;
int i;
// Get the number of callbacks.
///////////////////////////////
len = ArrayLength(connection->callbackList);
// gsifree the data.
/////////////////
for(i = 0 ; i < len ; i++)
{
data = (ciCallbackData *)ArrayNth(connection->callbackList, i);
ASSERT_DATA(data);
// gsifree the data.
/////////////////
ciFreeCallbackData(data);
}
// gsifree the list.
/////////////////
ArrayFree(connection->callbackList);
}
}
CHATBool ciAddCallback_(CHAT chat, int type, void * callback, void * callbackParams, void * param, int ID, const char * channel, size_t callbackParamsSize)
{
ciCallbackData data;
int len;
int i;
CONNECTION;
assert(type >= 0);
assert(type < CALLBACK_NUM);
assert(connection->callbackList != NULL);
assert(callback != NULL);
assert(callbackParams != NULL);
assert(callbackParamsSize > 0);
assert(ID >= 0);
#ifdef _DEBUG
if(channel != NULL)
assert(channel[0] != '\0');
#endif
// Setup the data.
//////////////////
memset(&data, 0, sizeof(ciCallbackData));
data.type = type;
data.callback = callback;
#ifndef _DEBUG
data.callbackParams = gsimalloc(callbackParamsSize);
#else
data.callbackParams = gsimalloc(callbackParamsSize + 64);
memset(data.callbackParams, 0xC4, callbackParamsSize + 64);
#endif
if(data.callbackParams == NULL)
return CHATFalse; //ERRCON
memcpy(data.callbackParams, callbackParams, callbackParamsSize);
data.param = param;
data.ID = ID;
if(channel == NULL)
data.channel = NULL;
else
{
len = (int)(strlen(channel) + 1);
data.channel = (char *)gsimalloc((unsigned int)len);
if(data.channel == NULL)
{
gsifree(data.callbackParams);
return CHATFalse; //ERRCON
}
memcpy(data.channel, channel, (unsigned int)len);
}
// Find which type of callback it is.
/////////////////////////////////////
switch(data.type)
{
case CALLBACK_RAW:
{
ciCallbackRawParams * destParams = (ciCallbackRawParams *)data.callbackParams;
ciCallbackRawParams * srcParams = (ciCallbackRawParams *)callbackParams;
COPY(raw);
break;
}
case CALLBACK_DISCONNECTED:
{
ciCallbackDisconnectedParams * destParams = (ciCallbackDisconnectedParams *)data.callbackParams;
ciCallbackDisconnectedParams * srcParams = (ciCallbackDisconnectedParams *)callbackParams;
COPY(reason);
break;
}
case CALLBACK_PRIVATE_MESSAGE:
{
ciCallbackPrivateMessageParams * destParams = (ciCallbackPrivateMessageParams *)data.callbackParams;
ciCallbackPrivateMessageParams * srcParams = (ciCallbackPrivateMessageParams *)callbackParams;
COPY(user);
COPY(message);
break;
}
case CALLBACK_INVITED:
{
ciCallbackInvitedParams * destParams = (ciCallbackInvitedParams *)data.callbackParams;
ciCallbackInvitedParams * srcParams = (ciCallbackInvitedParams *)callbackParams;
COPY(channel);
COPY(user);
break;
}
case CALLBACK_CHANNEL_MESSAGE:
{
ciCallbackChannelMessageParams * destParams = (ciCallbackChannelMessageParams *)data.callbackParams;
ciCallbackChannelMessageParams * srcParams = (ciCallbackChannelMessageParams *)callbackParams;
COPY(channel);
COPY(user);
COPY(message);
break;
}
case CALLBACK_KICKED:
{
ciCallbackKickedParams * destParams = (ciCallbackKickedParams *)data.callbackParams;
ciCallbackKickedParams * srcParams = (ciCallbackKickedParams *)callbackParams;
COPY(channel);
COPY(user);
COPY(reason);
break;
}
case CALLBACK_USER_JOINED:
{
ciCallbackUserJoinedParams * destParams = (ciCallbackUserJoinedParams *)data.callbackParams;
ciCallbackUserJoinedParams * srcParams = (ciCallbackUserJoinedParams *)callbackParams;
COPY(channel);
COPY(user);
break;
}
case CALLBACK_USER_PARTED:
{
ciCallbackUserPartedParams * destParams = (ciCallbackUserPartedParams *)data.callbackParams;
ciCallbackUserPartedParams * srcParams = (ciCallbackUserPartedParams *)callbackParams;
COPY(channel);
COPY(user);
COPY(reason);
COPY(kicker);
break;
}
case CALLBACK_USER_CHANGED_NICK:
{
ciCallbackUserChangedNickParams * destParams = (ciCallbackUserChangedNickParams *)data.callbackParams;
ciCallbackUserChangedNickParams * srcParams = (ciCallbackUserChangedNickParams *)callbackParams;
COPY(channel);
COPY(oldNick);
COPY(newNick);
break;
}
case CALLBACK_TOPIC_CHANGED:
{
ciCallbackTopicChangedParams * destParams = (ciCallbackTopicChangedParams *)data.callbackParams;
ciCallbackTopicChangedParams * srcParams = (ciCallbackTopicChangedParams *)callbackParams;
COPY(channel);
COPY(topic);
break;
}
case CALLBACK_CHANNEL_MODE_CHANGED:
{
ciCallbackChannelModeChangedParams * destParams = (ciCallbackChannelModeChangedParams *)data.callbackParams;
ciCallbackChannelModeChangedParams * srcParams = (ciCallbackChannelModeChangedParams *)callbackParams;
COPY(channel);
COPY_MODE();
break;
}
case CALLBACK_USER_MODE_CHANGED:
{
ciCallbackUserModeChangedParams * destParams = (ciCallbackUserModeChangedParams *)data.callbackParams;
ciCallbackUserModeChangedParams * srcParams = (ciCallbackUserModeChangedParams *)callbackParams;
COPY(channel);
COPY(user);
break;
}
case CALLBACK_USER_LIST_UPDATED:
{
ciCallbackUserListUpdatedParams * destParams = (ciCallbackUserListUpdatedParams *)data.callbackParams;
ciCallbackUserListUpdatedParams * srcParams = (ciCallbackUserListUpdatedParams *)callbackParams;
COPY(channel);
break;
}
case CALLBACK_ENUM_CHANNELS_EACH:
{
ciCallbackEnumChannelsEachParams * destParams = (ciCallbackEnumChannelsEachParams *)data.callbackParams;
ciCallbackEnumChannelsEachParams * srcParams = (ciCallbackEnumChannelsEachParams *)callbackParams;
COPY(channel);
COPY(topic);
break;
}
case CALLBACK_ENUM_CHANNELS_ALL:
{
ciCallbackEnumChannelsAllParams * destParams = (ciCallbackEnumChannelsAllParams *)data.callbackParams;
ciCallbackEnumChannelsAllParams * srcParams = (ciCallbackEnumChannelsAllParams *)callbackParams;
COPY_STR_ARRAY(channels, numChannels);
COPY_STR_ARRAY(topics, numChannels);
COPY_INT_ARRAY(numUsers, numChannels);
break;
}
case CALLBACK_ENTER_CHANNEL:
{
ciCallbackEnterChannelParams * destParams = (ciCallbackEnterChannelParams *)data.callbackParams;
ciCallbackEnterChannelParams * srcParams = (ciCallbackEnterChannelParams *)callbackParams;
COPY(channel);
break;
}
case CALLBACK_GET_CHANNEL_TOPIC:
{
ciCallbackGetChannelTopicParams * destParams = (ciCallbackGetChannelTopicParams *)data.callbackParams;
ciCallbackGetChannelTopicParams * srcParams = (ciCallbackGetChannelTopicParams *)callbackParams;
COPY(channel);
COPY(topic);
break;
}
case CALLBACK_GET_CHANNEL_MODE:
{
ciCallbackGetChannelModeParams * destParams = (ciCallbackGetChannelModeParams *)data.callbackParams;
ciCallbackGetChannelModeParams * srcParams = (ciCallbackGetChannelModeParams *)callbackParams;
COPY(channel);
COPY_MODE();
break;
}
case CALLBACK_GET_UDPRELAY:
{
ciCallbackGetUdpRelayParams * destParams = (ciCallbackGetUdpRelayParams *)data.callbackParams;
ciCallbackGetUdpRelayParams * srcParams = (ciCallbackGetUdpRelayParams *)callbackParams;
COPY(channel);
COPY(udpIp);
break;
}
case CALLBACK_GET_CHANNEL_PASSWORD:
{
ciCallbackGetChannelPasswordParams * destParams = (ciCallbackGetChannelPasswordParams *)data.callbackParams;
ciCallbackGetChannelPasswordParams * srcParams = (ciCallbackGetChannelPasswordParams *)callbackParams;
COPY(channel);
COPY(password);
break;
}
case CALLBACK_ENUM_USERS:
{
ciCallbackEnumUsersParams * destParams = (ciCallbackEnumUsersParams *)data.callbackParams;
ciCallbackEnumUsersParams * srcParams = (ciCallbackEnumUsersParams *)callbackParams;
COPY(channel);
COPY_STR_ARRAY(users, numUsers);
COPY_INT_ARRAY(modes, numUsers);
break;
}
case CALLBACK_GET_USER_INFO:
{
ciCallbackGetUserInfoParams * destParams = (ciCallbackGetUserInfoParams *)data.callbackParams;
ciCallbackGetUserInfoParams * srcParams = (ciCallbackGetUserInfoParams *)callbackParams;
COPY(nick);
COPY(user);
COPY(name);
COPY(address);
COPY_STR_ARRAY(channels, numChannels);
break;
}
case CALLBACK_GET_BASIC_USER_INFO:
{
ciCallbackGetBasicUserInfoParams * destParams = (ciCallbackGetBasicUserInfoParams *)data.callbackParams;
ciCallbackGetBasicUserInfoParams * srcParams = (ciCallbackGetBasicUserInfoParams *)callbackParams;
COPY(nick);
COPY(user);
COPY(address);
break;
}
case CALLBACK_GET_CHANNEL_BASIC_USER_INFO:
{
ciCallbackGetChannelBasicUserInfoParams * destParams = (ciCallbackGetChannelBasicUserInfoParams *)data.callbackParams;
ciCallbackGetChannelBasicUserInfoParams * srcParams = (ciCallbackGetChannelBasicUserInfoParams *)callbackParams;
COPY(channel);
COPY(nick);
COPY(user);
COPY(address);
break;
}
case CALLBACK_GET_USER_MODE:
{
ciCallbackGetUserModeParams * destParams = (ciCallbackGetUserModeParams *)data.callbackParams;
ciCallbackGetUserModeParams * srcParams = (ciCallbackGetUserModeParams *)callbackParams;
COPY(channel);
COPY(user);
break;
}
case CALLBACK_ENUM_CHANNEL_BANS:
{
ciCallbackEnumChannelBansParams * destParams = (ciCallbackEnumChannelBansParams *)data.callbackParams;
ciCallbackEnumChannelBansParams * srcParams = (ciCallbackEnumChannelBansParams *)callbackParams;
COPY(channel);
COPY_STR_ARRAY(bans, numBans);
break;
}
case CALLBACK_NICK_ERROR:
{
ciCallbackNickErrorParams * destParams = (ciCallbackNickErrorParams *)data.callbackParams;
ciCallbackNickErrorParams * srcParams = (ciCallbackNickErrorParams *)callbackParams;
COPY(nick);
COPY_STR_ARRAY(suggestedNicks, numSuggestedNicks);
break;
}
case CALLBACK_CHANGE_NICK:
{
ciCallbackChangeNickParams * destParams = (ciCallbackChangeNickParams *)data.callbackParams;
ciCallbackChangeNickParams * srcParams = (ciCallbackChangeNickParams *)callbackParams;
COPY(oldNick);
COPY(newNick);
break;
}
case CALLBACK_NEW_USER_LIST:
{
ciCallbackNewUserListParams * destParams = (ciCallbackNewUserListParams *)data.callbackParams;
ciCallbackNewUserListParams * srcParams = (ciCallbackNewUserListParams *)callbackParams;
COPY(channel);
COPY_STR_ARRAY(users, numUsers);
COPY_INT_ARRAY(modes, numUsers);
break;
}
case CALLBACK_BROADCAST_KEY_CHANGED:
{
ciCallbackBroadcastKeyChangedParams * destParams = (ciCallbackBroadcastKeyChangedParams *)data.callbackParams;
ciCallbackBroadcastKeyChangedParams * srcParams = (ciCallbackBroadcastKeyChangedParams *)callbackParams;
COPY(channel);
COPY(user);
COPY(key);
COPY(value);
break;
}
case CALLBACK_GET_GLOBAL_KEYS:
{
ciCallbackGetGlobalKeysParams * destParams = (ciCallbackGetGlobalKeysParams *)data.callbackParams;
ciCallbackGetGlobalKeysParams * srcParams = (ciCallbackGetGlobalKeysParams *)callbackParams;
COPY(user);
COPY_STR_ARRAY(keys, num);
COPY_STR_ARRAY(values, num);
break;
}
case CALLBACK_GET_CHANNEL_KEYS:
{
ciCallbackGetChannelKeysParams * destParams = (ciCallbackGetChannelKeysParams *)data.callbackParams;
ciCallbackGetChannelKeysParams * srcParams = (ciCallbackGetChannelKeysParams *)callbackParams;
COPY(channel);
COPY(user);
COPY_STR_ARRAY(keys, num);
COPY_STR_ARRAY(values, num);
break;
}
case CALLBACK_AUTHENTICATE_CDKEY:
{
ciCallbackAuthenticateCDKeyParams * destParams = (ciCallbackAuthenticateCDKeyParams *)data.callbackParams;
ciCallbackAuthenticateCDKeyParams * srcParams = (ciCallbackAuthenticateCDKeyParams *)callbackParams;
COPY(message);
break;
}
default:
// The type for this callback is messed up.
///////////////////////////////////////////
assert(0);
}
// Add it to the array.
///////////////////////
ArrayAppend(connection->callbackList, &data);
return CHATTrue;
}
static void ciCallCallback(CHAT chat, ciCallbackData * data)
{
void * param;
//CONNECTION;
ASSERT_DATA(data);
// Cache the param.
///////////////////
param = data->param;
// Find which type of callback it is.
/////////////////////////////////////
switch(data->type)
{
case CALLBACK_RAW:
{
ciCallbackRawParams * callbackParams = (ciCallbackRawParams *)data->callbackParams;
chatRaw callback = (chatRaw)data->callback;
#ifndef GSI_UNICODE
callback(chat, RAW, param);
break;
#else
// UNICODE: Copy all the params, call the callback, free the params
unsigned short* raw_W = UTF8ToUCS2StringAlloc(RAW);
callback(chat, raw_W, param);
gsifree(raw_W);
break;
#endif
}
case CALLBACK_DISCONNECTED:
{
ciCallbackDisconnectedParams * callbackParams = (ciCallbackDisconnectedParams *)data->callbackParams;
chatDisconnected callback = (chatDisconnected)data->callback;
#ifndef GSI_UNICODE
callback(chat, REASON, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* reason_W = UTF8ToUCS2StringAlloc(REASON);
callback(chat, reason_W, param);
gsifree(reason_W);
break;
#endif
}
case CALLBACK_PRIVATE_MESSAGE:
{
ciCallbackPrivateMessageParams * callbackParams = (ciCallbackPrivateMessageParams *)data->callbackParams;
chatPrivateMessage callback = (chatPrivateMessage)data->callback;
#ifndef GSI_UNICODE
callback(chat, USER, MESSAGE, TYPE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* message_W = UTF8ToUCS2StringAlloc(MESSAGE);
callback(chat, user_W, message_W, TYPE, param);
gsifree(user_W);
gsifree(message_W);
break;
#endif
}
case CALLBACK_INVITED:
{
ciCallbackInvitedParams * callbackParams = (ciCallbackInvitedParams *)data->callbackParams;
chatInvited callback = (chatInvited)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
callback(chat, channel_W, user_W, param);
gsifree(channel_W);
gsifree(user_W);
break;
#endif
}
case CALLBACK_CHANNEL_MESSAGE:
{
ciCallbackChannelMessageParams * callbackParams = (ciCallbackChannelMessageParams *)data->callbackParams;
chatChannelMessage callback = (chatChannelMessage)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, MESSAGE, TYPE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* message_W = UTF8ToUCS2StringAlloc(MESSAGE);
callback(chat, channel_W, user_W, message_W, TYPE, param);
gsifree(channel_W);
gsifree(user_W);
gsifree(message_W);
break;
#endif
}
case CALLBACK_KICKED:
{
ciCallbackKickedParams * callbackParams = (ciCallbackKickedParams *)data->callbackParams;
chatKicked callback = (chatKicked)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, REASON, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* reason_W = UTF8ToUCS2StringAlloc(REASON);
callback(chat, channel_W, user_W, reason_W, param);
gsifree(channel_W);
gsifree(user_W);
gsifree(reason_W);
break;
#endif
}
case CALLBACK_USER_JOINED:
{
ciCallbackUserJoinedParams * callbackParams = (ciCallbackUserJoinedParams *)data->callbackParams;
chatUserJoined callback = (chatUserJoined)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, MODE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
callback(chat, channel_W, user_W, MODE, param);
gsifree(channel_W);
gsifree(user_W);
break;
#endif
}
case CALLBACK_USER_PARTED:
{
ciCallbackUserPartedParams * callbackParams = (ciCallbackUserPartedParams *)data->callbackParams;
chatUserParted callback = (chatUserParted)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, WHY, REASON, KICKER, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* reason_W = UTF8ToUCS2StringAlloc(REASON);
unsigned short* kicker_W = UTF8ToUCS2StringAlloc(KICKER);
callback(chat, channel_W, user_W, WHY, reason_W, kicker_W, param);
gsifree(channel_W);
gsifree(user_W);
gsifree(reason_W);
gsifree(kicker_W);
break;
#endif
}
case CALLBACK_USER_CHANGED_NICK:
{
ciCallbackUserChangedNickParams * callbackParams = (ciCallbackUserChangedNickParams *)data->callbackParams;
chatUserChangedNick callback = (chatUserChangedNick)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, OLD_NICK, NEW_NICK, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* oldnick_W = UTF8ToUCS2StringAlloc(OLD_NICK);
unsigned short* newnick_W = UTF8ToUCS2StringAlloc(NEW_NICK);
callback(chat, channel_W, oldnick_W, newnick_W, param);
gsifree(channel_W);
gsifree(oldnick_W);
gsifree(newnick_W);
break;
#endif
}
case CALLBACK_TOPIC_CHANGED:
{
ciCallbackTopicChangedParams * callbackParams = (ciCallbackTopicChangedParams *)data->callbackParams;
chatTopicChanged callback = (chatTopicChanged)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, TOPIC, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* topic_W = UTF8ToUCS2StringAlloc(TOPIC);
callback(chat, channel_W, topic_W, param);
gsifree(channel_W);
gsifree(topic_W);
break;
#endif
}
case CALLBACK_CHANNEL_MODE_CHANGED:
{
ciCallbackChannelModeChangedParams * callbackParams = (ciCallbackChannelModeChangedParams *)data->callbackParams;
chatChannelModeChanged callback = (chatChannelModeChanged)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, MODE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
callback(chat, channel_W, MODE, param);
gsifree(channel_W);
break;
#endif
}
case CALLBACK_USER_MODE_CHANGED:
{
ciCallbackUserModeChangedParams * callbackParams = (ciCallbackUserModeChangedParams *)data->callbackParams;
chatUserModeChanged callback = (chatUserModeChanged)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, MODE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
callback(chat, channel_W, user_W, MODE, param);
gsifree(channel_W);
gsifree(user_W);
break;
#endif
}
case CALLBACK_USER_LIST_UPDATED:
{
ciCallbackUserListUpdatedParams * callbackParams = (ciCallbackUserListUpdatedParams *)data->callbackParams;
chatUserListUpdated callback = (chatUserListUpdated)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
callback(chat, channel_W, param);
gsifree(channel_W);
break;
#endif
}
case CALLBACK_ENUM_CHANNELS_EACH:
{
ciCallbackEnumChannelsEachParams * callbackParams = (ciCallbackEnumChannelsEachParams *)data->callbackParams;
chatEnumChannelsCallbackEach callback = (chatEnumChannelsCallbackEach)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, INDEX, CHANNEL, TOPIC, NUM_USERS, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* topic_W = UTF8ToUCS2StringAlloc(TOPIC);
callback(chat, SUCCESS, INDEX, channel_W, topic_W, NUM_USERS, param);
gsifree(channel_W);
gsifree(topic_W);
break;
#endif
}
case CALLBACK_ENUM_CHANNELS_ALL:
{
ciCallbackEnumChannelsAllParams * callbackParams = (ciCallbackEnumChannelsAllParams *)data->callbackParams;
chatEnumChannelsCallbackAll callback = (chatEnumChannelsCallbackAll)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, NUM_CHANNELS, (const char **)CHANNELS, (const char **)TOPICS, NUM_USERS, param);
break;
#else
unsigned short** channels_W = UTF8ToUCS2StringArrayAlloc((const char **)CHANNELS, NUM_CHANNELS);
unsigned short** topics_W = UTF8ToUCS2StringArrayAlloc((const char **)TOPICS, NUM_CHANNELS);
callback(chat, SUCCESS, NUM_CHANNELS, (const unsigned short**)channels_W, (const unsigned short**)topics_W, NUM_USERS, param);
FREE_STRING_ARRAY(channels_W, NUM_CHANNELS);
FREE_STRING_ARRAY(topics_W, NUM_CHANNELS);
break;
#endif
}
case CALLBACK_ENTER_CHANNEL:
{
ciCallbackEnterChannelParams * callbackParams = (ciCallbackEnterChannelParams *)data->callbackParams;
chatEnterChannelCallback callback = (chatEnterChannelCallback)data->callback;
// Call this before the callback so funcs called within the callback know.
//////////////////////////////////////////////////////////////////////////
ciJoinCallbackCalled(chat, CHANNEL);
#ifndef GSI_UNICODE
callback(chat, SUCCESS, RESULT, CHANNEL, param);
break;
#else
{
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
callback(chat, SUCCESS, RESULT, channel_W, param);
gsifree(channel_W);
break;
}
#endif
}
case CALLBACK_GET_CHANNEL_TOPIC:
{
ciCallbackGetChannelTopicParams * callbackParams = (ciCallbackGetChannelTopicParams *)data->callbackParams;
chatGetChannelTopicCallback callback = (chatGetChannelTopicCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, TOPIC, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* topic_W = UTF8ToUCS2StringAlloc(TOPIC);
callback(chat, SUCCESS, channel_W, topic_W, param);
gsifree(channel_W);
gsifree(topic_W);
break;
#endif
}
case CALLBACK_GET_CHANNEL_MODE:
{
ciCallbackGetChannelModeParams * callbackParams = (ciCallbackGetChannelModeParams *)data->callbackParams;
chatGetChannelModeCallback callback = (chatGetChannelModeCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, MODE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
callback(chat, SUCCESS, channel_W, MODE, param);
gsifree(channel_W);
break;
#endif
}
case CALLBACK_GET_UDPRELAY:
{
ciCallbackGetUdpRelayParams * callbackParams = (ciCallbackGetUdpRelayParams *)data->callbackParams;
chatGetUdpRelayCallback callback = (chatGetUdpRelayCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, callbackParams->udpIp, callbackParams->udpPort, callbackParams->udpKey, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* udpIp_W = UTF8ToUCS2StringAlloc(callbackParams->udpIp);
callback(chat, channel_W, udpIp_W, callbackParams->udpPort, callbackParams->udpKey, param);
gsifree(channel_W);
gsifree(udpIp_W);
break;
#endif
}
case CALLBACK_GET_CHANNEL_PASSWORD:
{
ciCallbackGetChannelPasswordParams * callbackParams = (ciCallbackGetChannelPasswordParams *)data->callbackParams;
chatGetChannelPasswordCallback callback = (chatGetChannelPasswordCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, ENABLED, PASSWORD, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* password_W = UTF8ToUCS2StringAlloc(PASSWORD);
callback(chat, SUCCESS, channel_W, ENABLED, password_W, param);
gsifree(channel_W);
gsifree(password_W);
break;
#endif
}
case CALLBACK_ENUM_USERS:
{
ciCallbackEnumUsersParams * callbackParams = (ciCallbackEnumUsersParams *)data->callbackParams;
chatEnumUsersCallback callback = (chatEnumUsersCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, NUM_USERS, (const char **)USERS, MODES, param);
break;
#else
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short** users_W = UTF8ToUCS2StringArrayAlloc((const char **)USERS, NUM_USERS);
callback(chat, SUCCESS, channel_W, NUM_USERS, (const unsigned short**)users_W, MODES, param);
gsifree(channel_W);
FREE_STRING_ARRAY(users_W, NUM_USERS);
break;
#endif
}
case CALLBACK_GET_USER_INFO:
{
ciCallbackGetUserInfoParams * callbackParams = (ciCallbackGetUserInfoParams *)data->callbackParams;
chatGetUserInfoCallback callback = (chatGetUserInfoCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, NICK, USER, NAME, ADDRESS, NUM_CHANNELS, (const char **)CHANNELS, param);
break;
#else
unsigned short* nick_W = UTF8ToUCS2StringAlloc(NICK);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* name_W = UTF8ToUCS2StringAlloc(NAME);
unsigned short* address_W = UTF8ToUCS2StringAlloc(ADDRESS);
unsigned short** channels_W = UTF8ToUCS2StringArrayAlloc((const char **)CHANNELS, NUM_CHANNELS);
callback(chat, SUCCESS, nick_W, user_W, name_W, address_W, NUM_CHANNELS, (const unsigned short**)channels_W, param);
gsifree(nick_W);
gsifree(user_W);
gsifree(name_W);
gsifree(address_W);
FREE_STRING_ARRAY(channels_W, NUM_CHANNELS);
break;
#endif
}
case CALLBACK_GET_BASIC_USER_INFO:
{
ciCallbackGetBasicUserInfoParams * callbackParams = (ciCallbackGetBasicUserInfoParams *)data->callbackParams;
chatGetBasicUserInfoCallback callback = (chatGetBasicUserInfoCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, NICK, USER, ADDRESS, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* nick_W = UTF8ToUCS2StringAlloc(NICK);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* address_W = UTF8ToUCS2StringAlloc(ADDRESS);
callback(chat, SUCCESS, nick_W, user_W, address_W, param);
gsifree(nick_W);
gsifree(user_W);
gsifree(address_W);
break;
#endif
}
case CALLBACK_GET_CHANNEL_BASIC_USER_INFO:
{
ciCallbackGetChannelBasicUserInfoParams * callbackParams = (ciCallbackGetChannelBasicUserInfoParams *)data->callbackParams;
chatGetChannelBasicUserInfoCallback callback = (chatGetChannelBasicUserInfoCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, NICK, USER, ADDRESS, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* nick_W = UTF8ToUCS2StringAlloc(NICK);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* address_W = UTF8ToUCS2StringAlloc(ADDRESS);
callback(chat, SUCCESS, channel_W, nick_W, user_W, address_W, param);
gsifree(channel_W);
gsifree(nick_W);
gsifree(user_W);
gsifree(address_W);
break;
#endif
}
case CALLBACK_GET_USER_MODE:
{
ciCallbackGetUserModeParams * callbackParams = (ciCallbackGetUserModeParams *)data->callbackParams;
chatGetUserModeCallback callback = (chatGetUserModeCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, USER, MODE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
callback(chat, SUCCESS, channel_W, user_W, MODE, param);
gsifree(channel_W);
gsifree(user_W);
break;
#endif
}
case CALLBACK_ENUM_CHANNEL_BANS:
{
ciCallbackEnumChannelBansParams * callbackParams = (ciCallbackEnumChannelBansParams *)data->callbackParams;
chatEnumChannelBansCallback callback = (chatEnumChannelBansCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, NUM_BANS, (const char **)BANS, param);
break;
#else
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short** bans_W = UTF8ToUCS2StringArrayAlloc((const char **)BANS, NUM_BANS);
callback(chat, SUCCESS, channel_W, NUM_BANS, (const unsigned short**)bans_W, param);
gsifree(channel_W);
FREE_STRING_ARRAY(bans_W, NUM_BANS);
break;
#endif
}
case CALLBACK_NICK_ERROR:
{
ciCallbackNickErrorParams * callbackParams = (ciCallbackNickErrorParams *)data->callbackParams;
chatNickErrorCallback callback = (chatNickErrorCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, TYPE, NICK, NUM_SUGGESTED_NICKS, (const char**)SUGGESTED_NICKS, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* nick_W = UTF8ToUCS2StringAlloc(NICK);
unsigned short** suggestedNicks_W = UTF8ToUCS2StringArrayAlloc((const char **)SUGGESTED_NICKS, NUM_SUGGESTED_NICKS);
callback(chat, TYPE, nick_W, NUM_SUGGESTED_NICKS, (const unsigned short**)suggestedNicks_W, param);
gsifree(nick_W);
FREE_STRING_ARRAY(suggestedNicks_W, NUM_SUGGESTED_NICKS);
break;
#endif
}
case CALLBACK_CHANGE_NICK:
{
ciCallbackChangeNickParams * callbackParams = (ciCallbackChangeNickParams *)data->callbackParams;
chatChangeNickCallback callback = (chatChangeNickCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, OLD_NICK, NEW_NICK, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* oldnick_W = UTF8ToUCS2StringAlloc(OLD_NICK);
unsigned short* newnick_W = UTF8ToUCS2StringAlloc(NEW_NICK);
callback(chat, SUCCESS, oldnick_W, newnick_W, param);
gsifree(oldnick_W);
gsifree(newnick_W);
break;
#endif
}
case CALLBACK_NEW_USER_LIST:
{
ciCallbackNewUserListParams * callbackParams = (ciCallbackNewUserListParams *)data->callbackParams;
chatNewUserList callback = (chatNewUserList)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, NUM_USERS, (const char **)USERS, MODES, param);
break;
#else
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short** users_W = UTF8ToUCS2StringArrayAlloc((const char**)USERS, NUM_USERS);
callback(chat, channel_W, NUM_USERS, (const unsigned short**)users_W, MODES, param);
gsifree(channel_W);
FREE_STRING_ARRAY(users_W, NUM_USERS);
break;
#endif
}
case CALLBACK_BROADCAST_KEY_CHANGED:
{
ciCallbackBroadcastKeyChangedParams * callbackParams = (ciCallbackBroadcastKeyChangedParams *)data->callbackParams;
chatBroadcastKeyChanged callback = (chatBroadcastKeyChanged)data->callback;
#ifndef GSI_UNICODE
callback(chat, CHANNEL, USER, KEY, VALUE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short* key_W = UTF8ToUCS2StringAlloc(KEY);
unsigned short* value_W = UTF8ToUCS2StringAlloc(VALUE);
callback(chat, channel_W, user_W, key_W, value_W, param);
gsifree(channel_W);
gsifree(user_W);
gsifree(key_W);
gsifree(value_W);
break;
#endif
}
case CALLBACK_GET_GLOBAL_KEYS:
{
ciCallbackGetGlobalKeysParams * callbackParams = (ciCallbackGetGlobalKeysParams *)data->callbackParams;
chatGetGlobalKeysCallback callback = (chatGetGlobalKeysCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, USER, NUM, (const char **)KEYS, (const char **)VALUES, param);
break;
#else
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short** keys_W = UTF8ToUCS2StringArrayAlloc((const char**)KEYS, NUM);
unsigned short** values_W = UTF8ToUCS2StringArrayAlloc((const char**)VALUES, NUM);
callback(chat, SUCCESS, user_W, NUM, (const unsigned short**)keys_W, (const unsigned short**)values_W, param);
gsifree(user_W);
FREE_STRING_ARRAY(keys_W, NUM);
FREE_STRING_ARRAY(values_W, NUM);
break;
#endif
}
case CALLBACK_GET_CHANNEL_KEYS:
{
ciCallbackGetChannelKeysParams * callbackParams = (ciCallbackGetChannelKeysParams *)data->callbackParams;
chatGetChannelKeysCallback callback = (chatGetChannelKeysCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, SUCCESS, CHANNEL, USER, NUM, (const char **)KEYS, (const char **)VALUES, param);
break;
#else
unsigned short* channel_W = UTF8ToUCS2StringAlloc(CHANNEL);
unsigned short* user_W = UTF8ToUCS2StringAlloc(USER);
unsigned short** keys_W = UTF8ToUCS2StringArrayAlloc((const char**)KEYS, NUM);
unsigned short** values_W = UTF8ToUCS2StringArrayAlloc((const char**)VALUES, NUM);
callback(chat, SUCCESS, channel_W, user_W, NUM, (const unsigned short**)keys_W, (const unsigned short**)values_W, param);
gsifree(channel_W);
gsifree(user_W);
FREE_STRING_ARRAY(keys_W, NUM);
FREE_STRING_ARRAY(values_W, NUM);
break;
#endif
}
case CALLBACK_AUTHENTICATE_CDKEY:
{
ciCallbackAuthenticateCDKeyParams * callbackParams = (ciCallbackAuthenticateCDKeyParams *)data->callbackParams;
chatAuthenticateCDKeyCallback callback = (chatAuthenticateCDKeyCallback)data->callback;
#ifndef GSI_UNICODE
callback(chat, RESULT, MESSAGE, param);
break;
#else
// Copy all the params, call the callback, free the params
unsigned short* message_W = UTF8ToUCS2StringAlloc(MESSAGE);
callback(chat, RESULT, message_W, param);
gsifree(message_W);
break;
#endif
}
default:
// The type for this callback is messed up.
///////////////////////////////////////////
assert(0);
}
// gsifree the data.
/////////////////
ciFreeCallbackData(data);
}
void ciCallCallbacks(CHAT chat, int ID)
{
ciCallbackData * data;
ciCallbackData dataCopy;
int skip;
CONNECTION;
// Call the callbacks.
//////////////////////
for(skip = 0 ; ArrayLength(connection->callbackList) > skip ; )
{
// Get the callback.
///////////////////
data = (ciCallbackData *)ArrayNth(connection->callbackList, skip);
ASSERT_DATA(data);
// Does this depend on a channel we're not in?
//////////////////////////////////////////////
if((data->channel != NULL) && !ciInChannel(chat, data->channel))
{
// gsifree the data.
/////////////////
ciFreeCallbackData(data);
// Kill it.
///////////
ArrayDeleteAt(connection->callbackList, skip);
}
else
{
// Check if this callback depends on the join callback having been called.
// Also, if blocking, only call that callback.
//////////////////////////////////////////////////////////////////////////
if(((data->channel == NULL) || ciWasJoinCallbackCalled(chat, data->channel)) &&
((ID == 0) || (data->ID == ID)))
{
// Copy the data so we can gsifree it before calling the callback.
///////////////////////////////////////////////////////////////
dataCopy = *data;
// gsifree it.
///////////
ArrayDeleteAt(connection->callbackList, skip);
// Call the callback.
/////////////////////
ciCallCallback(chat, &dataCopy);
// Was this the blocking callback?
//////////////////////////////////
if(ID != 0)
return;
}
else
{
// Increment the skip, because it's still in the array.
///////////////////////////////////////////////////////
skip++;
}
}
}
}
static int ciGetCallbackIndexByID(CHAT chat, int ID)
{
ciCallbackData * data;
int i;
int len;
CONNECTION;
// Get the array length.
////////////////////////
len = ArrayLength(connection->callbackList);
// Loop through the callbacks.
//////////////////////////////
for(i = 0 ; i < len ; i++)
{
// Get the callback.
////////////////////
data = (ciCallbackData *)ArrayNth(connection->callbackList, i);
ASSERT_DATA(data);
// Check for an ID match.
/////////////////////////
if(data->ID == ID)
return i;
}
// Didn't find one.
///////////////////
return -1;
}
CHATBool ciCheckCallbacksForID(CHAT chat, int ID)
{
if(ciGetCallbackIndexByID(chat, ID) == -1)
return CHATFalse;
return CHATTrue;
}