openmohaa/code/gamespy/Peer/peerCallbacks.c

3696 lines
83 KiB
C
Raw Permalink Normal View History

2023-02-04 21:00:01 +01:00
/*
GameSpy Peer SDK
Dan "Mr. Pants" Schoenblum
dan@gamespy.com
Copyright 1999-2007 GameSpy Industries, Inc
devsupport@gamespy.com
*/
/*************
** INCLUDES **
*************/
#include <string.h>
#include <stdlib.h>
#include "peer.h"
#include "peerMain.h"
#include "peerCallbacks.h"
#include "peerOperations.h"
/************
** DEFINES **
************/
#define ASSERT_DATA(data) assert(data->type >= 0);\
assert(data->callback);\
assert(data->params);
/**********
** TYPES **
**********/
typedef struct piCallbackData
{
piCallbackType type; // PI_<type>_CALLBACK
PEERBool success; // operation success
PEERCBType callback; // the function callback -- int type for ANSI compatability
void * callbackParam; // user-data for the callback
void * params; // extra callback params
int ID; // unique ID for this callback
PEERBool inCall; // set to true immediately before callback is called, then to false
} piCallbackData;
typedef struct piCallbackFuncs
{
piCallbackType type;
PEERBool (* copy)
(
void * paramsOut,
void * paramsIn
);
void (* gsifree)
(
void * params
);
void (* call)
(
PEER peer,
piCallbackData * data
);
} piCallbackFuncs;
/**************
** CALLBACKS **
**************/
static int piAddCallback
(
PEER peer,
PEERBool success,
PEERCBType callback,
void * param,
piCallbackType type,
void * paramsIn,
size_t paramsSize,
int opID
);
/* Connect.
**********/
typedef struct piConnectParams
{
int failureReason;
} piConnectParams;
static PEERBool piConnectCopy(void * paramsOut_, void * paramsIn_)
{
piConnectParams * paramsOut = (piConnectParams *)paramsOut_;
piConnectParams * paramsIn = (piConnectParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->failureReason = paramsIn->failureReason;
return PEERTrue;
}
static void piConnectFree(void * params_)
{
piConnectParams * params = (piConnectParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piConnectCall(PEER peer, piCallbackData * data)
{
piConnectParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_CONNECT_CALLBACK);
params = data->params;
((peerConnectCallback)data->callback)(peer, data->success, params->failureReason, data->callbackParam);
}
void piAddConnectCallback
(
PEER peer,
PEERBool success,
int failureReason,
peerConnectCallback callback,
void * param,
int opID
)
{
piConnectParams params;
params.failureReason = failureReason;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_CONNECT_CALLBACK, &params, sizeof(piConnectParams), opID);
}
/* JoinRoom.
***********/
typedef struct piJoinRoomParams
{
PEERJoinResult result;
RoomType roomType;
} piJoinRoomParams;
static PEERBool piJoinRoomCopy(void * paramsOut_, void * paramsIn_)
{
piJoinRoomParams * paramsOut = (piJoinRoomParams *)paramsOut_;
piJoinRoomParams * paramsIn = (piJoinRoomParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->result = paramsIn->result;
paramsOut->roomType = paramsIn->roomType;
return PEERTrue;
}
static void piJoinRoomFree(void * params_)
{
piJoinRoomParams * params = (piJoinRoomParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piJoinRoomCall(PEER peer, piCallbackData * data)
{
piJoinRoomParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_JOIN_ROOM_CALLBACK);
params = data->params;
((peerJoinRoomCallback)(PEERCBType)data->callback)(peer, data->success, params->result, params->roomType, data->callbackParam);
}
void piAddJoinRoomCallback
(
PEER peer,
PEERBool success,
PEERJoinResult result,
RoomType roomType,
peerJoinRoomCallback callback,
void * param,
int opID
)
{
piJoinRoomParams params;
// if this was called as part of an AutoMatch attempt, call the callback directly
// this is safe because we're only calling into Peer code
if(peerIsAutoMatching(peer) && (roomType == StagingRoom))
{
callback(peer, success, result, roomType, param);
return;
}
params.result = result;
params.roomType = roomType;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_JOIN_ROOM_CALLBACK, &params, sizeof(piJoinRoomParams), opID);
}
/* ListGroupsRooms.
******************/
typedef struct piListGroupRoomsParams
{
int groupID;
SBServer server;
char * name;
int numWaiting;
int maxWaiting;
int numGames;
int numPlaying;
} piListGroupRoomsParams;
static PEERBool piListGroupRoomsCopy(void * paramsOut_, void * paramsIn_)
{
piListGroupRoomsParams * paramsOut = (piListGroupRoomsParams *)paramsOut_;
piListGroupRoomsParams * paramsIn = (piListGroupRoomsParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->groupID = paramsIn->groupID;
paramsOut->server = paramsIn->server;
paramsOut->numWaiting = paramsIn->numWaiting;
paramsOut->maxWaiting = paramsIn->maxWaiting;
paramsOut->numGames = paramsIn->numGames;
paramsOut->numPlaying = paramsIn->numPlaying;
if(paramsIn->name)
{
paramsOut->name = goastrdup(paramsIn->name);
if(paramsIn->name && !paramsOut->name)
return PEERFalse;
}
else
paramsOut->name = NULL;
return PEERTrue;
}
static void piListGroupRoomsFree(void * params_)
{
piListGroupRoomsParams * params = (piListGroupRoomsParams *)params_;
assert(params);
gsifree(params->name);
}
static void piListGroupRoomsCall(PEER peer, piCallbackData * data)
{
piListGroupRoomsParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_LIST_GROUP_ROOMS_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerListGroupRoomsCallback)(PEERCBType)data->callback)(peer, data->success, params->groupID, params->server, params->name, params->numWaiting, params->maxWaiting, params->numGames, params->numPlaying, data->callbackParam);
#else
{
unsigned short* name_W = NULL;
if (params->name != NULL)
name_W = UTF8ToUCS2StringAlloc(params->name);
((peerListGroupRoomsCallback)(int)data->callback)(peer, data->success, params->groupID, params->server, name_W, params->numWaiting, params->maxWaiting, params->numGames, params->numPlaying, data->callbackParam);
gsifree(name_W);
}
#endif
}
void piAddListGroupRoomsCallback
(
PEER peer,
PEERBool success,
int groupID,
SBServer server,
const char * name,
int numWaiting,
int maxWaiting,
int numGames,
int numPlaying,
peerListGroupRoomsCallback callback,
void * param,
int opID
)
{
piListGroupRoomsParams params;
params.groupID = groupID;
params.server = server;
params.name = (char *)name;
params.numWaiting = numWaiting;
params.maxWaiting = maxWaiting;
params.numGames = numGames;
params.numPlaying = numPlaying;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_LIST_GROUP_ROOMS_CALLBACK, &params, sizeof(piListGroupRoomsParams), opID);
}
/* ListingGames.
***************/
typedef struct piListingGamesParams
{
char * name;
SBServer server;
PEERBool staging;
int msg;
int progress;
} piListingGamesParams;
static PEERBool piListingGamesCopy(void * paramsOut_, void * paramsIn_)
{
piListingGamesParams * paramsOut = (piListingGamesParams *)paramsOut_;
piListingGamesParams * paramsIn = (piListingGamesParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->name)
{
paramsOut->name = goastrdup(paramsIn->name);
if(paramsIn->name && !paramsOut->name)
return PEERFalse;
}
else
paramsOut->name = NULL;
paramsOut->staging = paramsIn->staging;
paramsOut->server = paramsIn->server;
paramsOut->msg = paramsIn->msg;
paramsOut->progress = paramsIn->progress;
return PEERTrue;
}
static void piListingGamesFree(void * params_)
{
piListingGamesParams * params = (piListingGamesParams *)params_;
assert(params);
gsifree(params->name);
}
static void piListingGamesCall(PEER peer, piCallbackData * data)
{
piListingGamesParams * params;
int len;
int i;
PEER_CONNECTION;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_LISTING_GAMES_CALLBACK);
params = data->params;
// This is a bit of a hack. We don't want the server browser progess to show
// 100% until the last callback is being called.
if (params->progress == 100)
{
len = ArrayLength(connection->callbackList);
for(i = 0; i < len; i++)
{
// look for a listing games callback
piCallbackData* anotherData = (piCallbackData *)ArrayNth(connection->callbackList, i);
if(anotherData != data && anotherData->type == PI_LISTING_GAMES_CALLBACK)
{
piListingGamesParams* anotherParams = (piListingGamesParams *)anotherData->params;
if(anotherParams->msg == PEER_UPDATE)
{
// Another update callback will follow this one,
// limit the current callback's progress to 99%
params->progress = 99;
break;
}
}
}
}
#ifndef GSI_UNICODE
((peerListingGamesCallback)(PEERCBType)data->callback)(peer, data->success, params->name, params->server, params->staging, params->msg, params->progress, data->callbackParam);
#else
{
unsigned short* name_W = NULL;
if (params->name != NULL)
name_W = UTF8ToUCS2StringAlloc(params->name);
((peerListingGamesCallback)(int)data->callback)(peer, data->success, name_W, params->server, params->staging, params->msg, params->progress, data->callbackParam);
gsifree(name_W);
}
#endif
}
void piAddListingGamesCallback
(
PEER peer,
PEERBool success,
SBServer server,
int msg
)
{
piListingGamesParams params;
const char * name;
const char * gamemode;
PEERBool staging;
int count;
int pendingCount;
int progress;
PEER_CONNECTION;
// if this is a remove, remove any queued adds or updates
if(msg == PEER_REMOVE)
piClearListingGameServerCallbacks(peer, server);
// get info from the server object
if(server)
{
name = SBServerGetStringValueA(server, "hostname", "(No Name)");
gamemode = SBServerGetStringValueA(server, "gamemode", "");
staging = (PEERBool)(strcasecmp(gamemode, "openstaging") == 0);
}
else
{
name = NULL;
staging = PEERFalse;
}
// set the progress
if(connection->initialGameList)
{
count = SBServerListCount(&connection->gameList);
if(count)
{
pendingCount = (connection->gameEngine.querylist.count + connection->gameEngine.pendinglist.count);
progress = (((count - pendingCount) * 100) / count);
}
else
{
progress = 0;
}
}
else
{
progress = 100;
}
params.name = (char *)name;
params.server = server;
params.staging = staging;
params.msg = msg;
params.progress = progress;
piAddCallback(peer, success, (PEERCBType)connection->gameListCallback, connection->gameListParam, PI_LISTING_GAMES_CALLBACK, &params, sizeof(piListingGamesParams), -1);
}
/* NickError.
*************/
typedef struct piNickErrorParams
{
int type;
char * nick;
int numSuggestedNicks;
char ** suggestedNicks;
} piNickErrorParams;
static PEERBool piNickErrorCopy(void * paramsOut_, void * paramsIn_)
{
int i;
int num;
PEERBool success = PEERTrue;
piNickErrorParams * paramsOut = (piNickErrorParams *)paramsOut_;
piNickErrorParams * paramsIn = (piNickErrorParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
memset(paramsOut, 0, sizeof(piNickErrorParams));
num = paramsOut->numSuggestedNicks = paramsIn->numSuggestedNicks;
paramsOut->type = paramsIn->type;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
success = PEERFalse;
}
else
paramsOut->nick = NULL;
if(success && num && paramsIn->suggestedNicks)
{
paramsOut->suggestedNicks = (char **)gsimalloc(sizeof(char *) * num);
if(!paramsOut->suggestedNicks)
success = PEERFalse;
else
memset(paramsOut->suggestedNicks, 0, sizeof(char *) * num);
for(i = 0 ; success && (i < num) ; i++)
{
paramsOut->suggestedNicks[i] = goastrdup(paramsIn->suggestedNicks[i]);
if(!paramsOut->suggestedNicks[i])
success = PEERFalse;
}
}
if(!success)
{
gsifree(paramsOut->nick);
for(i = 0 ; i < num ; i++)
{
if(paramsOut->suggestedNicks)
gsifree(paramsOut->suggestedNicks[i]);
}
gsifree(paramsOut->suggestedNicks);
}
return success;
}
static void piNickErrorFree(void * params_)
{
int i;
piNickErrorParams * params = (piNickErrorParams *)params_;
assert(params);
gsifree(params->nick);
for(i = 0 ; i < params->numSuggestedNicks ; i++)
{
if(params->suggestedNicks)
gsifree(params->suggestedNicks[i]);
}
gsifree(params->suggestedNicks);
}
static void piNickErrorCall(PEER peer, piCallbackData * data)
{
piNickErrorParams * params;
//PEER_CONNECTION;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_NICK_ERROR_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerNickErrorCallback)(PEERCBType)data->callback)(peer, params->type, params->nick, params->numSuggestedNicks, (const char **)params->suggestedNicks, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short** suggestedNicks_W = UTF8ToUCS2StringArrayAlloc((const UTF8String *)params->suggestedNicks, params->numSuggestedNicks);
int i;
((peerNickErrorCallback)data->callback)(peer, params->type, nick_W, params->numSuggestedNicks, (const unsigned short**)suggestedNicks_W, data->callbackParam);
gsifree(nick_W);
for (i=0; i < params->numSuggestedNicks; i++)
{
gsifree(suggestedNicks_W[i]);
}
gsifree(suggestedNicks_W);
}
#endif
}
void piAddNickErrorCallback
(
PEER peer,
int type,
const char * nick,
int numSuggestedNicks,
const char ** suggestedNicks,
void * param,
int opID
)
{
piNickErrorParams params;
PEER_CONNECTION;
params.type = type;
params.nick = (char *)nick;
params.numSuggestedNicks = numSuggestedNicks;
params.suggestedNicks = (char **)suggestedNicks;
piAddCallback(peer, PEERFalse, (PEERCBType)connection->nickErrorCallback, param, PI_NICK_ERROR_CALLBACK, &params, sizeof(piNickErrorParams), opID);
}
/* EnumPlayers.
**************/
typedef struct piEnumPlayersParams
{
RoomType roomType;
int index;
char * nick;
int flags;
} piEnumPlayersParams;
static PEERBool piEnumPlayersCopy(void * paramsOut_, void * paramsIn_)
{
piEnumPlayersParams * paramsOut = (piEnumPlayersParams *)paramsOut_;
piEnumPlayersParams * paramsIn = (piEnumPlayersParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
paramsOut->index = paramsIn->index;
paramsOut->flags = paramsIn->flags;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(paramsIn->nick && !paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
return PEERTrue;
}
static void piEnumPlayersFree(void * params_)
{
piEnumPlayersParams * params = (piEnumPlayersParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piEnumPlayersCall(PEER peer, piCallbackData * data)
{
piEnumPlayersParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ENUM_PLAYERS_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerEnumPlayersCallback)data->callback)(peer, data->success, params->roomType, params->index, params->nick, params->flags, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerEnumPlayersCallback)data->callback)(peer, data->success, params->roomType, params->index, nick_W, params->flags, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddEnumPlayersCallback
(
PEER peer,
PEERBool success,
RoomType roomType,
int index,
const char * nick,
int flags,
peerEnumPlayersCallback callback,
void * param,
int opID
)
{
piEnumPlayersParams params;
params.roomType = roomType;
params.index = index;
params.nick = (char *)nick;
params.flags = flags;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_ENUM_PLAYERS_CALLBACK, &params, sizeof(piEnumPlayersParams), opID);
}
/* GetPlayerInfo.
****************/
typedef struct piGetPlayerInfoParams
{
char * nick;
unsigned int IP;
int profileID;
} piGetPlayerInfoParams;
static PEERBool piGetPlayerInfoCopy(void * paramsOut_, void * paramsIn_)
{
piGetPlayerInfoParams * paramsOut = (piGetPlayerInfoParams *)paramsOut_;
piGetPlayerInfoParams * paramsIn = (piGetPlayerInfoParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
paramsOut->IP = paramsIn->IP;
paramsOut->profileID = paramsIn->profileID;
return PEERTrue;
}
static void piGetPlayerInfoFree(void * params_)
{
piGetPlayerInfoParams * params = (piGetPlayerInfoParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piGetPlayerInfoCall(PEER peer, piCallbackData * data)
{
piGetPlayerInfoParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GET_PLAYER_INFO_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGetPlayerInfoCallback)data->callback)(peer, data->success, params->nick, params->IP, params->profileID, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerGetPlayerInfoCallback)data->callback)(peer, data->success, nick_W, params->IP, params->profileID, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddGetPlayerInfoCallback
(
PEER peer,
PEERBool success,
const char * nick,
unsigned int IP,
int profileID,
peerGetPlayerInfoCallback callback,
void * param,
int opID
)
{
piGetPlayerInfoParams params;
params.nick = (char *)nick;
params.IP = IP;
params.profileID = profileID;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_GET_PLAYER_INFO_CALLBACK, &params, sizeof(piGetPlayerInfoParams), opID);
}
/* GetPlayerProfileID.
*********************/
typedef struct piGetPlayerProfileIDParams
{
char * nick;
int profileID;
} piGetPlayerProfileIDParams;
static PEERBool piGetPlayerProfileIDCopy(void * paramsOut_, void * paramsIn_)
{
piGetPlayerProfileIDParams * paramsOut = (piGetPlayerProfileIDParams *)paramsOut_;
piGetPlayerProfileIDParams * paramsIn = (piGetPlayerProfileIDParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
paramsOut->profileID = paramsIn->profileID;
return PEERTrue;
}
static void piGetPlayerProfileIDFree(void * params_)
{
piGetPlayerProfileIDParams * params = (piGetPlayerProfileIDParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piGetPlayerProfileIDCall(PEER peer, piCallbackData * data)
{
piGetPlayerProfileIDParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GET_PLAYER_PROFILE_ID_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGetPlayerProfileIDCallback)data->callback)(peer, data->success, params->nick, params->profileID, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerGetPlayerProfileIDCallback)data->callback)(peer, data->success, nick_W, params->profileID, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddGetPlayerProfileIDCallback
(
PEER peer,
PEERBool success,
const char * nick,
int profileID,
peerGetPlayerProfileIDCallback callback,
void * param,
int opID
)
{
piGetPlayerProfileIDParams params;
params.nick = (char *)nick;
params.profileID = profileID;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_GET_PLAYER_PROFILE_ID_CALLBACK, &params, sizeof(piGetPlayerProfileIDParams), opID);
}
/* GetPlayerIP.
**************/
typedef struct piGetPlayerIPParams
{
char * nick;
unsigned int IP;
} piGetPlayerIPParams;
static PEERBool piGetPlayerIPCopy(void * paramsOut_, void * paramsIn_)
{
piGetPlayerIPParams * paramsOut = (piGetPlayerIPParams *)paramsOut_;
piGetPlayerIPParams * paramsIn = (piGetPlayerIPParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->IP = paramsIn->IP;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
return PEERTrue;
}
static void piGetPlayerIPFree(void * params_)
{
piGetPlayerIPParams * params = (piGetPlayerIPParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piGetPlayerIPCall(PEER peer, piCallbackData * data)
{
piGetPlayerIPParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GET_PLAYER_IP_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGetPlayerIPCallback)data->callback)(peer, data->success, params->nick, params->IP, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerGetPlayerIPCallback)data->callback)(peer, data->success, nick_W, params->IP, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddGetPlayerIPCallback
(
PEER peer,
PEERBool success,
const char * nick,
unsigned int IP,
peerGetPlayerIPCallback callback,
void * param,
int opID
)
{
piGetPlayerIPParams params;
params.nick = (char *)nick;
params.IP = IP;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_GET_PLAYER_IP_CALLBACK, &params, sizeof(piGetPlayerIPParams), opID);
}
/* Room Message.
***************/
typedef struct piRoomMessageParams
{
RoomType roomType;
char * nick;
char * message;
MessageType messageType;
} piRoomMessageParams;
static PEERBool piRoomMessageCopy(void * paramsOut_, void * paramsIn_)
{
piRoomMessageParams * paramsOut = (piRoomMessageParams *)paramsOut_;
piRoomMessageParams * paramsIn = (piRoomMessageParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
paramsOut->messageType = paramsIn->messageType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->message)
{
paramsOut->message = goastrdup(paramsIn->message);
if(!paramsOut->message)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->message = NULL;
return PEERTrue;
}
static void piRoomMessageFree(void * params_)
{
piRoomMessageParams * params = (piRoomMessageParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->message);
}
static void piRoomMessageCall(PEER peer, piCallbackData * data)
{
piRoomMessageParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ROOM_MESSAGE_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerRoomMessageCallback)data->callback)(peer, params->roomType, params->nick, params->message, params->messageType, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* message_W = UTF8ToUCS2StringAlloc(params->message);
((peerRoomMessageCallback)data->callback)(peer, params->roomType, nick_W, message_W, params->messageType, data->callbackParam);
gsifree(nick_W);
gsifree(message_W);
}
#endif
}
void piAddRoomMessageCallback
(
PEER peer,
RoomType roomType,
const char * nick,
const char * message,
MessageType messageType
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->roomMessage)
{
piRoomMessageParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.message = (char *)message;
params.messageType = messageType;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->roomMessage, callbacks->param, PI_ROOM_MESSAGE_CALLBACK, &params, sizeof(piRoomMessageParams), -1);
}
}
/* Room UTM.
***********/
typedef struct piRoomUTMParams
{
RoomType roomType;
char * nick;
char * command;
char * parameters;
PEERBool authenticated;
} piRoomUTMParams;
static PEERBool piRoomUTMCopy(void * paramsOut_, void * paramsIn_)
{
piRoomUTMParams * paramsOut = (piRoomUTMParams *)paramsOut_;
piRoomUTMParams * paramsIn = (piRoomUTMParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->authenticated = paramsIn->authenticated;
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->command)
{
paramsOut->command = goastrdup(paramsIn->command);
if(!paramsOut->command)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->command = NULL;
if(paramsIn->parameters)
{
paramsOut->parameters = goastrdup(paramsIn->parameters);
if(!paramsOut->parameters)
{
gsifree(paramsOut->nick);
gsifree(paramsOut->command);
return PEERFalse;
}
}
else
paramsOut->parameters = NULL;
return PEERTrue;
}
static void piRoomUTMFree(void * params_)
{
piRoomUTMParams * params = (piRoomUTMParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->command);
gsifree(params->parameters);
}
static void piRoomUTMCall(PEER peer, piCallbackData * data)
{
piRoomUTMParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ROOM_UTM_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerRoomUTMCallback)data->callback)(peer, params->roomType, params->nick, params->command, params->parameters, params->authenticated, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* command_W = UTF8ToUCS2StringAlloc(params->command);
unsigned short* parameters_W = UTF8ToUCS2StringAlloc(params->parameters);
((peerRoomUTMCallback)data->callback)(peer, params->roomType, nick_W, command_W, parameters_W, params->authenticated, data->callbackParam);
gsifree(nick_W);
gsifree(command_W);
gsifree(parameters_W);
}
#endif
}
void piAddRoomUTMCallback
(
PEER peer,
RoomType roomType,
const char * nick,
const char * command,
const char * parameters,
PEERBool authenticated
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->roomUTM)
{
piRoomUTMParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.command = (char *)command;
params.parameters = (char *)parameters;
params.authenticated = authenticated;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->roomUTM, callbacks->param, PI_ROOM_UTM_CALLBACK, &params, sizeof(piRoomUTMParams), -1);
}
}
/* Room Name Changed.
********************/
typedef struct piRoomNameChangedParams
{
RoomType roomType;
} piRoomNameChangedParams;
static PEERBool piRoomNameChangedCopy(void * paramsOut_, void * paramsIn_)
{
piRoomNameChangedParams * paramsOut = (piRoomNameChangedParams *)paramsOut_;
piRoomNameChangedParams * paramsIn = (piRoomNameChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
return PEERTrue;
}
static void piRoomNameChangedFree(void * params_)
{
piRoomNameChangedParams * params = (piRoomNameChangedParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piRoomNameChangedCall(PEER peer, piCallbackData * data)
{
piRoomNameChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ROOM_NAME_CHANGED_CALLBACK);
params = data->params;
((peerRoomNameChangedCallback)data->callback)(peer, params->roomType, data->callbackParam);
}
void piAddRoomNameChangedCallback
(
PEER peer,
RoomType roomType
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->roomNameChanged)
{
piRoomNameChangedParams params;
params.roomType = roomType;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->roomNameChanged, callbacks->param, PI_ROOM_NAME_CHANGED_CALLBACK, &params, sizeof(piRoomNameChangedParams), -1);
}
}
/* Room Mode Changed.
********************/
typedef struct piRoomModeChangedParams
{
RoomType roomType;
CHATChannelMode mode;
} piRoomModeChangedParams;
static PEERBool piRoomModeChangedCopy(void * paramsOut_, void * paramsIn_)
{
piRoomModeChangedParams * paramsOut = (piRoomModeChangedParams *)paramsOut_;
piRoomModeChangedParams * paramsIn = (piRoomModeChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
paramsOut->mode = paramsIn->mode;
return PEERTrue;
}
static void piRoomModeChangedFree(void * params_)
{
piRoomModeChangedParams * params = (piRoomModeChangedParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piRoomModeChangedCall(PEER peer, piCallbackData * data)
{
piRoomModeChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ROOM_MODE_CHANGED_CALLBACK);
params = data->params;
((peerRoomModeChangedCallback)data->callback)(peer, params->roomType, &params->mode, data->callbackParam);
}
void piAddRoomModeChangedCallback
(
PEER peer,
RoomType roomType,
CHATChannelMode * mode
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->roomModeChanged)
{
piRoomModeChangedParams params;
params.roomType = roomType;
params.mode = *mode;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->roomModeChanged, callbacks->param, PI_ROOM_MODE_CHANGED_CALLBACK, &params, sizeof(piRoomModeChangedParams), -1);
}
}
/* Player Message.
*****************/
typedef struct piPlayerMessageParams
{
char * nick;
char * message;
MessageType messageType;
} piPlayerMessageParams;
static PEERBool piPlayerMessageCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerMessageParams * paramsOut = (piPlayerMessageParams *)paramsOut_;
piPlayerMessageParams * paramsIn = (piPlayerMessageParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->messageType = paramsIn->messageType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->message)
{
paramsOut->message = goastrdup(paramsIn->message);
if(!paramsOut->message)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->message = NULL;
return PEERTrue;
}
static void piPlayerMessageFree(void * params_)
{
piPlayerMessageParams * params = (piPlayerMessageParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->message);
}
static void piPlayerMessageCall(PEER peer, piCallbackData * data)
{
piPlayerMessageParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_MESSAGE_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerMessageCallback)data->callback)(peer, params->nick, params->message, params->messageType, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* message_W = UTF8ToUCS2StringAlloc(params->message);
((peerPlayerMessageCallback)data->callback)(peer, nick_W, message_W, params->messageType, data->callbackParam);
gsifree(nick_W);
gsifree(message_W);
}
#endif
}
void piAddPlayerMessageCallback
(
PEER peer,
const char * nick,
const char * message,
MessageType messageType
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerMessage)
{
piPlayerMessageParams params;
params.nick = (char *)nick;
params.message = (char *)message;
params.messageType = messageType;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerMessage, callbacks->param, PI_PLAYER_MESSAGE_CALLBACK, &params, sizeof(piPlayerMessageParams), -1);
}
}
/* Player UTM.
*************/
typedef struct piPlayerUTMParams
{
char * nick;
char * command;
char * parameters;
PEERBool authenticated;
} piPlayerUTMParams;
static PEERBool piPlayerUTMCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerUTMParams * paramsOut = (piPlayerUTMParams *)paramsOut_;
piPlayerUTMParams * paramsIn = (piPlayerUTMParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->authenticated = paramsIn->authenticated;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->command)
{
paramsOut->command = goastrdup(paramsIn->command);
if(!paramsOut->command)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->command = NULL;
if(paramsIn->parameters)
{
paramsOut->parameters = goastrdup(paramsIn->parameters);
if(!paramsOut->parameters)
{
gsifree(paramsOut->nick);
gsifree(paramsOut->command);
return PEERFalse;
}
}
else
paramsOut->parameters = NULL;
return PEERTrue;
}
static void piPlayerUTMFree(void * params_)
{
piPlayerUTMParams * params = (piPlayerUTMParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->command);
gsifree(params->parameters);
}
static void piPlayerUTMCall(PEER peer, piCallbackData * data)
{
piPlayerUTMParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_UTM_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerUTMCallback)data->callback)(peer, params->nick, params->command, params->parameters, params->authenticated, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* command_W = UTF8ToUCS2StringAlloc(params->command);
unsigned short* parameters_W = UTF8ToUCS2StringAlloc(params->parameters);
((peerPlayerUTMCallback)data->callback)(peer, nick_W, command_W, parameters_W, params->authenticated, data->callbackParam);
gsifree(nick_W);
gsifree(command_W);
gsifree(parameters_W);
}
#endif
}
void piAddPlayerUTMCallback
(
PEER peer,
const char * nick,
const char * command,
const char * parameters,
PEERBool authenticated
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerUTM)
{
piPlayerUTMParams params;
params.nick = (char *)nick;
params.command = (char *)command;
params.parameters = (char *)parameters;
params.authenticated = authenticated;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerUTM, callbacks->param, PI_PLAYER_UTM_CALLBACK, &params, sizeof(piPlayerUTMParams), -1);
}
}
/* Ready Changed.
****************/
typedef struct piReadyChangedParams
{
char * nick;
PEERBool ready;
} piReadyChangedParams;
static PEERBool piReadyChangedCopy(void * paramsOut_, void * paramsIn_)
{
piReadyChangedParams * paramsOut = (piReadyChangedParams *)paramsOut_;
piReadyChangedParams * paramsIn = (piReadyChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
paramsOut->ready = paramsIn->ready;
return PEERTrue;
}
static void piReadyChangedFree(void * params_)
{
piReadyChangedParams * params = (piReadyChangedParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piReadyChangedCall(PEER peer, piCallbackData * data)
{
piReadyChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_READY_CHANGED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerReadyChangedCallback)data->callback)(peer, params->nick, params->ready, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerReadyChangedCallback)data->callback)(peer, nick_W, params->ready, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddReadyChangedCallback
(
PEER peer,
const char * nick,
PEERBool ready
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->readyChanged)
{
piReadyChangedParams params;
params.nick = (char *)nick;
params.ready = ready;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->readyChanged, callbacks->param, PI_READY_CHANGED_CALLBACK, &params, sizeof(piReadyChangedParams), -1);
}
}
/* GameStarted.
**************/
typedef struct piGameStartedParams
{
SBServer server;
char * message;
} piGameStartedParams;
static PEERBool piGameStartedCopy(void * paramsOut_, void * paramsIn_)
{
piGameStartedParams * paramsOut = (piGameStartedParams *)paramsOut_;
piGameStartedParams * paramsIn = (piGameStartedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->server = paramsIn->server;
if(paramsIn->message)
{
paramsOut->message = goastrdup(paramsIn->message);
if(!paramsOut->message)
return PEERFalse;
}
else
paramsOut->message = NULL;
return PEERTrue;
}
static void piGameStartedFree(void * params_)
{
piGameStartedParams * params = (piGameStartedParams *)params_;
assert(params);
gsifree(params->message);
}
static void piGameStartedCall(PEER peer, piCallbackData * data)
{
piGameStartedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GAME_STARTED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGameStartedCallback)data->callback)(peer, params->server, params->message, data->callbackParam);
#else
{
unsigned short* message_W = UTF8ToUCS2StringAlloc(params->message);
((peerGameStartedCallback)data->callback)(peer, params->server, message_W, data->callbackParam);
gsifree(message_W);
}
#endif
}
void piAddGameStartedCallback
(
PEER peer,
SBServer server,
const char * message
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->gameStarted)
{
piGameStartedParams params;
params.server = server;
params.message = (char *)message;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->gameStarted, callbacks->param, PI_GAME_STARTED_CALLBACK, &params, sizeof(piGameStartedParams), -1);
}
}
/* Player Joined.
****************/
typedef struct piPlayerJoinedParams
{
RoomType roomType;
char * nick;
} piPlayerJoinedParams;
static PEERBool piPlayerJoinedCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerJoinedParams * paramsOut = (piPlayerJoinedParams *)paramsOut_;
piPlayerJoinedParams * paramsIn = (piPlayerJoinedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
return PEERTrue;
}
static void piPlayerJoinedFree(void * params_)
{
piPlayerJoinedParams * params = (piPlayerJoinedParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piPlayerJoinedCall(PEER peer, piCallbackData * data)
{
piPlayerJoinedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_JOINED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerJoinedCallback)data->callback)(peer, params->roomType, params->nick, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerPlayerJoinedCallback)data->callback)(peer, params->roomType, nick_W, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddPlayerJoinedCallback
(
PEER peer,
RoomType roomType,
const char * nick
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerJoined)
{
piPlayerJoinedParams params;
params.roomType = roomType;
params.nick = (char *)nick;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerJoined, callbacks->param, PI_PLAYER_JOINED_CALLBACK, &params, sizeof(piPlayerJoinedParams), -1);
}
}
/* Player Left.
**************/
typedef struct piPlayerLeftParams
{
RoomType roomType;
char * nick;
char * reason;
} piPlayerLeftParams;
static PEERBool piPlayerLeftCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerLeftParams * paramsOut = (piPlayerLeftParams *)paramsOut_;
piPlayerLeftParams * paramsIn = (piPlayerLeftParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->reason)
{
paramsOut->reason = goastrdup(paramsIn->reason);
if(!paramsOut->reason)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->reason = NULL;
return PEERTrue;
}
static void piPlayerLeftFree(void * params_)
{
piPlayerLeftParams * params = (piPlayerLeftParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->reason);
}
static void piPlayerLeftCall(PEER peer, piCallbackData * data)
{
piPlayerLeftParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_LEFT_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerLeftCallback)data->callback)(peer, params->roomType, params->nick, params->reason, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* reason_W = UTF8ToUCS2StringAlloc(params->reason);
((peerPlayerLeftCallback)data->callback)(peer, params->roomType, nick_W, reason_W, data->callbackParam);
gsifree(nick_W);
gsifree(reason_W);
}
#endif
}
void piAddPlayerLeftCallback
(
PEER peer,
RoomType roomType,
const char * nick,
const char * reason
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerLeft)
{
piPlayerLeftParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.reason = (char *)reason;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerLeft, callbacks->param, PI_PLAYER_LEFT_CALLBACK, &params, sizeof(piPlayerLeftParams), -1);
}
}
/* Kicked.
*********/
typedef struct piKickedParams
{
RoomType roomType;
char * nick;
char * reason;
} piKickedParams;
static PEERBool piKickedCopy(void * paramsOut_, void * paramsIn_)
{
piKickedParams * paramsOut = (piKickedParams *)paramsOut_;
piKickedParams * paramsIn = (piKickedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->reason)
{
paramsOut->reason = goastrdup(paramsIn->reason);
if(!paramsOut->reason)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->reason = NULL;
return PEERTrue;
}
static void piKickedFree(void * params_)
{
piKickedParams * params = (piKickedParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->reason);
}
static void piKickedCall(PEER peer, piCallbackData * data)
{
piKickedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_KICKED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerKickedCallback)data->callback)(peer, params->roomType, params->nick, params->reason, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* reason_W = UTF8ToUCS2StringAlloc(params->reason);
((peerKickedCallback)data->callback)(peer, params->roomType, nick_W, reason_W, data->callbackParam);
gsifree(nick_W);
gsifree(reason_W);
}
#endif
}
void piAddKickedCallback
(
PEER peer,
RoomType roomType,
const char * nick,
const char * reason
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->kicked)
{
piKickedParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.reason = (char *)reason;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->kicked, callbacks->param, PI_KICKED_CALLBACK, &params, sizeof(piKickedParams), -1);
}
}
/* New Player List.
******************/
typedef struct piNewPlayerListParams
{
RoomType roomType;
} piNewPlayerListParams;
static PEERBool piNewPlayerListCopy(void * paramsOut_, void * paramsIn_)
{
piNewPlayerListParams * paramsOut = (piNewPlayerListParams *)paramsOut_;
piNewPlayerListParams * paramsIn = (piNewPlayerListParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
return PEERTrue;
}
static void piNewPlayerListFree(void * params_)
{
piNewPlayerListParams * params = (piNewPlayerListParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piNewPlayerListCall(PEER peer, piCallbackData * data)
{
piNewPlayerListParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_NEW_PLAYER_LIST_CALLBACK);
params = data->params;
((peerNewPlayerListCallback)data->callback)(peer, params->roomType, data->callbackParam);
}
void piAddNewPlayerListCallback
(
PEER peer,
RoomType roomType
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->newPlayerList)
{
piNewPlayerListParams params;
params.roomType = roomType;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->newPlayerList, callbacks->param, PI_NEW_PLAYER_LIST_CALLBACK, &params, sizeof(piNewPlayerListParams), -1);
}
}
/* Player Changed Nick.
**********************/
typedef struct piPlayerChangedNickParams
{
RoomType roomType;
char * oldNick;
char * newNick;
} piPlayerChangedNickParams;
static PEERBool piPlayerChangedNickCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerChangedNickParams * paramsOut = (piPlayerChangedNickParams *)paramsOut_;
piPlayerChangedNickParams * paramsIn = (piPlayerChangedNickParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->oldNick)
{
paramsOut->oldNick = goastrdup(paramsIn->oldNick);
if(!paramsOut->oldNick)
return PEERFalse;
}
else
paramsOut->oldNick = NULL;
if(paramsIn->newNick)
{
paramsOut->newNick = goastrdup(paramsIn->newNick);
if(!paramsOut->newNick)
{
gsifree(paramsOut->oldNick);
return PEERFalse;
}
}
else
paramsOut->newNick = NULL;
return PEERTrue;
}
static void piPlayerChangedNickFree(void * params_)
{
piPlayerChangedNickParams * params = (piPlayerChangedNickParams *)params_;
assert(params);
gsifree(params->oldNick);
gsifree(params->newNick);
}
static void piPlayerChangedNickCall(PEER peer, piCallbackData * data)
{
piPlayerChangedNickParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_CHANGED_NICK_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerChangedNickCallback)data->callback)(peer, params->roomType, params->oldNick, params->newNick, data->callbackParam);
#else
{
unsigned short* oldNick_W = UTF8ToUCS2StringAlloc(params->oldNick);
unsigned short* newNick_W = UTF8ToUCS2StringAlloc(params->newNick);
((peerPlayerChangedNickCallback)data->callback)(peer, params->roomType, oldNick_W, newNick_W, data->callbackParam);
gsifree(oldNick_W);
gsifree(newNick_W);
}
#endif
}
void piAddPlayerChangedNickCallback
(
PEER peer,
RoomType roomType,
const char * oldNick,
const char * newNick
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerChangedNick)
{
piPlayerChangedNickParams params;
params.roomType = roomType;
params.oldNick = (char *)oldNick;
params.newNick = (char *)newNick;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerChangedNick, callbacks->param, PI_PLAYER_CHANGED_NICK_CALLBACK, &params, sizeof(piPlayerChangedNickParams), -1);
}
}
/* Player Info.
**************/
typedef struct piPlayerInfoParams
{
RoomType roomType;
char * nick;
unsigned int IP;
int profileID;
} piPlayerInfoParams;
static PEERBool piPlayerInfoCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerInfoParams * paramsOut = (piPlayerInfoParams *)paramsOut_;
piPlayerInfoParams * paramsIn = (piPlayerInfoParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
paramsOut->IP = paramsIn->IP;
paramsOut->profileID = paramsIn->profileID;
return PEERTrue;
}
static void piPlayerInfoFree(void * params_)
{
piPlayerInfoParams * params = (piPlayerInfoParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piPlayerInfoCall(PEER peer, piCallbackData * data)
{
piPlayerInfoParams * params;
PEER_CONNECTION;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_INFO_CALLBACK);
params = data->params;
// Don't call this if we're not in the room anymore.
////////////////////////////////////////////////////
if(!connection->inRoom[params->roomType])
return;
#ifndef GSI_UNICODE
((peerPlayerInfoCallback)data->callback)(peer, params->roomType, params->nick, params->IP, params->profileID, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerPlayerInfoCallback)data->callback)(peer, params->roomType, nick_W, params->IP, params->profileID, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddPlayerInfoCallback
(
PEER peer,
RoomType roomType,
const char * nick,
unsigned int IP,
int profileID
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerInfo)
{
piPlayerInfoParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.IP = IP;
params.profileID = profileID;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerInfo, callbacks->param, PI_PLAYER_INFO_CALLBACK, &params, sizeof(piPlayerInfoParams), -1);
}
}
/* Disconnected.
***************/
typedef struct piDisconnectedParams
{
char * reason;
} piDisconnectedParams;
static PEERBool piDisconnectedCopy(void * paramsOut_, void * paramsIn_)
{
piDisconnectedParams * paramsOut = (piDisconnectedParams *)paramsOut_;
piDisconnectedParams * paramsIn = (piDisconnectedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->reason)
{
paramsOut->reason = goastrdup(paramsIn->reason);
if(!paramsOut->reason)
return PEERFalse;
}
else
paramsOut->reason = NULL;
return PEERTrue;
}
static void piDisconnectedFree(void * params_)
{
piDisconnectedParams * params = (piDisconnectedParams *)params_;
assert(params);
gsifree(params->reason);
}
static void piDisconnectedCall(PEER peer, piCallbackData * data)
{
piDisconnectedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_DISCONNECTED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerDisconnectedCallback)data->callback)(peer, params->reason, data->callbackParam);
#else
{
unsigned short* reason_W = UTF8ToUCS2StringAlloc(params->reason);
((peerDisconnectedCallback)data->callback)(peer, reason_W, data->callbackParam);
gsifree(reason_W);
}
#endif
}
void piAddDisconnectedCallback
(
PEER peer,
const char * reason
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->disconnected)
{
piDisconnectedParams params;
params.reason = (char *)reason;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->disconnected, callbacks->param, PI_DISCONNECTED_CALLBACK, &params, sizeof(piDisconnectedParams), -1);
}
}
/* Ping.
*******/
typedef struct piPingParams
{
char * nick;
int ping;
} piPingParams;
static PEERBool piPingCopy(void * paramsOut_, void * paramsIn_)
{
piPingParams * paramsOut = (piPingParams *)paramsOut_;
piPingParams * paramsIn = (piPingParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->ping = paramsIn->ping;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
return PEERTrue;
}
static void piPingFree(void * params_)
{
piPingParams * params = (piPingParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piPingCall(PEER peer, piCallbackData * data)
{
piPingParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PING_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPingCallback)data->callback)(peer, params->nick, params->ping, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerPingCallback)data->callback)(peer, nick_W, params->ping, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddPingCallback
(
PEER peer,
const char * nick,
int ping
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->ping)
{
piPingParams params;
params.nick = (char *)nick;
params.ping = ping;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->ping, callbacks->param, PI_PING_CALLBACK, &params, sizeof(piPingParams), -1);
}
}
/* CrossPing.
************/
typedef struct piCrossPingParams
{
char * nick1;
char * nick2;
int crossPing;
} piCrossPingParams;
static PEERBool piCrossPingCopy(void * paramsOut_, void * paramsIn_)
{
piCrossPingParams * paramsOut = (piCrossPingParams *)paramsOut_;
piCrossPingParams * paramsIn = (piCrossPingParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->crossPing = paramsIn->crossPing;
if(paramsIn->nick1)
{
paramsOut->nick1 = goastrdup(paramsIn->nick1);
if(!paramsOut->nick1)
return PEERFalse;
}
else
paramsOut->nick1 = NULL;
if(paramsIn->nick2)
{
paramsOut->nick2 = goastrdup(paramsIn->nick2);
if(!paramsOut->nick2)
{
gsifree(paramsOut->nick1);
return PEERFalse;
}
}
else
paramsOut->nick2 = NULL;
return PEERTrue;
}
static void piCrossPingFree(void * params_)
{
piCrossPingParams * params = (piCrossPingParams *)params_;
assert(params);
gsifree(params->nick1);
gsifree(params->nick2);
}
static void piCrossPingCall(PEER peer, piCallbackData * data)
{
piCrossPingParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_CROSS_PING_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerCrossPingCallback)data->callback)(peer, params->nick1, params->nick2, params->crossPing, data->callbackParam);
#else
{
unsigned short* nick1_W = UTF8ToUCS2StringAlloc(params->nick1);
unsigned short* nick2_W = UTF8ToUCS2StringAlloc(params->nick2);
((peerCrossPingCallback)data->callback)(peer, nick1_W, nick2_W, params->crossPing, data->callbackParam);
gsifree(nick1_W);
gsifree(nick2_W);
}
#endif
}
void piAddCrossPingCallback
(
PEER peer,
const char * nick1,
const char * nick2,
int crossPing
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->crossPing)
{
piCrossPingParams params;
params.nick1 = (char *)nick1;
params.nick2 = (char *)nick2;
params.crossPing = crossPing;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->crossPing, callbacks->param, PI_CROSS_PING_CALLBACK, &params, sizeof(piCrossPingParams), -1);
}
}
/* Change Nick.
**************/
typedef struct piChangeNickParams
{
char * oldNick;
char * newNick;
} piChangeNickParams;
static PEERBool piChangeNickCopy(void * paramsOut_, void * paramsIn_)
{
piChangeNickParams * paramsOut = (piChangeNickParams *)paramsOut_;
piChangeNickParams * paramsIn = (piChangeNickParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
if(paramsIn->newNick)
{
paramsOut->newNick = goastrdup(paramsIn->newNick);
if(!paramsOut->newNick)
return PEERFalse;
}
else
paramsOut->newNick = NULL;
if(paramsIn->oldNick)
{
paramsOut->oldNick = goastrdup(paramsIn->oldNick);
if(!paramsOut->oldNick)
{
gsifree(paramsOut->newNick);
return PEERFalse;
}
}
else
paramsOut->oldNick = NULL;
return PEERTrue;
}
static void piChangeNickFree(void * params_)
{
piChangeNickParams * params = (piChangeNickParams *)params_;
assert(params);
gsifree(params->newNick);
gsifree(params->oldNick);
}
static void piChangeNickCall(PEER peer, piCallbackData * data)
{
piChangeNickParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_CHANGE_NICK_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerChangeNickCallback)data->callback)(peer, data->success, params->oldNick, params->newNick, data->callbackParam);
#else
{
unsigned short* oldNick_W = UTF8ToUCS2StringAlloc(params->oldNick);
unsigned short* newNick_W = UTF8ToUCS2StringAlloc(params->newNick);
((peerChangeNickCallback)data->callback)(peer, data->success, oldNick_W, newNick_W, data->callbackParam);
gsifree(oldNick_W);
gsifree(newNick_W);
}
#endif
}
void piAddChangeNickCallback
(
PEER peer,
PEERBool success,
const char * oldNick,
const char * newNick,
peerChangeNickCallback callback,
void * param,
int opID
)
{
piChangeNickParams params;
params.newNick = (char *)newNick;
params.oldNick = (char *)oldNick;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_CHANGE_NICK_CALLBACK, &params, sizeof(piChangeNickParams), opID);
}
/* GlobalKeyChanged.
*******************/
typedef struct piGlobalGlobalKeyChangedParams
{
RoomType roomType;
char * nick;
char * key;
char * value;
} piGlobalKeyChangedParams;
static PEERBool piGlobalKeyChangedCopy(void * paramsOut_, void * paramsIn_)
{
piGlobalKeyChangedParams * paramsOut = (piGlobalKeyChangedParams *)paramsOut_;
piGlobalKeyChangedParams * paramsIn = (piGlobalKeyChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->key)
{
paramsOut->key = goastrdup(paramsIn->key);
if(!paramsOut->key)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->key = NULL;
if(paramsIn->value)
{
paramsOut->value = goastrdup(paramsIn->value);
if(!paramsOut->value)
{
gsifree(paramsOut->nick);
gsifree(paramsOut->key);
return PEERFalse;
}
}
else
paramsOut->value = NULL;
return PEERTrue;
}
static void piGlobalKeyChangedFree(void * params_)
{
piGlobalKeyChangedParams * params = (piGlobalKeyChangedParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->key);
gsifree(params->value);
}
static void piGlobalKeyChangedCall(PEER peer, piCallbackData * data)
{
piGlobalKeyChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GLOBAL_KEY_CHANGED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGlobalKeyChangedCallback)data->callback)(peer, params->nick, params->key, params->value, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* key_W = UTF8ToUCS2StringAlloc(params->key);
unsigned short* value_W = UTF8ToUCS2StringAlloc(params->value);
((peerGlobalKeyChangedCallback)data->callback)(peer, nick_W, key_W, value_W, data->callbackParam);
gsifree(nick_W);
gsifree(key_W);
gsifree(value_W);
}
#endif
}
void piAddGlobalKeyChangedCallback
(
PEER peer,
const char * nick,
const char * key,
const char * value
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->globalKeyChanged)
{
piGlobalKeyChangedParams params;
params.nick = (char *)nick;
params.key = (char *)key;
params.value = (char *)value;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->globalKeyChanged, callbacks->param, PI_GLOBAL_KEY_CHANGED_CALLBACK, &params, sizeof(piGlobalKeyChangedParams), -1);
}
}
/* RoomKeyChanged.
*****************/
typedef struct piRoomKeyChangedParams
{
RoomType roomType;
char * nick;
char * key;
char * value;
} piRoomKeyChangedParams;
static PEERBool piRoomKeyChangedCopy(void * paramsOut_, void * paramsIn_)
{
piRoomKeyChangedParams * paramsOut = (piRoomKeyChangedParams *)paramsOut_;
piRoomKeyChangedParams * paramsIn = (piRoomKeyChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
if(paramsIn->key)
{
paramsOut->key = goastrdup(paramsIn->key);
if(!paramsOut->key)
{
gsifree(paramsOut->nick);
return PEERFalse;
}
}
else
paramsOut->key = NULL;
if(paramsIn->value)
{
paramsOut->value = goastrdup(paramsIn->value);
if(!paramsOut->value)
{
gsifree(paramsOut->nick);
gsifree(paramsOut->key);
return PEERFalse;
}
}
else
paramsOut->value = NULL;
return PEERTrue;
}
static void piRoomKeyChangedFree(void * params_)
{
piRoomKeyChangedParams * params = (piRoomKeyChangedParams *)params_;
assert(params);
gsifree(params->nick);
gsifree(params->key);
gsifree(params->value);
}
static void piRoomKeyChangedCall(PEER peer, piCallbackData * data)
{
piRoomKeyChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_ROOM_KEY_CHANGED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerRoomKeyChangedCallback)data->callback)(peer, params->roomType, params->nick, params->key, params->value, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short* key_W = UTF8ToUCS2StringAlloc(params->key);
unsigned short* value_W = UTF8ToUCS2StringAlloc(params->value);
((peerRoomKeyChangedCallback)data->callback)(peer, params->roomType, nick_W, key_W, value_W, data->callbackParam);
gsifree(nick_W);
gsifree(key_W);
gsifree(value_W);
}
#endif
}
void piAddRoomKeyChangedCallback
(
PEER peer,
RoomType roomType,
const char * nick,
const char * key,
const char * value
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->roomKeyChanged)
{
piRoomKeyChangedParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.key = (char *)key;
params.value = (char *)value;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->roomKeyChanged, callbacks->param, PI_ROOM_KEY_CHANGED_CALLBACK, &params, sizeof(piRoomKeyChangedParams), -1);
}
}
/* GetGlobalKeys.
****************/
typedef struct piGetGlobalKeysParams
{
char * nick;
int num;
char ** keys;
char ** values;
} piGetGlobalKeysParams;
static PEERBool piGetGlobalKeysCopy(void * paramsOut_, void * paramsIn_)
{
int i;
int num;
PEERBool success = PEERTrue;
piGetGlobalKeysParams * paramsOut = (piGetGlobalKeysParams *)paramsOut_;
piGetGlobalKeysParams * paramsIn = (piGetGlobalKeysParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
memset(paramsOut, 0, sizeof(piGetGlobalKeysParams));
num = paramsOut->num = paramsIn->num;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
success = PEERFalse;
}
else
paramsOut->nick = NULL;
if(success && num)
{
paramsOut->keys = (char **)gsimalloc(sizeof(char *) * num);
if(!paramsOut->keys)
success = PEERFalse;
else
memset(paramsOut->keys, 0, sizeof(char *) * num);
}
if(success && num && paramsIn->values)
{
paramsOut->values = (char **)gsimalloc(sizeof(char *) * num);
if(!paramsOut->values)
success = PEERFalse;
else
memset(paramsOut->values, 0, sizeof(char *) * num);
}
if(success && num && paramsIn->values)
{
for(i = 0 ; success && (i < num) ; i++)
{
paramsOut->keys[i] = goastrdup(paramsIn->keys[i]);
if(!paramsOut->keys[i])
success = PEERFalse;
else
{
paramsOut->values[i] = goastrdup(paramsIn->values[i]);
if(!paramsOut->values[i])
success = PEERFalse;
}
}
}
if(!success)
{
gsifree(paramsOut->nick);
for(i = 0 ; i < num ; i++)
{
if(paramsOut->keys)
gsifree(paramsOut->keys[i]);
if(paramsOut->values)
gsifree(paramsOut->values[i]);
}
gsifree(paramsOut->keys);
gsifree(paramsOut->values);
}
return success;
}
static void piGetGlobalKeysFree(void * params_)
{
int i;
piGetGlobalKeysParams * params = (piGetGlobalKeysParams *)params_;
assert(params);
gsifree(params->nick);
for(i = 0 ; i < params->num ; i++)
{
gsifree(params->keys[i]);
if(params->values)
gsifree(params->values[i]);
}
gsifree(params->keys);
gsifree(params->values);
}
static void piGetGlobalKeysCall(PEER peer, piCallbackData * data)
{
piGetGlobalKeysParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GET_GLOBAL_KEYS_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGetGlobalKeysCallback)data->callback)(peer, data->success, params->nick, params->num, (const char **)params->keys, (const char **)params->values, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short** keys_W = UTF8ToUCS2StringArrayAlloc((const UTF8String *)params->keys, params->num);
unsigned short** values_W = UTF8ToUCS2StringArrayAlloc((const UTF8String *)params->values, params->num);
int i;
((peerGetGlobalKeysCallback)data->callback)(peer, data->success, nick_W, params->num, (const unsigned short**)keys_W, (const unsigned short**)values_W, data->callbackParam);
gsifree(nick_W);
for (i=0; i < params->num; i++)
{
gsifree(keys_W[i]);
if (values_W != NULL) // may be a NULL when getting keys for "*"
gsifree(values_W[i]);
}
gsifree(keys_W);
gsifree(values_W);
}
#endif
}
void piAddGetGlobalKeysCallback
(
PEER peer,
PEERBool success,
const char * nick,
int num,
const char ** keys,
const char ** values,
peerGetGlobalKeysCallback callback,
void * param,
int opID
)
{
piGetGlobalKeysParams params;
params.nick = (char *)nick;
params.num = num;
params.keys = (char **)keys;
params.values = (char **)values;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_GET_GLOBAL_KEYS_CALLBACK, &params, sizeof(piGetGlobalKeysParams), opID);
}
/* GetRoomKeys.
****************/
typedef struct piGetRoomKeysParams
{
RoomType roomType;
char * nick;
int num;
char ** keys;
char ** values;
} piGetRoomKeysParams;
static PEERBool piGetRoomKeysCopy(void * paramsOut_, void * paramsIn_)
{
int i;
int num;
PEERBool success = PEERTrue;
piGetRoomKeysParams * paramsOut = (piGetRoomKeysParams *)paramsOut_;
piGetRoomKeysParams * paramsIn = (piGetRoomKeysParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
memset(paramsOut, 0, sizeof(piGetRoomKeysParams));
num = paramsOut->num = paramsIn->num;
paramsOut->roomType = paramsIn->roomType;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
success = PEERFalse;
}
else
paramsOut->nick = NULL;
if(success && num)
{
paramsOut->keys = (char **)gsimalloc(sizeof(char *) * num);
if(!paramsOut->keys)
success = PEERFalse;
else
memset(paramsOut->keys, 0, sizeof(char *) * num);
}
if(success && num && paramsIn->values)
{
paramsOut->values = (char **)gsimalloc(sizeof(char *) * num);
if(!paramsOut->values)
success = PEERFalse;
else
memset(paramsOut->values, 0, sizeof(char *) * num);
}
if(success && num && paramsIn->values)
{
for(i = 0 ; success && (i < num) ; i++)
{
paramsOut->keys[i] = goastrdup(paramsIn->keys[i]);
if(!paramsOut->keys[i])
success = PEERFalse;
else if(paramsOut->values)
{
paramsOut->values[i] = goastrdup(paramsIn->values[i]);
if(!paramsOut->values[i])
success = PEERFalse;
}
}
}
if(!success)
{
gsifree(paramsOut->nick);
for(i = 0 ; i < num ; i++)
{
if(paramsOut->keys)
gsifree(paramsOut->keys[i]);
if(paramsOut->values)
gsifree(paramsOut->values[i]);
}
gsifree(paramsOut->keys);
gsifree(paramsOut->values);
}
return success;
}
static void piGetRoomKeysFree(void * params_)
{
int i;
piGetRoomKeysParams * params = (piGetRoomKeysParams *)params_;
assert(params);
gsifree(params->nick);
for(i = 0 ; i < params->num ; i++)
{
gsifree(params->keys[i]);
if(params->values)
gsifree(params->values[i]);
}
gsifree(params->keys);
gsifree(params->values);
}
static void piGetRoomKeysCall(PEER peer, piCallbackData * data)
{
piGetRoomKeysParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_GET_ROOM_KEYS_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerGetRoomKeysCallback)data->callback)(peer, data->success, params->roomType, params->nick, params->num, params->keys, params->values, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
unsigned short** keys_W = UTF8ToUCS2StringArrayAlloc((const UTF8String *)params->keys, params->num);
unsigned short** values_W = UTF8ToUCS2StringArrayAlloc((const UTF8String *)params->values, params->num);
int i;
((peerGetRoomKeysCallback)data->callback)(peer, data->success, params->roomType, nick_W, params->num, keys_W, values_W, data->callbackParam);
gsifree(nick_W);
for (i=0; i < params->num; i++)
{
gsifree(keys_W[i]);
if (values_W != NULL) // may be a NULL when getting keys for "*"
gsifree(values_W[i]);
}
gsifree(keys_W);
gsifree(values_W);
}
#endif
}
void piAddGetRoomKeysCallback
(
PEER peer,
PEERBool success,
RoomType roomType,
const char * nick,
int num,
const char ** keys,
const char ** values,
peerGetRoomKeysCallback callback,
void * param,
int opID
)
{
piGetRoomKeysParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.num = num;
params.keys = (char **)keys;
params.values = (char **)values;
piAddCallback(peer, success, (PEERCBType)callback, param, PI_GET_ROOM_KEYS_CALLBACK, &params, sizeof(piGetRoomKeysParams), opID);
}
/* PlayerFlagsChanged.
*********************/
typedef struct piPlayerFlagsChangedParams
{
RoomType roomType;
char * nick;
int oldFlags;
int newFlags;
} piPlayerFlagsChangedParams;
static PEERBool piPlayerFlagsChangedCopy(void * paramsOut_, void * paramsIn_)
{
piPlayerFlagsChangedParams * paramsOut = (piPlayerFlagsChangedParams *)paramsOut_;
piPlayerFlagsChangedParams * paramsIn = (piPlayerFlagsChangedParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->roomType = paramsIn->roomType;
paramsOut->newFlags = paramsIn->newFlags;
paramsOut->oldFlags = paramsIn->oldFlags;
if(paramsIn->nick)
{
paramsOut->nick = goastrdup(paramsIn->nick);
if(!paramsOut->nick)
return PEERFalse;
}
else
paramsOut->nick = NULL;
return PEERTrue;
}
static void piPlayerFlagsChangedFree(void * params_)
{
piPlayerFlagsChangedParams * params = (piPlayerFlagsChangedParams *)params_;
assert(params);
gsifree(params->nick);
}
static void piPlayerFlagsChangedCall(PEER peer, piCallbackData * data)
{
piPlayerFlagsChangedParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_PLAYER_FLAGS_CHANGED_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerPlayerFlagsChangedCallback)data->callback)(peer, params->roomType, params->nick, params->oldFlags, params->newFlags, data->callbackParam);
#else
{
unsigned short* nick_W = UTF8ToUCS2StringAlloc(params->nick);
((peerPlayerFlagsChangedCallback)data->callback)(peer, params->roomType, nick_W, params->oldFlags, params->newFlags, data->callbackParam);
gsifree(nick_W);
}
#endif
}
void piAddPlayerFlagsChangedCallback
(
PEER peer,
RoomType roomType,
const char * nick,
int oldFlags,
int newFlags
)
{
PEERCallbacks * callbacks;
PEER_CONNECTION;
callbacks = &connection->callbacks;
if(callbacks->playerFlagsChanged)
{
piPlayerFlagsChangedParams params;
params.roomType = roomType;
params.nick = (char *)nick;
params.oldFlags = oldFlags;
params.newFlags = newFlags;
piAddCallback(peer, PEERTrue, (PEERCBType)callbacks->playerFlagsChanged, callbacks->param, PI_PLAYER_FLAGS_CHANGED_CALLBACK, &params, sizeof(piPlayerFlagsChangedParams), -1);
}
}
/* Authenticate CD Key.
**********************/
typedef struct piAuthenticateCDKeyParams
{
int result;
char * message;
} piAuthenticateCDKeyParams;
static PEERBool piAuthenticateCDKeyCopy(void * paramsOut_, void * paramsIn_)
{
piAuthenticateCDKeyParams * paramsOut = (piAuthenticateCDKeyParams *)paramsOut_;
piAuthenticateCDKeyParams * paramsIn = (piAuthenticateCDKeyParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->result = paramsIn->result;
if(paramsIn->message)
{
paramsOut->message = goastrdup(paramsIn->message);
if(!paramsOut->message)
return PEERFalse;
}
else
paramsOut->message = NULL;
return PEERTrue;
}
static void piAuthenticateCDKeyFree(void * params_)
{
piAuthenticateCDKeyParams * params = (piAuthenticateCDKeyParams *)params_;
assert(params);
gsifree(params->message);
}
static void piAuthenticateCDKeyCall(PEER peer, piCallbackData * data)
{
piAuthenticateCDKeyParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_AUTHENTICATE_CDKEY_CALLBACK);
params = data->params;
#ifndef GSI_UNICODE
((peerAuthenticateCDKeyCallback)data->callback)(peer, params->result, params->message, data->callbackParam);
#else
{
unsigned short* message_W = UTF8ToUCS2StringAlloc(params->message);
((peerAuthenticateCDKeyCallback)data->callback)(peer, params->result, message_W, data->callbackParam);
gsifree(message_W);
}
#endif
}
void piAddAuthenticateCDKeyCallback
(
PEER peer,
int result,
const char * message,
peerAuthenticateCDKeyCallback callback,
void * param,
int opID
)
{
piAuthenticateCDKeyParams params;
params.result = result;
params.message = (char *)message;
piAddCallback(peer, PEERTrue, (PEERCBType)callback, param, PI_AUTHENTICATE_CDKEY_CALLBACK, &params, sizeof(piAuthenticateCDKeyParams), opID);
}
/* AutoMatch Status.
*******************/
typedef struct piAutoMatchStatusParams
{
PEERAutoMatchStatus status;
} piAutoMatchStatusParams;
static PEERBool piAutoMatchStatusCopy(void * paramsOut_, void * paramsIn_)
{
piAutoMatchStatusParams * paramsOut = (piAutoMatchStatusParams *)paramsOut_;
piAutoMatchStatusParams * paramsIn = (piAutoMatchStatusParams *)paramsIn_;
assert(paramsOut);
assert(paramsIn);
paramsOut->status = paramsIn->status;
return PEERTrue;
}
static void piAutoMatchStatusFree(void * params_)
{
piAutoMatchStatusParams * params = (piAutoMatchStatusParams *)params_;
assert(params);
GSI_UNUSED(params);
}
static void piAutoMatchStatusCall(PEER peer, piCallbackData * data)
{
piAutoMatchStatusParams * params;
assert(data);
assert(data->callback);
assert(data->params);
assert(data->type == PI_AUTO_MATCH_STATUS_CALLBACK);
params = data->params;
((peerAutoMatchStatusCallback)data->callback)(peer, params->status, data->callbackParam);
}
void piAddAutoMatchStatusCallback
(
PEER peer
)
{
piAutoMatchStatusParams params;
piOperation * operation;
PEER_CONNECTION;
operation = connection->autoMatchOperation;
if(!operation || !operation->callback)
return;
params.status = connection->autoMatchStatus;
piAddCallback(peer, PEERTrue, operation->callback, operation->callbackParam, PI_AUTO_MATCH_STATUS_CALLBACK, &params, sizeof(piAutoMatchStatusParams), operation->ID);
}
/* AutoMatch Rate.
*****************/
int piCallAutoMatchRateCallback
(
PEER peer,
SBServer server
)
{
piOperation * operation;
PEER_CONNECTION;
operation = connection->autoMatchOperation;
if(!operation || !operation->callback2)
return 0;
return ((peerAutoMatchRateCallback)connection->autoMatchOperation->callback2)(peer, server, operation->callbackParam);
}
/************
** GLOBALS **
************/
static const piCallbackFuncs callbackFuncs[] =
{
{
PI_CONNECT_CALLBACK,
piConnectCopy,
piConnectFree,
piConnectCall
},
{
PI_JOIN_ROOM_CALLBACK,
piJoinRoomCopy,
piJoinRoomFree,
piJoinRoomCall
},
{
PI_LIST_GROUP_ROOMS_CALLBACK,
piListGroupRoomsCopy,
piListGroupRoomsFree,
piListGroupRoomsCall
},
{
PI_LISTING_GAMES_CALLBACK,
piListingGamesCopy,
piListingGamesFree,
piListingGamesCall
},
{
PI_NICK_ERROR_CALLBACK,
piNickErrorCopy,
piNickErrorFree,
piNickErrorCall
},
{
PI_ENUM_PLAYERS_CALLBACK,
piEnumPlayersCopy,
piEnumPlayersFree,
piEnumPlayersCall
},
{
PI_GET_PLAYER_INFO_CALLBACK,
piGetPlayerInfoCopy,
piGetPlayerInfoFree,
piGetPlayerInfoCall
},
{
PI_GET_PLAYER_PROFILE_ID_CALLBACK,
piGetPlayerProfileIDCopy,
piGetPlayerProfileIDFree,
piGetPlayerProfileIDCall
},
{
PI_GET_PLAYER_IP_CALLBACK,
piGetPlayerIPCopy,
piGetPlayerIPFree,
piGetPlayerIPCall
},
{
PI_ROOM_MESSAGE_CALLBACK,
piRoomMessageCopy,
piRoomMessageFree,
piRoomMessageCall
},
{
PI_ROOM_UTM_CALLBACK,
piRoomUTMCopy,
piRoomUTMFree,
piRoomUTMCall
},
{
PI_ROOM_NAME_CHANGED_CALLBACK,
piRoomNameChangedCopy,
piRoomNameChangedFree,
piRoomNameChangedCall
},
{
PI_ROOM_MODE_CHANGED_CALLBACK,
piRoomModeChangedCopy,
piRoomModeChangedFree,
piRoomModeChangedCall
},
{
PI_PLAYER_MESSAGE_CALLBACK,
piPlayerMessageCopy,
piPlayerMessageFree,
piPlayerMessageCall
},
{
PI_PLAYER_UTM_CALLBACK,
piPlayerUTMCopy,
piPlayerUTMFree,
piPlayerUTMCall
},
{
PI_READY_CHANGED_CALLBACK,
piReadyChangedCopy,
piReadyChangedFree,
piReadyChangedCall
},
{
PI_GAME_STARTED_CALLBACK,
piGameStartedCopy,
piGameStartedFree,
piGameStartedCall
},
{
PI_PLAYER_JOINED_CALLBACK,
piPlayerJoinedCopy,
piPlayerJoinedFree,
piPlayerJoinedCall
},
{
PI_PLAYER_LEFT_CALLBACK,
piPlayerLeftCopy,
piPlayerLeftFree,
piPlayerLeftCall
},
{
PI_KICKED_CALLBACK,
piKickedCopy,
piKickedFree,
piKickedCall
},
{
PI_NEW_PLAYER_LIST_CALLBACK,
piNewPlayerListCopy,
piNewPlayerListFree,
piNewPlayerListCall
},
{
PI_PLAYER_CHANGED_NICK_CALLBACK,
piPlayerChangedNickCopy,
piPlayerChangedNickFree,
piPlayerChangedNickCall
},
{
PI_PLAYER_INFO_CALLBACK,
piPlayerInfoCopy,
piPlayerInfoFree,
piPlayerInfoCall
},
{
PI_DISCONNECTED_CALLBACK,
piDisconnectedCopy,
piDisconnectedFree,
piDisconnectedCall
},
{
PI_PING_CALLBACK,
piPingCopy,
piPingFree,
piPingCall
},
{
PI_CROSS_PING_CALLBACK,
piCrossPingCopy,
piCrossPingFree,
piCrossPingCall
},
{
PI_CHANGE_NICK_CALLBACK,
piChangeNickCopy,
piChangeNickFree,
piChangeNickCall
},
{
PI_GLOBAL_KEY_CHANGED_CALLBACK,
piGlobalKeyChangedCopy,
piGlobalKeyChangedFree,
piGlobalKeyChangedCall
},
{
PI_ROOM_KEY_CHANGED_CALLBACK,
piRoomKeyChangedCopy,
piRoomKeyChangedFree,
piRoomKeyChangedCall
},
{
PI_GET_GLOBAL_KEYS_CALLBACK,
piGetGlobalKeysCopy,
piGetGlobalKeysFree,
piGetGlobalKeysCall
},
{
PI_GET_ROOM_KEYS_CALLBACK,
piGetRoomKeysCopy,
piGetRoomKeysFree,
piGetRoomKeysCall
},
{
PI_PLAYER_FLAGS_CHANGED_CALLBACK,
piPlayerFlagsChangedCopy,
piPlayerFlagsChangedFree,
piPlayerFlagsChangedCall
},
{
PI_AUTHENTICATE_CDKEY_CALLBACK,
piAuthenticateCDKeyCopy,
piAuthenticateCDKeyFree,
piAuthenticateCDKeyCall
},
{
PI_AUTO_MATCH_STATUS_CALLBACK,
piAutoMatchStatusCopy,
piAutoMatchStatusFree,
piAutoMatchStatusCall
},
{
PI_NUM_CALLBACK_TYPES,
NULL,
NULL,
NULL
}
};
/**************
** FUNCTIONS **
**************/
static void piCallbackListFree(void *elem1)
{
piCallbackData * data = (piCallbackData *)elem1;
//ASSERT_DATA(data);
// Call the gsifree func.
//////////////////////
callbackFuncs[data->type].gsifree(data->params);
// Cleanup the callback data.
/////////////////////////////
#ifdef GSI_MANIC_DEBUG
// Set the data to a fill value so we catch the overwrite
memset(data->params, 0xea, sizeof(data->params));
#endif
gsifree(data->params);
}
PEERBool piCallbacksInit
(
PEER peer
)
{
PEER_CONNECTION;
#ifdef _DEBUG
{
// Consistency check.
/////////////////////
int i;
for(i = 0 ; i <= PI_NUM_CALLBACK_TYPES ; i++)
assert(callbackFuncs[i].type == i);
}
#endif
// No callbacks yet.
////////////////////
connection->callbacksQueued = 0;
connection->callbacksCalled = 0;
connection->callbackDepth = 0;
// Init the list.
/////////////////
connection->callbackList = ArrayNew(sizeof(piCallbackData), 0, piCallbackListFree);
if(!connection->callbackList)
return PEERFalse;
return PEERTrue;
}
void piCallbacksCleanup
(
PEER peer
)
{
PEER_CONNECTION;
// gsifree the callback list.
//////////////////////////
if(connection->callbackList)
ArrayFree(connection->callbackList);
}
#ifdef GSI_MANIC_DEBUG
#include "stdio.h"
#endif
static void piCallCallback(PEER peer, piCallbackData * data, int index)
{
PEER_CONNECTION;
// In the call.
///////////////
data->inCall = PEERTrue;
connection->callbackDepth++;
// Call it.
///////////
callbackFuncs[data->type].call(peer, data);
// Out of the call.
///////////////////
data->inCall = PEERFalse;
connection->callbackDepth--;
// One more called.
///////////////////
connection->callbacksCalled++;
// gsifree it.
///////////
ArrayDeleteAt(connection->callbackList, index);
}
void piCallbacksThink
(
PEER peer,
int blockingID
)
{
int index;
int len;
piCallbackData * data;
PEER_CONNECTION;
assert(blockingID >= -1);
// Blocking call?
/////////////////
if(blockingID != -1)
{
// How many?
////////////
len = ArrayLength(connection->callbackList);
assert(len >= 0);
// Check if this callback is finished.
//////////////////////////////////////
for(index = 0 ; index < len ; index++)
{
// Get the nth element.
///////////////////////
data = (piCallbackData *)ArrayNth(connection->callbackList, index);
assert(data);
// Check the ID and specifically for disconnect.
////////////////////////////////////////////////
if((data->ID == blockingID) || (data->type == PI_DISCONNECTED_CALLBACK))
{
// Call it.
///////////
piCallCallback(peer, data, index);
break;
}
}
}
else
{
int numInCalls = 0;
while(ArrayLength(connection->callbackList) > numInCalls)
{
// Get the callback data.
/////////////////////////
data = (piCallbackData *)ArrayNth(connection->callbackList, numInCalls);
assert(data);
// Are we already in this call? (how philosophical)
///////////////////////////////////////////////////
if(data->inCall)
{
numInCalls++;
}
else
{
// Call it.
///////////
piCallCallback(peer, data, numInCalls);
}
}
}
}
static int piAddCallback
(
PEER peer,
PEERBool success,
PEERCBType callback,
void * param,
piCallbackType type,
void * paramsIn,
size_t paramsSize,
int opID
)
{
piCallbackData data;
void * paramsOut;
PEER_CONNECTION;
assert(callback);
//assert(type >= 0);
assert(type < PI_NUM_CALLBACK_TYPES);
assert(paramsIn);
assert(paramsSize > 0);
// If no callback, nothing to do.
/////////////////////////////////
if(!callback)
return -1;
// Allocate the output struct.
//////////////////////////////
paramsOut = gsimalloc(paramsSize);
if(!paramsOut)
return -1;
// Zero it.
///////////
memset(paramsOut, 0, paramsSize);
// Copy the input to the output.
////////////////////////////////
if(!callbackFuncs[type].copy(paramsOut, paramsIn))
{
assert(0);
gsifree(paramsOut);
return -1;
}
// Fill in the data.
////////////////////
data.type = type;
data.success = success;
data.callback = callback;
data.callbackParam = param;
data.params = paramsOut;
data.ID = opID;
data.inCall = PEERFalse;
// Add it to the list.
//////////////////////
ArrayAppend(connection->callbackList, &data);
connection->callbacksQueued++;
return data.ID;
}
static int GS_STATIC_CALLBACK piIsCallbackFinishedCompareCallback
(
const void *elem1,
const void *elem2
)
{
piCallbackData * data1 = (piCallbackData *)elem1;
piCallbackData * data2 = (piCallbackData *)elem2;
assert(data1);
assert(data2);
return (data1->ID - data2->ID);
}
PEERBool piIsCallbackFinished
(
PEER peer,
int opID
)
{
int index;
piCallbackData data;
PEER_CONNECTION;
// Search for it.
/////////////////
data.ID = opID;
index = ArraySearch(connection->callbackList, &data, piIsCallbackFinishedCompareCallback, 0, 0);
return (index == NOT_FOUND)?PEERTrue:PEERFalse;
}
void piClearCallbacks
(
PEER peer,
piCallbackType type
)
{
piCallbackData * data;
int len;
int i;
PEER_CONNECTION;
len = ArrayLength(connection->callbackList);
for(i = (len - 1) ; i >= 0 ; i--)
{
data = (piCallbackData *)ArrayNth(connection->callbackList, i);
if(data->type == type)
ArrayDeleteAt(connection->callbackList, i);
}
}
void piClearListingGameServerCallbacks(PEER peer, SBServer server)
{
piCallbackData * data;
piListingGamesParams * params;
int len;
int i;
PEER_CONNECTION;
len = ArrayLength(connection->callbackList);
for(i = (len - 1) ; i >= 0 ; i--)
{
data = (piCallbackData *)ArrayNth(connection->callbackList, i);
if(data->type == PI_LISTING_GAMES_CALLBACK)
{
params = (piListingGamesParams *)data->params;
if(params->server == server)
ArrayDeleteAt(connection->callbackList, i);
}
}
}