void RankSystem::saveRank_exec() { // Enter Critical Section EnterCriticalSection(MUTEX); // Open Stats file for Writing const char* filename = MF_BuildPathname("%s", get_localinfo("csstats")); // Path to "csstats.dat" FILE* bfp = fopen(filename, "wb"); if(bfp == NULL) { MF_SyncLog("saveRank: Could not load csstats file: \"%s\"", filename); // Leave Critical Section LeaveCriticalSection(MUTEX); return; } // Write First Byte (RANK_VERSION) int16_t* buffer = new int16_t; *buffer = RANK_VERSION; fwrite(buffer, sizeof(int16_t), 1, bfp); // Save RankStats *itr = head; while(itr != NULL) { fwrite(&itr->namelen, sizeof(int16_t), 1, bfp); fwrite(itr->name, sizeof(char), itr->namelen, bfp); fwrite(&itr->uniquelen, sizeof(int16_t), 1, bfp); fwrite(itr->unique, sizeof(char), itr->uniquelen, bfp); fwrite(&itr->tks, sizeof(int32_t), 1, bfp); fwrite(&itr->damage, sizeof(int32_t), 1, bfp); fwrite(&itr->deaths, sizeof(int32_t), 1, bfp); fwrite(&itr->kills, sizeof(int32_t), 1, bfp); fwrite(&itr->shots, sizeof(int32_t), 1, bfp); fwrite(&itr->hits, sizeof(int32_t), 1, bfp); fwrite(&itr->hs, sizeof(int32_t), 1, bfp); fwrite(&itr->bDefusions, sizeof(int32_t), 1, bfp); fwrite(&itr->bDefused, sizeof(int32_t), 1, bfp); fwrite(&itr->bPlants, sizeof(int32_t), 1, bfp); fwrite(&itr->bExplosions, sizeof(int32_t), 1, bfp); fwrite(itr->bodyHits, sizeof(itr->bodyHits), 1, bfp); itr = itr->next; } *buffer = 0; fwrite(buffer, sizeof(int16_t), 1, bfp); // NULL Terminator fclose(bfp); // Leave Critical Section LeaveCriticalSection(MUTEX); }
void OnGeoipCommand() { const auto cmd = CMD_ARGV(1); if (!strcmp(cmd, "version")) { if (!HandleDB.filename) { MF_PrintSrvConsole("\n Database is not loaded.\n"); return; } const auto meta_dump = "\n" " Database metadata\n" " Node count: %i\n" " Record size: %i bits\n" " IP version: IPv%i\n" " Binary format: %i.%i\n" " Build epoch: %llu (%s)\n" " Type: %s\n" " Languages: "; char date[40]; strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S UTC", gmtime(reinterpret_cast<const time_t *>(&HandleDB.metadata.build_epoch))); fprintf(stdout, meta_dump, HandleDB.metadata.node_count, HandleDB.metadata.record_size, HandleDB.metadata.ip_version, HandleDB.metadata.binary_format_major_version, HandleDB.metadata.binary_format_minor_version, HandleDB.metadata.build_epoch, date, HandleDB.metadata.database_type); for (size_t i = 0; i < HandleDB.metadata.languages.count; ++i) { fprintf(stdout, "%s", HandleDB.metadata.languages.names[i]); if (i < HandleDB.metadata.languages.count - 1) { fprintf(stdout, " "); } } fprintf(stdout, "\n"); fprintf(stdout, " Description:\n"); for (size_t i = 0; i < HandleDB.metadata.description.count; ++i) { fprintf(stdout, " %s: %s\n", HandleDB.metadata.description.descriptions[i]->language, HandleDB.metadata.description.descriptions[i]->description); } fprintf(stdout, "\n"); } else if (!strcmp(cmd, "dump")) { if (!HandleDB.filename) { MF_PrintSrvConsole("\n Database is not loaded.\n\n"); return; } const auto num_args = CMD_ARGC(); if (num_args < 3) { MF_PrintSrvConsole("\n An IP address must be provided.\n\n"); return; } const auto ip = stripPort(const_cast<char *>(CMD_ARGV(2))); auto gai_error = 0; auto mmdb_error = 0; auto result = MMDB_lookup_string(&HandleDB, ip, &gai_error, &mmdb_error); if (gai_error != 0 || mmdb_error != MMDB_SUCCESS || !result.found_entry) { MF_PrintSrvConsole("\n Either look up failed or no found result.\n\n"); return; } MMDB_entry_data_list_s *entry_data_list = nullptr; int status; if ((status = MMDB_get_entry_data_list(&result.entry, &entry_data_list)) != MMDB_SUCCESS || entry_data_list == nullptr) { MF_PrintSrvConsole("\n Could not retrieve data list - %s.\n\n", MMDB_strerror(status)); return; } const char *file = nullptr; FILE *fp = nullptr; if (num_args > 3) { file = CMD_ARGV(3); fp = fopen(MF_BuildPathname("%s", file), "w"); } if (!fp) { file = nullptr; fp = stdout; } fprintf(fp, "\n"); MMDB_dump_entry_data_list(fp, entry_data_list, 2); fprintf(fp, "\n"); if (file) { fclose(fp); } MMDB_free_entry_data_list(entry_data_list); } else if (!strcmp(cmd, "reload")) { const auto isDatabaseLoaded = HandleDB.filename != nullptr; if (isDatabaseLoaded) { MMDB_close(&HandleDB); } if (loadDatabase() && !NativesRegistered) { MF_AddNatives(GeoipNatives); NativesRegistered = true; } } else { MF_PrintSrvConsole("\n"); MF_PrintSrvConsole(" Usage: geoip <command> [argument]\n"); MF_PrintSrvConsole(" Commands:\n"); MF_PrintSrvConsole(" version - display geoip database metadata\n"); MF_PrintSrvConsole(" reload - reload geoip database\n"); MF_PrintSrvConsole(" dump <ip> [output file] - dump all data from an IP address formatted in a JSON-ish fashion.\n"); MF_PrintSrvConsole(" An output file is mod-based and if not provided, it will print in the console.\n"); MF_PrintSrvConsole("\n"); } }
// Load Rank Routine void RankSystem::loadRank() { // Wait for saveRank THREAD to Finish (Important) if(h_saveRank != NULL) WaitForSingleObject(h_saveRank, INFINITE); // Open Stats file for Reading const char* filename = MF_BuildPathname("%s", get_localinfo("csstats")); // Path to csstats file FILE* bfp = fopen(filename, "rb"); if(bfp == NULL) { MF_SyncLog("loadRank: Could not load csstats file: \"%s\"", filename); return; } // Get RANK_VERSION (1 Byte) int16_t* buffer = new int16_t; if(fread(buffer, sizeof(int16_t), 1, bfp) != 1 || *buffer != RANK_VERSION) { MF_SyncLog("loadRank: Invalid RANK_VERSION Found!"); fclose(bfp); return; } // Init Stats d; char *unique = NULL, *name = NULL; // Clear Memory before Load g_rank.clear(); // Load if(fread(buffer, sizeof(int16_t), 1, bfp) != 1) // Pre Check { fclose(bfp); return; } while(buffer != NULL && *buffer && !feof(bfp)) { name = new char[*buffer]; if(fread(name, sizeof(char), *buffer, bfp) != *buffer) break; if(fread(buffer, sizeof(int16_t), 1, bfp) != 1) break; // unique length unique = new char[*buffer]; if(fread(unique, sizeof(char), *buffer, bfp) != *buffer) break; if(fread(&d.tks, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.damage, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.deaths, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.kills, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.shots, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.hits, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.hs, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.bDefusions, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.bDefused, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.bPlants, sizeof(int32_t), 1, bfp) != 1) break; if(fread(&d.bExplosions, sizeof(int32_t), 1, bfp) != 1) break; if(fread(d.bodyHits, sizeof(d.bodyHits), 1, bfp) != 1) break; if(fread(buffer, sizeof(int16_t), 1, bfp) != 1) break; // name length or NULL Terminator // Precise Check: Duplicate Entries ( Defalult: Discard Lower Rank Entries ) RankSystem::RankStats* temp = findEntryInRank(unique); if(temp == NULL) { temp = newEntryInRank(unique, name); if(temp != NULL) temp->updatePosition(&d, true); else { MF_SyncLog("loadRank: Unable to load any more Stats on Server"); fclose(bfp); return; } } delete[] name; delete[] unique; } fclose(bfp); }