Using enet to track client connections. Fixed console message queue.
This commit is contained in:
parent
89a266165f
commit
ae1bb486cd
6 changed files with 56 additions and 41 deletions
|
@ -448,6 +448,7 @@ static void processNetworkEvent(void) {
|
||||||
while (enet_host_service(_host, event, 1)) {
|
while (enet_host_service(_host, event, 1)) {
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case ENET_EVENT_TYPE_CONNECT:
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
|
logWrite("Connected!\n");
|
||||||
_connected = 1;
|
_connected = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -458,6 +459,7 @@ static void processNetworkEvent(void) {
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||||
|
logWrite("Disconnected!\n");
|
||||||
_connected = 0;
|
_connected = 0;
|
||||||
_modemCommandMode = 1;
|
_modemCommandMode = 1;
|
||||||
comAddToBuffer("\13NO CARRIER\13", 12);
|
comAddToBuffer("\13NO CARRIER\13", 12);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
* - Find a light grey to replace white widget data areas
|
* - Find a light grey to replace white widget data areas
|
||||||
* - No thumb in listbox scrollbar
|
* - No thumb in listbox scrollbar
|
||||||
* - Layout container widgets!
|
* - Layout container widgets!
|
||||||
|
* - Fix variable names. something = local; _something = file global; __something = project global
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,20 @@
|
||||||
|
|
||||||
void *clientThread(void *data) {
|
void *clientThread(void *data) {
|
||||||
|
|
||||||
ClientThreadT *client = (ClientThreadT *)data;
|
ENetPeer *peer = (ENetPeer *)data;
|
||||||
|
ClientThreadT *client = (ClientThreadT *)peer->data;
|
||||||
ENetPacket *packet = NULL;
|
ENetPacket *packet = NULL;
|
||||||
int32_t r;
|
int32_t r;
|
||||||
|
|
||||||
// Send service banner.
|
// Send service banner.
|
||||||
packet = enet_packet_create("KPMPGSMKII\r", 11, ENET_PACKET_FLAG_RELIABLE);
|
packet = enet_packet_create("KPMPGSMKII\r", 11, ENET_PACKET_FLAG_RELIABLE);
|
||||||
r = enet_peer_send(client->peer, 0, packet);
|
r = enet_peer_send(peer, 0, packet);
|
||||||
|
|
||||||
consoleMessageQueue("Packet: %p %d\n", packet, r);
|
consoleMessageQueue("Packet: %p %d\n", packet, r);
|
||||||
|
|
||||||
|
while (client->running) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ typedef struct ClientThreadS {
|
||||||
uint64_t threadIndex;
|
uint64_t threadIndex;
|
||||||
pthread_t threadHandle;
|
pthread_t threadHandle;
|
||||||
pthread_attr_t threadAttributes;
|
pthread_attr_t threadAttributes;
|
||||||
ENetPeer *peer;
|
|
||||||
uint8_t running;
|
uint8_t running;
|
||||||
} ClientThreadT;
|
} ClientThreadT;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ void consoleMessageQueue(const char *message, ...) {
|
||||||
arrput(_consoleMessageQueue, newMessage);
|
arrput(_consoleMessageQueue, newMessage);
|
||||||
pthread_mutex_unlock(&_messageQueueMutex);
|
pthread_mutex_unlock(&_messageQueueMutex);
|
||||||
|
|
||||||
free(newMessage);
|
// Do not free newMessage - we do it when we dequeue the message.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,10 +66,12 @@ void consoleRun(void) {
|
||||||
uint8_t commandOk = 0;
|
uint8_t commandOk = 0;
|
||||||
struct timespec remaining = { 0, 0 };
|
struct timespec remaining = { 0, 0 };
|
||||||
struct timespec sleepTime = { 0, 1000000000/4 };
|
struct timespec sleepTime = { 0, 1000000000/4 };
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
if (pthread_mutex_init(&_messageQueueMutex, NULL)) utilDie("Unable to create console message queue mutex.\n");
|
if (pthread_mutex_init(&_messageQueueMutex, NULL)) utilDie("Unable to create console message queue mutex.\n");
|
||||||
|
|
||||||
terminalModeConioSet();
|
terminalModeConioSet();
|
||||||
|
|
||||||
while (_running) {
|
while (_running) {
|
||||||
|
|
||||||
if (kbhit()) {
|
if (kbhit()) {
|
||||||
|
@ -89,6 +91,16 @@ void consoleRun(void) {
|
||||||
// Backspace
|
// Backspace
|
||||||
case 8:
|
case 8:
|
||||||
case 127:
|
case 127:
|
||||||
|
if (commandIndex > 0) {
|
||||||
|
commandIndex--;
|
||||||
|
command[commandIndex] = 0;
|
||||||
|
printf("%c %c", 8, 8);
|
||||||
|
if (commandIndex == 0) {
|
||||||
|
commandEntering = 0;
|
||||||
|
// Erase prompt, too.
|
||||||
|
printf("%c %c", 8, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ESC
|
// ESC
|
||||||
|
@ -150,13 +162,20 @@ void consoleRun(void) {
|
||||||
pthread_mutex_lock(&_messageQueueMutex);
|
pthread_mutex_lock(&_messageQueueMutex);
|
||||||
if (arrlenu(_consoleMessageQueue) > 0) {
|
if (arrlenu(_consoleMessageQueue) > 0) {
|
||||||
sendToConsole("%s", _consoleMessageQueue[0]);
|
sendToConsole("%s", _consoleMessageQueue[0]);
|
||||||
|
free(_consoleMessageQueue[0]);
|
||||||
arrdel(_consoleMessageQueue, 0);
|
arrdel(_consoleMessageQueue, 0);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&_messageQueueMutex);
|
pthread_mutex_unlock(&_messageQueueMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminalModeOriginalSet();
|
|
||||||
|
|
||||||
|
// Anything left in the message queue?
|
||||||
|
for (i=0; i<arrlenu(_consoleMessageQueue); i++) {
|
||||||
|
free(_consoleMessageQueue[i]);
|
||||||
|
}
|
||||||
|
arrfree(_consoleMessageQueue);
|
||||||
|
|
||||||
|
terminalModeOriginalSet();
|
||||||
pthread_mutex_destroy(&_messageQueueMutex);
|
pthread_mutex_destroy(&_messageQueueMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,6 @@ static void configWrite(char *file) {
|
||||||
static void *serverThread(void *data) {
|
static void *serverThread(void *data) {
|
||||||
ENetHost *server = (ENetHost *)data;
|
ENetHost *server = (ENetHost *)data;
|
||||||
ENetEvent event = { 0 };
|
ENetEvent event = { 0 };
|
||||||
ClientThreadT **clientList = NULL;
|
|
||||||
ClientThreadT *client = NULL;
|
ClientThreadT *client = NULL;
|
||||||
uint64_t nextIndex = 0;
|
uint64_t nextIndex = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -119,19 +118,19 @@ static void *serverThread(void *data) {
|
||||||
NEW(ClientThreadT, client);
|
NEW(ClientThreadT, client);
|
||||||
if (!client) utilDie("Unable to allocate new client.\n");
|
if (!client) utilDie("Unable to allocate new client.\n");
|
||||||
client->threadIndex = nextIndex++;
|
client->threadIndex = nextIndex++;
|
||||||
client->peer = event.peer;
|
|
||||||
client->running = 1;
|
client->running = 1;
|
||||||
// Keep our index in the peer data for later.
|
// Keep our client in the peer data for later.
|
||||||
event.peer->data = (void *)client->threadIndex;
|
event.peer->data = (void *)client;
|
||||||
// Make new thread for this client.
|
// Make new thread for this client.
|
||||||
if (pthread_attr_init(&client->threadAttributes) != 0) utilDie("Unable to create client thread attributes.\n");
|
if (pthread_attr_init(&client->threadAttributes) != 0) utilDie("Unable to create client thread attributes.\n");
|
||||||
pthread_attr_setdetachstate(&client->threadAttributes, PTHREAD_CREATE_JOINABLE);
|
pthread_attr_setdetachstate(&client->threadAttributes, PTHREAD_CREATE_JOINABLE);
|
||||||
if (pthread_create(&client->threadHandle, &client->threadAttributes, clientThread, (void *)client) != 0) utilDie("Unable to start client thread.\n");
|
if (pthread_create(&client->threadHandle, &client->threadAttributes, clientThread, (void *)event.peer) != 0) utilDie("Unable to start client thread.\n");
|
||||||
// Add to our client list.
|
|
||||||
arrput(clientList, client);
|
|
||||||
// Tell the console.
|
// Tell the console.
|
||||||
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
||||||
consoleMessageQueue("%ld: %s connected.\n", client->threadIndex, buffer);
|
consoleMessageQueue("%ld: [%s] connected.\n", client->threadIndex, buffer);
|
||||||
|
// Blargh.
|
||||||
|
ENetPacket *packet = enet_packet_create("KPMPGSMKII\r", 11, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(event.peer, 0, packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
|
@ -140,38 +139,28 @@ static void *serverThread(void *data) {
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||||
// Find our client.
|
// Get our client.
|
||||||
for (i=0; i<arrlenu(clientList); i++) {
|
client = (ClientThreadT *)event.peer->data;
|
||||||
if ((uint64_t)event.peer->data == clientList[i]->threadIndex) {
|
|
||||||
// Stop client processing.
|
// Stop client processing.
|
||||||
clientList[i]->running = 0;
|
client->running = 0;
|
||||||
pthread_join(clientList[i]->threadHandle, &status);
|
pthread_join(client->threadHandle, &status);
|
||||||
// Tell the console.
|
// Tell the console.
|
||||||
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
||||||
consoleMessageQueue("%ld: %s disconnected.\n", clientList[i]->threadIndex, buffer);
|
consoleMessageQueue("%ld: [%s] disconnected.\n", client->threadIndex, buffer);
|
||||||
// Delete client.
|
|
||||||
DEL(clientList[i]);
|
|
||||||
// Take it out of the client list.
|
|
||||||
arrdel(clientList, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anyone still running, be rude. Nuke 'em.
|
// Anyone still running, be rude. Nuke 'em.
|
||||||
for (i=0; i<arrlenu(clientList); i++) {
|
for (i=0; i<server->peerCount; i++) {
|
||||||
// Hang up.
|
client = (ClientThreadT *)server->peers[i].data;
|
||||||
enet_peer_reset(clientList[i]->peer);
|
|
||||||
// Stop client processing.
|
// Stop client processing.
|
||||||
clientList[i]->running = 0;
|
client->running = 0;
|
||||||
pthread_join(clientList[i]->threadHandle, &status);
|
pthread_join(client->threadHandle, &status);
|
||||||
// Delete client.
|
// Hang up.
|
||||||
DEL(clientList[i]);
|
enet_peer_reset(&server->peers[i]);
|
||||||
}
|
}
|
||||||
arrfree(clientList);
|
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +182,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
memoryStartup(argv[0]);
|
memoryStartup(argv[0]);
|
||||||
logOpenByHandle(memoryLogHandleGet());
|
logOpenByHandle(memoryLogHandleGet());
|
||||||
logWrite("%s", "Kangaroo Punch MultiPlayer DOS Game Server Mark II\n");
|
logWrite("%s", "Kangaroo Punch MultiPlayer Game Server Mark II\n");
|
||||||
logWrite("%s", "Copyright (C) 2020-2021 Scott Duensing scott@kangaroopunch.com\n\n");
|
logWrite("%s", "Copyright (C) 2020-2021 Scott Duensing scott@kangaroopunch.com\n\n");
|
||||||
configFile = utilAppNameWithNewExtensionGet(argv[0], "ini");
|
configFile = utilAppNameWithNewExtensionGet(argv[0], "ini");
|
||||||
configRead(configFile);
|
configRead(configFile);
|
||||||
|
@ -211,7 +200,7 @@ int main(int argc, char *argv[]) {
|
||||||
address.host = ENET_HOST_ANY;
|
address.host = ENET_HOST_ANY;
|
||||||
address.port = settingsPortNumber;
|
address.port = settingsPortNumber;
|
||||||
server = enet_host_create(&address, /* the address to bind the server host to */
|
server = enet_host_create(&address, /* the address to bind the server host to */
|
||||||
settingsMaxClients, /* allow up to 32 clients and/or outgoing connections */
|
settingsMaxClients, /* allow up to XX clients and/or outgoing connections */
|
||||||
1, /* allow up to 2 channels to be used, 0 and 1 */
|
1, /* allow up to 2 channels to be used, 0 and 1 */
|
||||||
0, /* assume any amount of incoming bandwidth */
|
0, /* assume any amount of incoming bandwidth */
|
||||||
0 /* assume any amount of outgoing bandwidth */
|
0 /* assume any amount of outgoing bandwidth */
|
||||||
|
|
Loading…
Add table
Reference in a new issue