void CmdUnloadPlugin(const CCommandContext &context, const CCommand &command){ if(command.ArgC() != 2){ META_CONPRINT("Usage: js_unload [plugin_dir]\n"); return; } auto pl = SMJS_Plugin::GetPluginByDir(command.Arg(1)); if(pl == NULL){ META_CONPRINTF("Plugin \"%s\" is not loaded!\n", command.Arg(1)); return; } delete pl; META_CONPRINTF("Plugin \"%s\" unloaded successfully!\n", command.Arg(1)); }
void CmdLoadPlugin(const CCommandContext &context, const CCommand &command){ if(command.ArgC() != 2){ META_CONPRINT("Usage: js_load [plugin_dir]\n"); return; } auto pl = SMJS_Plugin::GetPluginByDir(command.Arg(1)); if(pl != NULL){ META_CONPRINTF("Plugin \"%s\" is already loaded!\n", command.Arg(1)); return; } pl = LoadPlugin(command.Arg(1)); if(pl == NULL){ META_CONPRINTF("Plugin \"%s\" failed to load!\n", command.Arg(1)); }else{ META_CONPRINTF("Plugin \"%s\" loaded successfully!\n", command.Arg(1)); } }
void ConnectOperation::RunThinkPart() { if(NULL == this->database) { this->callback->OnError(this->dbDriver, this->dbInfo, this->connectionError); return; } META_CONPRINTF("Got db...\n"); this->callback->OnSuccess(this->dbDriver, this->dbInfo, this->database); }
void CEntityManager::PrintDump() { META_CONPRINTF("=====================================\n"); SourceHook::List<CEntity *> cent_list; CEntity *cent; int networked_count = 0; int non_networked_count = 0; for(int i=0;i<NUM_ENT_ENTRIES;i++) { cent = pEntityData[i]; if(cent != NULL) { cent_list.push_back(cent); if(i < MAX_EDICTS) networked_count++; else non_networked_count++; } } #ifdef _DEBUG META_CONPRINTF("CEntity Instance:\t\t%lld\n",CEntityManager::count); #endif META_CONPRINTF("CEntity Factory:\t\t%d\n",pFactoryTrie.size()); META_CONPRINTF("CEntity Swap:\t\t\t%d\n",pSwapTrie.size()); META_CONPRINTF("CEntity Cache:\t\t\t%d\n",pCacheTrie.size()); META_CONPRINTF("CEntity Hook:\t\t\t%d\n",pHookedTrie.size()); META_CONPRINTF("CEntity Networked:\t\t%d\n",networked_count); META_CONPRINTF("CEntity Non Networked:\t\t%d\n",non_networked_count); META_CONPRINTF("CEntity Total:\t\t\t%d\n",networked_count+non_networked_count); char buffer[128]; pFactoryTrie.bad_iterator(buffer,128, ¢_list,our_trie_iterator); cent_list.clear(); META_CONPRINTF("=====================================\n"); }
void our_trie_iterator(KTrie<IEntityFactory_CE *> *pTrie, const char *name, IEntityFactory_CE *& obj, void *data) { SourceHook::List<CEntity *> *cent_list = (SourceHook::List<CEntity *> *)data; int count = 0; SourceHook::List<CEntity *>::iterator _iter; CEntity *pInfo; for(_iter=cent_list->begin(); _iter!=cent_list->end(); _iter++) { pInfo = (*_iter); if(strcmp(name, pInfo->GetClassname()) == 0) { count++; continue; } IType *pType = GetType(pInfo->BaseEntity()); IBaseType *pBase = pType->GetBaseType(); do { const char *classname = GetTypeName(pBase->GetTypeInfo()); if(strcmp(classname, name) == 0) { count++; } } while (pBase->GetNumBaseClasses() && (pBase = pBase->GetBaseClass(0))); pType->Destroy(); } if(strlen(name) < 7) META_CONPRINTF("%s:\t\t\t\t%d\n",name,count); else if(strlen(name) < 15) META_CONPRINTF("%s:\t\t\t%d\n",name,count); else if(strlen(name) < 23) META_CONPRINTF("%s:\t\t%d\n",name,count); else META_CONPRINTF("%s:\t%d\n",name,count); }
cell_t GetSendTableByNetclass(IPluginContext *pContext, const cell_t *params) { char *title; pContext->LocalToString(params[1], &title); ServerClass *sc = UTIL_FindServerClass(title); if (sc == NULL) { META_CONPRINTF("Could not open find netclass \"%s\"\n", title); return BAD_HANDLE; } return g_pHandleSys->CreateHandle(g_SendTableHandle, sc->m_pTable, pContext->GetIdentity(), myself->GetIdentity(), NULL); }
void GlobalApprehensivePlugin::FireGameEvent(IGameEvent * event) { if (event == NULL) return; std::string name(event->GetName()); if (name == playerDeathEvent) { int attackerId = event->GetInt("attacker"); std::string attackerName = GetPlayerName(attackerId); uint32 attackerAccountId = GetAccountID(attackerId); int assisterId = event->GetInt("assister"); int victimId = event->GetInt("userid"); std::string victimName = GetPlayerName(victimId); uint32 victimAccountId = GetAccountID(victimId); std::string attackerWeapon(event->GetString("weapon")); bool headshot = event->GetBool("headshot"); META_CONPRINTF("%s (%d) killed %s (%d) with weapon %s\n", attackerName.c_str(), attackerAccountId, victimName.c_str(), victimAccountId, attackerWeapon.c_str()); } }
void *ResolveDemangledSymbol(void* handle, const char* symbol, int& type, char* argsBuffer, unsigned int len) { #ifdef PLATFORM_WINDOWS return GetProcAddress((HMODULE)handle, symbol); #elif defined PLATFORM_LINUX struct link_map* dlmap; struct stat dlstat; int dlfile; uintptr_t map_base; Elf32_Ehdr* file_hdr; Elf32_Shdr* sections, * shstrtab_hdr, * symtab_hdr, * strtab_hdr; Elf32_Sym* symtab; const char* shstrtab, * strtab; uint16_t section_count; uint32_t symbol_count; LibSymbolTable* libtable; SymbolTable* table; Symbol* symbol_entry = NULL; dlmap = (struct link_map*)handle; symtab_hdr = NULL; strtab_hdr = NULL; table = NULL; /* See if we already have a symbol table for this library */ /*for (size_t i = 0; i < m_SymTables.size(); i++) { libtable = m_SymTables[i]; if (libtable->lib_base == dlmap->l_addr) { table = &libtable->table; break; } }*/ /* If we don't have a symbol table for this library, then create one */ if (table == NULL) { libtable = new LibSymbolTable(); libtable->table.Initialize(); libtable->lib_base = dlmap->l_addr; libtable->last_pos = 0; table = &libtable->table; m_SymTables.push_back(libtable); } // TODO Make this work with demangled symbols ? /* See if the symbol is already cached in our table */ /*symbol_entry = table->FindSymbol(symbol, strlen(symbol)); if (symbol_entry != NULL) { return symbol_entry->address; }*/ /* If symbol isn't in our table, then we have open the actual library */ dlfile = open(dlmap->l_name, O_RDONLY); if (dlfile == -1 || fstat(dlfile, &dlstat) == -1) { close(dlfile); return NULL; } /* Map library file into memory */ file_hdr = (Elf32_Ehdr *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0); map_base = (uintptr_t)file_hdr; if (file_hdr == MAP_FAILED) { close(dlfile); return NULL; } close(dlfile); if (file_hdr->e_shoff == 0 || file_hdr->e_shstrndx == SHN_UNDEF) { munmap(file_hdr, dlstat.st_size); return NULL; } sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff); section_count = file_hdr->e_shnum; /* Get ELF section header string table */ shstrtab_hdr = §ions[file_hdr->e_shstrndx]; shstrtab = (const char *)(map_base + shstrtab_hdr->sh_offset); /* Iterate sections while looking for ELF symbol table and string table */ for (uint16_t i = 0; i < section_count; i++) { Elf32_Shdr &hdr = sections[i]; const char *section_name = shstrtab + hdr.sh_name; if (strcmp(section_name, ".symtab") == 0) { symtab_hdr = &hdr; } else if (strcmp(section_name, ".strtab") == 0) { strtab_hdr = &hdr; } } /* Uh oh, we don't have a symbol table or a string table */ if (symtab_hdr == NULL || strtab_hdr == NULL) { munmap(file_hdr, dlstat.st_size); return NULL; } symtab = (Elf32_Sym *)(map_base + symtab_hdr->sh_offset); strtab = (const char *)(map_base + strtab_hdr->sh_offset); symbol_count = symtab_hdr->sh_size / symtab_hdr->sh_entsize; /* Iterate symbol table starting from the position we were at last time */ for (uint32_t i = libtable->last_pos; i < symbol_count; i++) { Elf32_Sym& sym = symtab[i]; unsigned char sym_type = ELF32_ST_TYPE(sym.st_info); const char* sym_name = strtab + sym.st_name; Symbol* cur_sym; /* Skip symbols that are undefined or do not refer to functions or objects */ if (sym.st_shndx == SHN_UNDEF || (sym_type != STT_FUNC && sym_type != STT_OBJECT)) { continue; } char *name_demangled = NULL; int status; size_t length = 0; name_demangled = abi::__cxa_demangle(sym_name, NULL, &length, &status); if (status != 0) { continue; } //META_CONPRINTF("[MASTERHOOK] Checkpoint: 1\n"); //META_CONPRINTF("[MASTERHOOK] Checkpoint: 1.1 \"%s\"\n", name_demangled); //META_CONPRINTF("[MASTERHOOK] Checkpoint: 1.2\n"); char* brace_open = NULL; if (sym_type == STT_FUNC && strrchr(symbol, '(') == NULL) { // Is Function and passed symbol doesn't have an arglist // Let's strip off the arglist as we don't want to compare with that brace_open = strrchr(name_demangled, '('); if (brace_open != NULL) { brace_open[0] = '\0'; } } /* Caching symbols as we go along */ cur_sym = table->InternSymbol(name_demangled, strlen(name_demangled), (void *)(dlmap->l_addr + sym.st_value)); if (strcmp(name_demangled, symbol) == 0) { if (brace_open != NULL) { char* brace_close = strrchr(brace_open+1, ')'); if (brace_close != NULL) { brace_close[0] = '\0'; } if (length > strlen(brace_open+1)) { brace_close[len] = '\0'; } //META_CONPRINTF("[MASTERHOOK] Checkpoint: 2 \"%s\" d:%d\n", brace_open+1, len); memmove(argsBuffer, brace_open+1, len); argsBuffer[len] = '\0'; } symbol_entry = cur_sym; libtable->last_pos = ++i; type = STT_FUNC; free(name_demangled); break; } //META_CONPRINTF("[MASTERHOOK] Checkpoint: 3 \"%s\"\n", name_demangled); free(name_demangled); //META_CONPRINTF("[MASTERHOOK] Checkpoint: 4\n"); } #ifdef DEBUG //META_CONPRINTF("[MASTERHOOK] Checkpoint: 5 - End of Symbol Table\n"); #endif munmap(file_hdr, dlstat.st_size); #ifdef DEBUG META_CONPRINTF("[MASTERHOOK] type: %d\n", type); #endif return symbol_entry ? symbol_entry->address : NULL; #elif defined PLATFORM_APPLE uintptr_t dlbase, linkedit_addr; uint32_t image_count; struct mach_header *file_hdr; struct load_command *loadcmds; struct segment_command *linkedit_hdr; struct symtab_command *symtab_hdr; struct nlist *symtab; const char *strtab; uint32_t loadcmd_count; uint32_t symbol_count; LibSymbolTable *libtable; SymbolTable *table; Symbol *symbol_entry; dlbase = 0; image_count = m_ImageList->infoArrayCount; linkedit_hdr = NULL; symtab_hdr = NULL; table = NULL; /* Loop through mach-o images in process. * We can skip index 0 since that is just the executable. */ for (uint32_t i = 1; i < image_count; i++) { const struct dyld_image_info &info = m_ImageList->infoArray[i]; /* "Load" each one until we get a matching handle */ void *h = dlopen(info.imageFilePath, RTLD_NOLOAD); if (h == handle) { dlbase = (uintptr_t)info.imageLoadAddress; dlclose(h); break; } dlclose(h); } if (!dlbase) { /* Uh oh, we couldn't find a matching handle */ return NULL; } /* See if we already have a symbol table for this library */ for (size_t i = 0; i < m_SymTables.size(); i++) { libtable = m_SymTables[i]; if (libtable->lib_base == dlbase) { table = &libtable->table; break; } } /* If we don't have a symbol table for this library, then create one */ if (table == NULL) { libtable = new LibSymbolTable(); libtable->table.Initialize(); libtable->lib_base = dlbase; libtable->last_pos = 0; table = &libtable->table; m_SymTables.push_back(libtable); } /* See if the symbol is already cached in our table */ symbol_entry = table->FindSymbol(symbol, strlen(symbol)); if (symbol_entry != NULL) { return symbol_entry->address; } /* If symbol isn't in our table, then we have to locate it in memory */ file_hdr = (struct mach_header *)dlbase; loadcmds = (struct load_command *)(dlbase + sizeof(struct mach_header)); loadcmd_count = file_hdr->ncmds; /* Loop through load commands until we find the ones for the symbol table */ for (uint32_t i = 0; i < loadcmd_count; i++) { if (loadcmds->cmd == LC_SEGMENT && !linkedit_hdr) { struct segment_command *seg = (struct segment_command *)loadcmds; if (strcmp(seg->segname, "__LINKEDIT") == 0) { linkedit_hdr = seg; if (symtab_hdr) { break; } } } else if (loadcmds->cmd == LC_SYMTAB) { symtab_hdr = (struct symtab_command *)loadcmds; if (linkedit_hdr) { break; } } /* Load commands are not of a fixed size which is why we add the size */ loadcmds = (struct load_command *)((uintptr_t)loadcmds + loadcmds->cmdsize); } if (!linkedit_hdr || !symtab_hdr || !symtab_hdr->symoff || !symtab_hdr->stroff) { /* Uh oh, no symbol table */ return NULL; } linkedit_addr = dlbase + linkedit_hdr->vmaddr; symtab = (struct nlist *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff); strtab = (const char *)(linkedit_addr + symtab_hdr->stroff - linkedit_hdr->fileoff); symbol_count = symtab_hdr->nsyms; /* Iterate symbol table starting from the position we were at last time */ for (uint32_t i = libtable->last_pos; i < symbol_count; i++) { struct nlist &sym = symtab[i]; /* Ignore the prepended underscore on all symbols, so +1 here */ const char *sym_name = strtab + sym.n_un.n_strx + 1; Symbol *cur_sym; /* Skip symbols that are undefined */ if (sym.n_sect == NO_SECT) { continue; } /* Caching symbols as we go along */ cur_sym = table->InternSymbol(sym_name, strlen(sym_name), (void *)(dlbase + sym.n_value)); if (strcmp(symbol, sym_name) == 0) { symbol_entry = cur_sym; libtable->last_pos = ++i; break; } } return symbol_entry ? symbol_entry->address : NULL; #endif }
/* Given Elf header, Elf_Scn, and Elf32_Shdr * print out the symbol table */ void *GetSymbolAdress(const char *filename, const char *symbol) { #ifdef PLATFORM_POSIX int fd; Elf *elf; GElf_Ehdr elfhdr; if (elf_version(EV_CURRENT) == EV_NONE) { META_CONPRINTF("ELF library is out of date, Quitting\n"); } fd = open(filename, O_RDONLY); if (fd < 0) { META_CONPRINTF("[Masterhook] Unable to open \"%s\"\n", filename); } elf = elf_begin(fd, ELF_C_READ, NULL); if (gelf_getehdr(elf, &elfhdr) == 0) { META_CONPRINTF("Cannot read elf header. This usually means that %s is not a valid elf file\n", filename); } Elf_Scn* section = 0; Elf32_Shdr *shdr = NULL; bool symtabFound = false; while ((section = elf_nextscn(elf, section)) != 0) { if ((shdr = elf32_getshdr (section)) != 0) { if (shdr->sh_type == SHT_SYMTAB) { symtabFound = true; break; } } } if (shdr == NULL || !symtabFound) { return NULL; } Elf_Scn *scn = section; Elf_Data *data; char *name; data = 0; int number = 0; if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0){ META_CONPRINTF("Section had no data!\n"); return NULL; } Elf32_Sym *esym = (Elf32_Sym*) data->d_buf; Elf32_Sym *lastsym = (Elf32_Sym*) ((char*) data->d_buf + data->d_size); for (; esym < lastsym; esym++) { if ((esym->st_value == 0) || (ELF32_ST_BIND(esym->st_info) == STB_WEAK) || (ELF32_ST_BIND(esym->st_info) == STB_NUM) || (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) { continue; } name = elf_strptr(elf, shdr->sh_link , (size_t)esym->st_name); if(!name){ META_CONPRINTF("%s\n", elf_errmsg(elf_errno())); return NULL; } char *name_demangled = 0; int* status; name_demangled = abi::__cxa_demangle(name, 0, 0, status); #ifdef DEBUG META_CONPRINTF("%d: Name: %s == %s Address: 0x%x\n", number++, name_demangled, symbol, esym->st_value); #endif if (name_demangled != NULL) { if (strstr(name_demangled, symbol)) { return (void*)esym->st_value; } } //free(name_demangled); } #endif return NULL; }
INavMesh *NavMeshLoader::Load(char *error, int errorMaxlen) { strcpy_s(error, errorMaxlen, ""); char navPath[1024]; g_pSM->BuildPath(Path_Game, navPath, sizeof(navPath), "maps\\%s.nav", this->mapName); FILE *fileHandle = fopen(navPath, "rb"); if(!fileHandle) { sprintf_s(error, errorMaxlen, "Unable to find navigation mesh: %s", navPath); return NULL; } unsigned int magicNumber; int elementsRead = this->ReadData(&magicNumber, sizeof(unsigned int), 1, fileHandle); if(elementsRead != 1) { fclose(fileHandle); sprintf_s(error, errorMaxlen, "Error reading magic number value from navigation mesh: %s", navPath); return NULL; } if(magicNumber != 0xFEEDFACE) { fclose(fileHandle); sprintf_s(error, errorMaxlen, "Invalid magic number value from navigation mesh: %s [%p]", navPath, magicNumber); return NULL; } unsigned int version; elementsRead = this->ReadData(&version, sizeof(unsigned int), 1, fileHandle); if(elementsRead != 1) { fclose(fileHandle); sprintf_s(error, errorMaxlen, "Error reading version number from navigation mesh: %s", navPath); return NULL; } if (version < 6 || version > 16) { fclose(fileHandle); sprintf_s(error, errorMaxlen, "Invalid version number value from navigation mesh: %s [%d]", navPath, version); return NULL; } unsigned int navMeshSubVersion = 0; if(version >= 10) { this->ReadData(&navMeshSubVersion, sizeof(unsigned int), 1, fileHandle); } unsigned int saveBspSize; this->ReadData(&saveBspSize, sizeof(unsigned int), 1, fileHandle); char bspPath[1024]; g_pSM->BuildPath(Path_Game, bspPath, sizeof(bspPath), "maps\\%s.bsp", this->mapName); unsigned int actualBspSize = 0; #ifdef PLATFORM_WINDOWS struct _stat s; _stat(bspPath, &s); actualBspSize = s.st_size; #elif defined PLATFORM_POSIX struct stat s; stat(bspPath, &s); actualBspSize = s.st_size; #endif if(actualBspSize != saveBspSize) { META_CONPRINTF("WARNING: Navigation mesh was not built with the same version of the map [%d vs %d].\n", actualBspSize, saveBspSize); } unsigned char meshAnalyzed = 0; if(version >= 14) { this->ReadData(&meshAnalyzed, sizeof(unsigned char), 1, fileHandle); } bool isMeshAnalyzed = meshAnalyzed != 0; //META_CONPRINTF("Is mesh analyzed: %s\n", isMeshAnalyzed ? "yes" : "no"); unsigned short placeCount; this->ReadData(&placeCount, sizeof(unsigned short), 1, fileHandle); //META_CONPRINTF("Nav version: %d; BSPSize: %d; MagicNumber: %p; SubVersion: %d [v10+only]; Place Count: %d\n", version, saveBspSize, magicNumber, navMeshSubVersion, placeCount); List<INavMeshPlace*> *places = new List<INavMeshPlace*>(); for(unsigned int placeIndex = 0; placeIndex < placeCount; placeIndex++) { unsigned short placeSize; this->ReadData(&placeSize, sizeof(unsigned short), 1, fileHandle); char placeName[256]; this->ReadData(placeName, sizeof(unsigned char), placeSize, fileHandle); places->Append(new NavMeshPlace(placeIndex, placeName)); //META_CONPRINTF("Parsed place: %s [%d]\n", placeName, placeIndex); } unsigned char unnamedAreas = 0; if(version > 11) { this->ReadData(&unnamedAreas, sizeof(unsigned char), 1, fileHandle); } bool hasUnnamedAreas = unnamedAreas != 0; //META_CONPRINTF("Has unnamed areas: %s\n", hasUnnamedAreas ? "yes" : "no"); IList<INavMeshArea*> *areas = new List<INavMeshArea*>(); unsigned int areaCount; this->ReadData(&areaCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Area count: %d\n", areaCount); for(unsigned int areaIndex = 0; areaIndex < areaCount; areaIndex++) { unsigned int areaID; float x1, y1, z1, x2, y2, z2; unsigned int areaFlags = 0; IList<INavMeshConnection*> *connections = new List<INavMeshConnection*>(); IList<INavMeshHidingSpot*> *hidingSpots = new List<INavMeshHidingSpot*>(); IList<INavMeshEncounterPath*> *encounterPaths = new List<INavMeshEncounterPath*>(); IList<INavMeshLadderConnection*> *ladderConnections = new List<INavMeshLadderConnection*>(); IList<INavMeshCornerLightIntensity*> *cornerLightIntensities = new List<INavMeshCornerLightIntensity*>(); IList<INavMeshVisibleArea*> *visibleAreas = new List<INavMeshVisibleArea*>(); unsigned int inheritVisibilityFrom = 0; unsigned char hidingSpotCount = 0; unsigned int visibleAreaCount = 0; float earliestOccupyTimeFirstTeam = 0.0f; float earliestOccupyTimeSecondTeam = 0.0f; float northEastCornerZ; float southWestCornerZ; unsigned short placeID = 0; unsigned char unk01 = 0; this->ReadData(&areaID, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Area ID: %d\n", areaID); if(version <= 8) { this->ReadData(&areaFlags, sizeof(unsigned char), 1, fileHandle); } else if(version < 13) { this->ReadData(&areaFlags, sizeof(unsigned short), 1, fileHandle); } else { this->ReadData(&areaFlags, sizeof(unsigned int), 1, fileHandle); } //META_CONPRINTF("Area Flags: %d\n", areaFlags); this->ReadData(&x1, sizeof(float), 1, fileHandle); this->ReadData(&y1, sizeof(float), 1, fileHandle); this->ReadData(&z1, sizeof(float), 1, fileHandle); this->ReadData(&x2, sizeof(float), 1, fileHandle); this->ReadData(&y2, sizeof(float), 1, fileHandle); this->ReadData(&z2, sizeof(float), 1, fileHandle); //META_CONPRINTF("Area extent: (%f, %f, %f), (%f, %f, %f)\n", x1, y1, z1, x2, y2, z2); this->ReadData(&northEastCornerZ, sizeof(float), 1, fileHandle); this->ReadData(&southWestCornerZ, sizeof(float), 1, fileHandle); //META_CONPRINTF("Corners: NW(%f), SW(%f)\n", northEastCornerZ, southWestCornerZ); // CheckWaterLevel() are we underwater in this area? for(unsigned int direction = 0; direction < NAV_DIR_COUNT; direction++) { unsigned int connectionCount; this->ReadData(&connectionCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Connection count: %d (%p)\n", connectionCount, connectionCount); for(int connectionIndex = 0; connectionIndex < connectionCount; connectionIndex++) { unsigned int connectingAreaID; this->ReadData(&connectingAreaID, sizeof(unsigned int), 1, fileHandle); INavMeshConnection *connection = new NavMeshConnection(connectingAreaID, (NavDirType)direction); connections->Append(connection); } } this->ReadData(&hidingSpotCount, sizeof(unsigned char), 1, fileHandle); //META_CONPRINTF("Hiding Spot Count: %d\n", hidingSpotCount); for(unsigned int hidingSpotIndex = 0; hidingSpotIndex < hidingSpotCount; hidingSpotIndex++) { unsigned int hidingSpotID; this->ReadData(&hidingSpotID, sizeof(unsigned int), 1, fileHandle); float hidingSpotX, hidingSpotY, hidingSpotZ; this->ReadData(&hidingSpotX, sizeof(float), 1, fileHandle); this->ReadData(&hidingSpotY, sizeof(float), 1, fileHandle); this->ReadData(&hidingSpotZ, sizeof(float), 1, fileHandle); unsigned char hidingSpotFlags; this->ReadData(&hidingSpotFlags, sizeof(unsigned char), 1, fileHandle); INavMeshHidingSpot *hidingSpot = new NavMeshHidingSpot(hidingSpotID, hidingSpotX, hidingSpotY, hidingSpotZ, hidingSpotFlags); hidingSpots->Append(hidingSpot); //META_CONPRINTF("Parsed hiding spot (%f, %f, %f) with ID [%p] and flags [%p]\n", hidingSpotX, hidingSpotY, hidingSpotZ, hidingSpotID, hidingSpotFlags); } // These are old but we just need to read the data. if(version < 15) { unsigned char approachAreaCount; this->ReadData(&approachAreaCount, sizeof(unsigned char), 1, fileHandle); for(unsigned int approachAreaIndex = 0; approachAreaIndex < approachAreaCount; approachAreaIndex++) { unsigned int approachHereID; this->ReadData(&approachHereID, sizeof(unsigned int), 1, fileHandle); unsigned int approachPrevID; this->ReadData(&approachPrevID, sizeof(unsigned int), 1, fileHandle); unsigned char approachType; this->ReadData(&approachType, sizeof(unsigned char), 1, fileHandle); unsigned int approachNextID; this->ReadData(&approachNextID, sizeof(unsigned int), 1, fileHandle); unsigned char approachHow; this->ReadData(&approachHow, sizeof(unsigned char), 1, fileHandle); } } unsigned int encounterPathCount; this->ReadData(&encounterPathCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Encounter Path Count: %d\n", encounterPathCount); for(unsigned int encounterPathIndex = 0; encounterPathIndex < encounterPathCount; encounterPathIndex++) { unsigned int encounterFromID; this->ReadData(&encounterFromID, sizeof(unsigned int), 1, fileHandle); unsigned char encounterFromDirection; this->ReadData(&encounterFromDirection, sizeof(unsigned char), 1, fileHandle); unsigned int encounterToID; this->ReadData(&encounterToID, sizeof(unsigned int), 1, fileHandle); unsigned char encounterToDirection; this->ReadData(&encounterToDirection, sizeof(unsigned char), 1, fileHandle); unsigned char encounterSpotCount; this->ReadData(&encounterSpotCount, sizeof(unsigned char), 1, fileHandle); //META_CONPRINTF("Encounter [from ID %d] [from dir %p] [to ID %d] [to dir %p] [spot count %d]\n", encounterFromID, encounterFromDirection, encounterToID, encounterToDirection, encounterSpotCount); IList<INavMeshEncounterSpot*> *encounterSpots = new List<INavMeshEncounterSpot*>(); for(int encounterSpotIndex = 0; encounterSpotIndex < encounterSpotCount; encounterSpotIndex++) { unsigned int encounterSpotOrderId; this->ReadData(&encounterSpotOrderId, sizeof(unsigned int), 1, fileHandle); unsigned char encounterSpotT; this->ReadData(&encounterSpotT, sizeof(unsigned char), 1, fileHandle); float encounterSpotParametricDistance = (float)encounterSpotT / 255.0f; INavMeshEncounterSpot *encounterSpot = new NavMeshEncounterSpot(encounterSpotOrderId, encounterSpotParametricDistance); encounterSpots->Append(encounterSpot); //META_CONPRINTF("Encounter spot [order id %d] and [T %p]\n", encounterSpotOrderId, encounterSpotT); } INavMeshEncounterPath *encounterPath = new NavMeshEncounterPath(encounterFromID, (NavDirType)encounterFromDirection, encounterToID, (NavDirType)encounterToDirection, encounterSpots); encounterPaths->Append(encounterPath); } this->ReadData(&placeID, sizeof(unsigned short), 1, fileHandle); //META_CONPRINTF("Place ID: %d\n", placeID); for(unsigned int ladderDirection = 0; ladderDirection < NAV_LADDER_DIR_COUNT; ladderDirection++) { unsigned int ladderConnectionCount; this->ReadData(&ladderConnectionCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Ladder Connection Count: %d\n", ladderConnectionCount); for(unsigned int ladderConnectionIndex = 0; ladderConnectionIndex < ladderConnectionCount; ladderConnectionIndex++) { unsigned int ladderConnectID; this->ReadData(&ladderConnectID, sizeof(unsigned int), 1, fileHandle); INavMeshLadderConnection *ladderConnection = new NavMeshLadderConnection(ladderConnectID, (NavLadderDirType)ladderDirection); ladderConnections->Append(ladderConnection); //META_CONPRINTF("Parsed ladder connect [ID %d]\n", ladderConnectID); } } this->ReadData(&earliestOccupyTimeFirstTeam, sizeof(float), 1, fileHandle); this->ReadData(&earliestOccupyTimeSecondTeam, sizeof(float), 1, fileHandle); if(version >= 11) { for (int navCornerIndex = 0; navCornerIndex < NAV_CORNER_COUNT; navCornerIndex++) { float navCornerLightIntensity; this->ReadData(&navCornerLightIntensity, sizeof(float), 1, fileHandle); INavMeshCornerLightIntensity *cornerLightIntensity = new NavMeshCornerLightIntensity((NavCornerType)navCornerIndex, navCornerLightIntensity); cornerLightIntensities->Append(cornerLightIntensity); //META_CONPRINTF("Light intensity: [%f] [idx %d]\n", navCornerLightIntensity, navCornerIndex); } if(version >= 16) { this->ReadData(&visibleAreaCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Visible area count: %d\n", visibleAreaCount); for(unsigned int visibleAreaIndex = 0; visibleAreaIndex < visibleAreaCount; visibleAreaIndex++) { unsigned int visibleAreaID; this->ReadData(&visibleAreaID, sizeof(unsigned int), 1, fileHandle); unsigned char visibleAreaAttributes; this->ReadData(&visibleAreaAttributes, sizeof(unsigned char), 1, fileHandle); INavMeshVisibleArea *visibleArea = new NavMeshVisibleArea(visibleAreaID, visibleAreaAttributes); visibleAreas->Append(visibleArea); //META_CONPRINTF("Parsed visible area [%d] with attr [%p]\n", visibleAreaID, visibleAreaAttributes); } this->ReadData(&inheritVisibilityFrom, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Inherit visibilty from: %d\n", inheritVisibilityFrom); this->ReadData(&unk01, sizeof(unsigned char), 1, fileHandle); } } INavMeshArea *area = new NavMeshArea(areaID, areaFlags, placeID, x1, y1, z1, x2, y2, z2, northEastCornerZ, southWestCornerZ, connections, hidingSpots, encounterPaths, ladderConnections, cornerLightIntensities, visibleAreas, inheritVisibilityFrom, earliestOccupyTimeFirstTeam, earliestOccupyTimeSecondTeam, unk01); areas->Append(area); } unsigned int ladderCount; this->ReadData(&ladderCount, sizeof(unsigned int), 1, fileHandle); //META_CONPRINTF("Ladder count: %d\n", ladderCount); IList<INavMeshLadder*> *ladders = new List<INavMeshLadder*>(); for(unsigned int ladderIndex = 0; ladderIndex < ladderCount; ladderIndex++) { unsigned int ladderID; this->ReadData(&ladderID, sizeof(unsigned int), 1, fileHandle); float ladderWidth; this->ReadData(&ladderWidth, sizeof(float), 1, fileHandle); float ladderTopX, ladderTopY, ladderTopZ, ladderBottomX, ladderBottomY, ladderBottomZ; this->ReadData(&ladderTopX, sizeof(float), 1, fileHandle); this->ReadData(&ladderTopY, sizeof(float), 1, fileHandle); this->ReadData(&ladderTopZ, sizeof(float), 1, fileHandle); this->ReadData(&ladderBottomX, sizeof(float), 1, fileHandle); this->ReadData(&ladderBottomY, sizeof(float), 1, fileHandle); this->ReadData(&ladderBottomZ, sizeof(float), 1, fileHandle); float ladderLength; this->ReadData(&ladderLength, sizeof(float), 1, fileHandle); unsigned int ladderDirection; this->ReadData(&ladderDirection, sizeof(unsigned int), 1, fileHandle); unsigned int ladderTopForwardAreaID; this->ReadData(&ladderTopForwardAreaID, sizeof(unsigned int), 1, fileHandle); unsigned int ladderTopLeftAreaID; this->ReadData(&ladderTopLeftAreaID, sizeof(unsigned int), 1, fileHandle); unsigned int ladderTopRightAreaID; this->ReadData(&ladderTopRightAreaID, sizeof(unsigned int), 1, fileHandle); unsigned int ladderTopBehindAreaID; this->ReadData(&ladderTopBehindAreaID, sizeof(unsigned int), 1, fileHandle); unsigned int ladderBottomAreaID; this->ReadData(&ladderBottomAreaID, sizeof(unsigned int), 1, fileHandle); INavMeshLadder *ladder = new NavMeshLadder(ladderID, ladderWidth, ladderLength, ladderTopX, ladderTopY, ladderTopZ, ladderBottomX, ladderBottomY, ladderBottomZ, (NavDirType)ladderDirection, ladderTopForwardAreaID, ladderTopLeftAreaID, ladderTopRightAreaID, ladderTopBehindAreaID, ladderBottomAreaID); ladders->Append(ladder); } fclose(fileHandle); INavMesh *mesh = new NavMesh(magicNumber, version, navMeshSubVersion, saveBspSize, isMeshAnalyzed, places, areas, ladders); return mesh; }