Jump to content

Distraught

Honorable Member
  • Posts

    270
  • Joined

  • Last visited

  • Days Won

    38
  • Feedback

    100%

Everything posted by Distraught

  1. We also use WebView2. It works on WIn7 if they install the runtime for it.
  2. Search for this in python. If you locate the TextLine object, you just have to find where it's Show function are called from.
  3. Just compiled the server for Windows in VS when developing something. That way you can easily debug things since VS has the best debugger. I recommend moving to CMake for the server and client too, so you have a unified build system. Also, when you're done with a feature and wanna test it on a FreeBSD env, I suggest using Jenkins and creating jobs to easily pull, build and deploy with just a click on a web panel.
  4. prt->material_count = 0; for (int i = 0; i < REFINE_MATERIAL_MAX_NUM; i++) { str_to_number(prt->materials[i].vnum, data[col++]); str_to_number(prt->materials[i].count, data[col++]); if (prt->materials[i].vnum == 0) break; prt->material_count++; } Writing this makes the code logic more clear and easier to follow. Try setting for example an item for the first and third slot while leaving the second one 0.
  5. Really? For me one car doesn't reduce my FPS. It starts to drop to 50 at around 80 cars. (3070 Ti)
  6. Yeah, because you told the MySQL server to only listen on localhost. You need to just close the port used by the "db" program. Alternatively you can add BIND_IP = localhost or 127.0.0.1 to the conf.txt for your "db" program.
  7. Why do you need DevIL anyway? Just replace it with stb_image, as I remember only a few changes are needed.
  8. Never capture pointers in lambdas if it's not called somewhere inside the function where you created it (like an std::for_each or something), by this I also mean capturing "this" or "&". If the object gets destroyed, it becomes a dangling pointer causing a crash when you dereference it. Capture the PID instead and try to find the corresponding LPCHARACTER from CHARACTER_MANAGER.
  9. We did the same at Land of Heroes. The only problem with other platforms is granny. We need to completely get rid of that because of arm64 platforms (bless you Apple).
  10. What do you mean by that? We're using this for days, and nobody noticed any problem. Literally it's just caching the values that has already been calculated.
  11. Hi everyone, During some profiling today, I noticed that a significant amount of time in the Update process is being used to determine the z position of characters. This is primarily because we currently have to iterate through all the collisions to verify their height. By default, there’s another method available that utilizes caching, so we don’t have to repeatedly perform these calculations. Unfortunately, this method wasn’t used. We’ll be updating our code to take advantage of the cached version. First, go to MapManager.h in GameLib. Find float GetHeight(float fx, float fy); and add after: float GetCacheHeight(float fx, float fy); Now, go to MapManager.cpp and add the following code somewhere: float CMapManager::GetCacheHeight(float fx, float fy) { if (!m_pkMap) return 0.0f; CMapOutdoor& rkMap = GetMapOutdoorRef(); return rkMap.GetCacheHeight(fx, fy); } Now go to InstanceBase.cpp in UserInterface and find the CInstanceBase::__GetBackgroundHeight function. Modify it: float CInstanceBase::__GetBackgroundHeight(float x, float y) { CPythonBackground& rkBG=CPythonBackground::Instance(); return rkBG.GetCacheHeight(x, y); } That's all, we're done. Here is how our flame graph looks like now: I hope, it helped!
  12. No, it just adds a global mutex, so may decreases it. You did something really wrong if it fixes your crashes.
  13. Educational purpose: Using a work for educational purposes weighs in favor of fair use.
  14. Hi all, Yesterday, we brainstormed the concept of hosting a real-life M2Dev conference, akin to a game development day, featuring prominent figures from our community delivering TED-style talks on a variety of subjects. As of now, the idea has backing from @ Apranax, @ masodikbela, @ Zerial, @ .plechito', @ Deliris, @ VegaS™ and myself, all of whom are committed to speaking at the event. We're targeting this fall, around October or November, in Budapest for the event. To gauge interest, I'm putting up a poll. If there's sufficient enthusiasm, we'll kick off the planning process.
  15. Download Hello everyone, Some time ago I created this memory leak finder for Land of Heroes, but we don't really use it anymore so I decided to release it. You can use it only on Windows (otherwise you have to modify it a bit), and you will need mhook for it to work. namespace MemoryLeakFinder { typedef void* (__cdecl* _malloc)(_In_ _CRT_GUARDOVERFLOW size_t _Size); typedef void (__cdecl* _free)(_Pre_maybenull_ _Post_invalid_ void* _Block); _malloc True_malloc = (_malloc) ::malloc; _free True_free = (_free) ::free; template <class T> class NoTraceAllocator { public: using value_type = T; NoTraceAllocator() noexcept {} template <class U> NoTraceAllocator(NoTraceAllocator<U> const&) noexcept {} value_type* allocate(std::size_t n) { return static_cast<value_type*>(True_malloc(n * sizeof(value_type))); } void deallocate(value_type* p, std::size_t) noexcept { True_free(p); } }; static bool GetStackWalk(char* outWalk) { ::SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_UNDNAME); if (!::SymInitialize(::GetCurrentProcess(), "[Hidden Content]", TRUE)) return false; PVOID addrs[25] = { 0 }; USHORT frames = CaptureStackBackTrace(1, 25, addrs, NULL); char* ptr = outWalk; for (USHORT i = 0; i < frames; i++) { ULONG64 buffer[(sizeof(SYMBOL_INFO) + 1024 + sizeof(ULONG64) - 1) / sizeof(ULONG64)] = { 0 }; SYMBOL_INFO* info = (SYMBOL_INFO*)buffer; info->SizeOfStruct = sizeof(SYMBOL_INFO); info->MaxNameLen = 1024; DWORD64 displacement = 0; if (::SymFromAddr(::GetCurrentProcess(), (DWORD64)addrs[i], &displacement, info)) { ptr += sprintf_s(outWalk, 1024, "%s\n", info->Name); } } ::SymCleanup(::GetCurrentProcess()); return true; } std::unordered_map<void*, const char* , std::hash<void*> , std::equal_to<void*> , NoTraceAllocator<std::pair<const void*, const char*>>> memoryAllocations; void* My_malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size) { void* ptr = True_malloc(_Size); char* stackTrace = (char*)True_malloc(1024); GetStackWalk(stackTrace); memoryAllocations.emplace(std::make_pair(ptr, stackTrace)); return ptr; } void My_free(_Pre_maybenull_ _Post_invalid_ void* _Block) { auto it = memoryAllocations.find(_Block); if (it != memoryAllocations.end()) { True_free((void*)it->second); memoryAllocations.erase(it); } return True_free(_Block); } void StartMemoryLeakFinder() { Mhook_SetHook((PVOID*)&True_malloc, My_malloc); Mhook_SetHook((PVOID*)&True_free, My_free); } void StopMemoryLeakFinder() { Mhook_Unhook((PVOID*)&True_malloc); Mhook_Unhook((PVOID*)&True_free); std::ofstream ofs("memoryleaks.txt"); for (auto it = memoryAllocations.begin(); it != memoryAllocations.end(); ++it) { ofs << it->second << std::endl; True_free((void*)it->second); } ofs.close(); } } You have to call StartMemoryLeakFinder() and StopMemoryLeakFinder() where you'd like them to start and stop accordingly.
  16. That’s the function of another class.
  17. You just need to modify the return value of CArea::GetMaxLoadingDistanceSqr function, that's why I put this into a seperated function so it's easy to implement a slider. For example interpolate between pfStart and pfFarClip. Just add a new option to CPythonSystem and a slider in python which sets its value and you can use the value of the sliderbar as it is (0.0-1.0). float CArea::GetMaxLoadingDistanceSqr() const { int peNum; float pfStart, pfEnd, pfFarClip; CPythonBackground::instance().GetDistanceSetInfo(&peNum, &pfStart, &pfEnd, &pfFarClip); // you need to get your value for exmaple from CPythonSystem or from whenever you want float fRatio = CPythonSystem::instance().GetLoadingDistance(); // use one of the interpolation functions i provided return LinearInterpolation(pfStart * pfStart, pfFarClip * pfFarClip, fRatio); }
  18. Hello guys, I didn't like the basic memory pooling solution in the client so I extended and rewrote some parts of it. now it allocates memory in chunks instead of one by one, the chunk's size can grow Alloc can have any parameters, so you don't need to use only default constructors ctors and dtors are called properly for each object created by the pool and also on unfreed objects on Clear Keep in mind, that it's not a drop-in replacement for every case where the old one was used, you may need to modify your code at some places, so I suggest porting to this new version one by one. Good luck! template<typename T> class CMemoryPoolNew { public: CMemoryPoolNew(size_t uChunkSize = 16, bool bGrowChunkSize = true) : m_uChunkSize(uChunkSize) , m_bGrowChunkSize(bGrowChunkSize) { } ~CMemoryPoolNew() { Clear(); } void Clear() { assert(m_Free.size() == m_Data.size() && "Memory pool has unfreed objects!"); if (m_Free.size() != m_Data.size()) { for (T* pData : m_Data) { if (std::find(m_Free.begin(), m_Free.end(), pData) == m_Free.end()) { pData->~T(); } } } m_Data.clear(); m_Data.shrink_to_fit(); m_Free.clear(); m_Free.shrink_to_fit(); for (T* pChunk : m_Chunk) { ::free(pChunk); } m_Chunk.clear(); m_Chunk.shrink_to_fit(); } template<class... _Types> T* Alloc(_Types&&... _Args) { if (m_Free.empty()) Grow(); T* pNew = m_Free.back(); m_Free.pop_back(); return new(pNew) T(std::forward<_Types>(_Args)...); } void Free(T* pData) { pData->~T(); m_Free.push_back(pData); } size_t GetCapacity() const { return m_Data.size(); } private: void Grow() { size_t uChunkSize = m_uChunkSize; if (m_bGrowChunkSize) uChunkSize += uChunkSize * m_Chunk.size(); T* pStart = (T*) ::malloc(uChunkSize * sizeof(T)); m_Chunk.push_back(pStart); m_Data.reserve(m_Data.size() + uChunkSize); m_Free.reserve(m_Free.size() + uChunkSize); for (size_t i = 0; i < uChunkSize; ++i) { m_Data.push_back(pStart + i); m_Free.push_back(pStart + i); } } private: size_t m_uChunkSize; bool m_bGrowChunkSize; std::vector<T*> m_Data; std::vector<T*> m_Free; std::vector<T*> m_Chunk; };
  19. Thank you guys Yes, that's not included, it will use the clipping distance by default. You can play with the distance in CArea::GetMaxLoadingDistanceSqr.
  20. Hello everyone, I was optimizing the loading of maps for my server and I decided to share it with the public. With this modifications, only the objects and effects around the character will be loaded and it will handle their load and unload as you move around. Also effect updatings are optimized a way that closer effects are updated more frequently. Okay, so let's start the work ? [Hidden Content] Good luck! ?
  21. Then it's not a fix, it's in your code only.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.