// LEMONBBS MODULES: CHAT // to enable the text chat module, first initialize the module using the initChat() method. // then, set a name for every channel using the setChannelName() method. #include #include #include #include "chat.h" struct Channel* channelList; unsigned int channelListLength; unsigned int getChannelCount() { return channelListLength; } void initChat(unsigned int channelCount) { unsigned int allocSize = channelCount*sizeof(struct Channel); channelList = malloc(allocSize); memset(channelList, 0, allocSize); for (int i = 0; i < channelCount; ++i) { pthread_mutex_init(&channelList[i].clientsLock, NULL); } channelListLength = channelCount; } // warning: memory unsafe. check string length first. void setChannelName(int channelId, const char* name) { strcpy(channelList[channelId].name, name); } const char* getChannelName(size_t channelId) { return channelList[channelId].name; } int isUserInChat(size_t channelId, int64_t userId) { pthread_mutex_lock(&channelList[channelId].clientsLock); int result = 0; for (int i = 0; i < USERS_PER_CHANNEL; ++i) { struct Connection* currIter = channelList[channelId].clients[i]; if (currIter == NULL) { continue; } if (currIter->userId == userId) { result = 1; break; } } pthread_mutex_unlock(&channelList[channelId].clientsLock); return result; } int addChatUser(size_t channelId, struct Connection* userConnection) { pthread_mutex_lock(&channelList[channelId].clientsLock); for (int i = 0; i < USERS_PER_CHANNEL; ++i) { struct Connection** currIter = channelList[channelId].clients + i; if (*currIter == NULL) { *currIter = userConnection; pthread_mutex_unlock(&channelList[channelId].clientsLock); return 1; } } pthread_mutex_unlock(&channelList[channelId].clientsLock); return 0; } int removeChatUser(size_t channelId, int64_t userId) { pthread_mutex_lock(&channelList[channelId].clientsLock); for (int i = 0; i < USERS_PER_CHANNEL; ++i) { struct Connection** currIter = channelList[channelId].clients + i; if (*currIter == NULL) { continue; } if ((*currIter)->userId == userId) { *currIter = NULL; pthread_mutex_unlock(&channelList[channelId].clientsLock); return 1; } } pthread_mutex_unlock(&channelList[channelId].clientsLock); return 0; } int countUsers(size_t channelId) { pthread_mutex_lock(&channelList[channelId].clientsLock); int result = 0; for (int i = 0; i < USERS_PER_CHANNEL; ++i) { struct Connection* currIter = channelList[channelId].clients[i]; if (currIter == NULL) { continue; } else { result++; } } pthread_mutex_unlock(&channelList[channelId].clientsLock); return result; } void broadcastString(size_t channelId, const char* message, size_t messageLength) { pthread_mutex_lock(&channelList[channelId].clientsLock); for (int i = 0; i < USERS_PER_CHANNEL; ++i) { struct Connection* currIter = channelList[channelId].clients[i]; if (currIter != NULL) { lolib_writeSocket(&currIter->socket, message, messageLength); } } pthread_mutex_unlock(&channelList[channelId].clientsLock); }