This repository has been archived on 2021-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
lemonbbs/src/chat.c
2021-12-15 18:52:53 +01:00

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);
}