/* * Kangaroo Punch MultiPlayer Game Server Mark II * Copyright (C) 2020-2021 Scott Duensing * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "gui.h" #include "comport.h" #include "config.h" #include "timer.h" #include "runtime.h" #include "network.h" typedef struct NetworkChannelsS { uint8_t key; netPacketHandler value; } NetworkChannelsT; static netPacketHandler *_systemHandlers = NULL; static NetworkChannelsT *_channels = NULL; static uint8_t _netRunning = 0; static uint8_t _netStarted = 0; uint8_t netChannelGet(netPacketHandler handler) { uint8_t channel = 0; uint16_t x = 0; // We reserve 0 for system stuff. // Returning 0 means no channel was found. // Find first unused channel. for (x=1; x<255; x++) { if (hmgeti(_channels, x) < 0) { channel = x; hmput(_channels, x, handler); break; } } return channel; } void netChannelRelease(uint8_t channel) { hmdel(_channels, channel); } void netChannelSystemGet(netPacketHandler handler) { arrput(_systemHandlers, handler); } void netChannelSystemRelease(netPacketHandler handler) { uint16_t x; for (x=0; xchannel = decoded.channel; packet->length = decoded.length; packet->packetType = decoded.packetType; packet->data = (char *)malloc(decoded.length); memcpy(packet->data, decoded.data, decoded.length); // Send it to the subscriber. _systemHandlers[r](packet); } } else { // Does someone want this channel? r = hmgeti(_channels, decoded.channel); if (r >= 0) { // Copy the packet out. NEW(PacketDecodeDataT, packet); packet->channel = decoded.channel; packet->length = decoded.length; packet->packetType = decoded.packetType; packet->data = (char *)malloc(decoded.length); memcpy(packet->data, decoded.data, decoded.length); // Send it to the subscriber. _channels[r].value(packet); } } // Destroy our copy. packetDecodeDataStaticDestroy(&decoded); break; } } } // _netRunning } void netShutdown(void) { FILE *cache = NULL; netPacketHandlerStop(); if (_netStarted) { _netStarted = 0; // Save & free integer table. cache = fopen("cache/integer.dat", "wt"); if (cache) { if (__runtimeData.integers) { while (shlen(__runtimeData.integers) > 0) { //logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value); fprintf(cache, "%s=%ld\n", __runtimeData.integers[0].key, (long)__runtimeData.integers[0].value); shdel(__runtimeData.integers, __runtimeData.integers[0].key); } shfree(__runtimeData.integers); } fclose(cache); } // Save & free string table. cache = fopen("cache/string.dat", "wt"); if (cache) { if (__runtimeData.strings) { while (shlen(__runtimeData.strings) > 0) { //logWrite("[%s]=[%s]\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value); fprintf(cache, "%s=%s\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value); DEL(__runtimeData.strings[0].value); shdel(__runtimeData.strings, __runtimeData.strings[0].key); } shfree(__runtimeData.strings); } fclose(cache); } packetThreadDataDestroy(&__packetThreadData); } } void netStartup(void) { FILE *cache = NULL; char *line = NULL; char *p = NULL; char *temp = NULL; if (!_netStarted) { _netStarted = 1; __packetThreadData = packetThreadDataCreate(NULL); packetSenderRegister(comPacketSender); __runtimeData.integers = NULL; __runtimeData.strings = NULL; __runtimeData.protocolVersion = 0; sh_new_strdup(__runtimeData.integers); sh_new_strdup(__runtimeData.strings); // ***TODO*** Default initial tables line = (char *)malloc(4096); if (line) { // Load string cache. cache = fopen("cache/string.dat", "rt"); if (cache) { while (fscanf(cache, "%s\n", line) != EOF) { p = strstr(line, "="); if (p) { *p = 0; p++; // Do we have this string already? temp = shget(__runtimeData.strings, line); if (temp) { DEL(temp); shdel(__runtimeData.strings, line); } shput(__runtimeData.strings, line, strdup(p)); } } fclose(cache); } // Load integer cache. cache = fopen("cache/integer.dat", "rt"); if (cache) { while (fscanf(cache, "%s\n", line) != EOF) { p = strstr(line, "="); if (p) { *p = 0; p++; shput(__runtimeData.integers, line, atol(p)); } } fclose(cache); } free(line); line = NULL; } } }