109 lines
3.5 KiB
C
109 lines
3.5 KiB
C
// 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 <memory.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#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);
|
|
}
|