Nathan.
Members-
Postów
217 -
Rejestracja
-
Ostatnia wizyta
-
Wygrane w rankingu
1
Osiągnięcia Nathan.
-
322ZADSSAD zareagował(a) na odpowiedź w temacie:
[C++] Naprawa (zabezpieczenie) iniekcji SQL dotycząca "net.SendAnswerMakeGuildPacket"
-
kiraly012 zareagował(a) na odpowiedź w temacie:
[C++] FIX - Naprawa błędu z wyświetlaniem nazw sklepów nad potworami i graczami.
-
kuba331sa zareagował(a) na odpowiedź w temacie:
[C++] Naprawa (zabezpieczenie) iniekcji SQL dotycząca "net.SendAnswerMakeGuildPacket"
-
Bistik zareagował(a) na odpowiedź w temacie:
[C++] Naprawa (zabezpieczenie) iniekcji SQL dotycząca "net.SendAnswerMakeGuildPacket"
-
KropaDev zareagował(a) na odpowiedź w temacie:
[C++] Rewolucja w zarządzaniu buffami nowa funkcja dla GM.
-
Bercik8912 zareagował(a) na odpowiedź w temacie:
[C++] FIX - Naprawa błędu z wyświetlaniem nazw sklepów nad potworami i graczami.
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Ikony] Skrzynie Ekwipunku
-
Nathan. zareagował(a) na odpowiedź w temacie:
Metin2 Pliki Serwerowe 2025 zaktualizowane z pełnym FoxFS / dx9 (Mainline)
-
MrJazor zareagował(a) na odpowiedź w temacie:
[C++] Rewolucja w zarządzaniu buffami nowa funkcja dla GM.
-
Nathan. zareagował(a) na odpowiedź w temacie:
[C++] Konwersja formatu czasu.
-
Silence zareagował(a) na odpowiedź w temacie:
[C++] FIX - Naprawa błędu z wyświetlaniem nazw sklepów nad potworami i graczami.
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Client] Rozpakowany Dragon2 (Upscaled 4K)
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Plechito] All New Stuff (Refreshed)
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Client] Rozpakowany XenoxMT2 (Upscaled 4K)
-
Nathan. zareagował(a) na odpowiedź w temacie:
Pliki Serwerowe DivineWorld s2 Official
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Client] Rozpakowany Valium - Akademia (Upscaled 4K)
-
Nathan. zareagował(a) na odpowiedź w temacie:
[Client] Rozpakowany CarolineMT2 (Upscaled 4K)
-
MrDJ zareagował(a) na odpowiedź w temacie:
[C++] FIX - Naprawa problemu z nullptr w funkcji przenoszenia przedmiotów do magazynu.
-
MrDJ zareagował(a) na odpowiedź w temacie:
[C++] Naprawa (zabezpieczenie) iniekcji SQL dotycząca "net.SendAnswerMakeGuildPacket"
-
null
-
Tak jak w temacie, małe zabezpieczenie gildyjne. 📂Lokalizacja pliku: game -> guild_manager.cpp 🔍 Szukaj: DWORD CGuildManager::CreateGuild(TGuildCreateParameter& gcp) { if (!gcp.master) return 0; if (!check_name(gcp.name)) { gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ćµĺ> ±ćµĺ Ŕ̸§ŔĚ ŔűÇŐÇĎÁö ľĘ˝Ŕ´Ď´Ů.")); return 0; } Dodaj pod : //fix sql2 ~ sharegon.pl static char __guild_name[GUILD_NAME_MAX_LEN*2+1]; DBManager::instance().EscapeString(__guild_name, sizeof(__guild_name), gcp.name, strnlen(gcp.name, sizeof(gcp.name))); if (strncmp(__guild_name, gcp.name, strnlen(gcp.name, sizeof(gcp.name)))) return 0; //fix sql2 ~ sharegon.pl
-
Cześć👋 Podczas walki z potworami, czasami mogą nad nimi pojawiać się nazwy sklepów. Zdarza się to głównie na serwerach z dużą ilością graczy. Nawet jeśli gracz nie założył własnego sklepu nad postacią mogą pojawiać się nazwy sklepów innych graczy. Ten błąd również istniał na oficjalnych serwerach dawno temu. Rozwiązanie błędu dotyczy tylko zwykłych sklepów wystawianych przez graczy. Możesz na podstawie tego rozwiązania wdrożyć poprawkę również w sklepach offline. Jeśli dokonasz poniższych zmian w swoim kodzie, rozwiążesz ten problem. Uwaga bez odpowiednich modyfikacji w sklepach offline mogą występować problemy z nazwami sklepów! Wyjaśnienie problemu: Funkcja 'GetMyShop' zwraca pointer na sklep przypisany do postaci. W przypadku błędnej obsługi, gdy zwrócony pointer jest null i gdy w okolicy pojawia się wiele potworów, trudno jest określić, która postać do czego się odnosi. Funkcja 'EncodeInsertPacket' jest nieco problematyczna i powoduje opóźnienia rzędu 1 - 2 sekundy w obszarach z dużą ilością potworów. Kolejnym problemem jest wyświetlanie nazw sklepów nad postaciami, które tak naprawdę nie mają własnego sklepu. 🧩 Rozwiązanie: 📁 Lokalizacja pliku: 'game -> char.cpp' 🔍 Szukaj: void CHARACTER::EncodeInsertPacket(LPENTITY entity) if (GetMyShop()) { TPacketGCShopSign p; p.bHeader = HEADER_GC_SHOP_SIGN; p.dwVID = GetVID(); strlcpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign)); d->Packet(&p, sizeof(TPacketGCShopSign)); } ♻️ Zamień: if (IsPC() && GetMyShop()) { TPacketGCShopSign p; p.bHeader = HEADER_GC_SHOP_SIGN; p.dwVID = GetVID(); strncpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign) - 1); p.szSign[sizeof(p.szSign) - 1] = '\0'; d->Packet(&p, sizeof(TPacketGCShopSign)); } 🔍 Szukaj: void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE bItemCount) char szSign[SHOP_SIGN_MAX_LEN+1]; strlcpy(szSign, c_pszSign, sizeof(szSign)); m_stShopSign = szSign; if (m_stShopSign.length() == 0) return; if (LC_IsCanada() == false) { if (CBanwordManager::instance().CheckString(m_stShopSign.c_str(), m_stShopSign.length())) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("비속어나 은어가 포함된 상점 이름으로 상점을 열 수 없습니다.")); return; } } ♻️ Zamień: char szSign[SHOP_SIGN_MAX_LEN+1]; strlcpy(szSign, c_pszSign, sizeof(szSign)); //m_stShopSign = szSign; - opóźniamy przepisanie szSign do m_stShopSign do momentu wysłania pakietu. if (strlen(szSign) == 0) { return; } if (LC_IsCanada() == false) { if (CBanwordManager::instance().CheckString(szSign, strlen(szSign))) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("비속어나 은어가 포함된 상점 이름으로 상점을 열 수 없습니다.")); return; } } 🔍 Szukamy nadal w funkcji 'OpenMyShop': TPacketGCShopSign p; p.bHeader = HEADER_GC_SHOP_SIGN; p.dwVID = GetVID(); strlcpy(p.szSign, c_pszSign, sizeof(p.szSign)); PacketAround(&p, sizeof(TPacketGCShopSign)); ♻️ Zamień: m_stShopSign = szSign; TPacketGCShopSign packet{}; packet.bHeader = HEADER_GC_SHOP_SIGN; packet.dwVID = GetVID(); strncpy(packet.szSign, szSign, sizeof(packet.szSign) - 1); packet.szSign[sizeof(packet.szSign) - 1] = '\0'; PacketAround(&packet, sizeof(TPacketGCShopSign));
-
Witam wszystkich👋 Zarys problemu 📖 Każdy, kto zajmuje się tworzeniem serwerów do gry Metin2, zna znaczenie stabilności i bezawaryjności. W tym kontekście, błąd w funkcji CInputMain::SafeboxCheckin może być prawdziwą pułapką, prowadzącą do crashu serwera i frustracji graczy. 🎮😤 Ta funkcja zajmuje się przenoszeniem przedmiotów pomiędzy ekwipunkiem a magazynem, co jest kluczową operacją dla każdego gracza. Co gorsza, błąd pojawia się w momencie, gdy próbujemy sprawdzić status questu. Na pewno nikt z nas nie chce, aby serwer padł w tak krytycznym momencie! 🛠️ Problem w Skrócie 🤔 Błąd polega na tym, że metoda GetPCForce() może zwrócić wskaźnik nullptr, który później jest używany w metodzie IsRunning(). Jest to klasyczny przypadek błędu segmentacji, który może mieć poważne konsekwencje, takie jak crash serwera. Funkcja z problemem 📍 Funkcja CInputMain::SafeboxCheckin służy do sprawdzenia przenoszonych przedmiotów między magazynem a ekwipunkiem postaci. Obejmuje ona różne warunki i przypadki, które muszą być spełnione, zanim przedmiot zostanie przeniesiony. Obejmuje również sprawdzanie różnych questów i ich statusów, co prowadzi do potencjalnego błędu segmentacji, jeżeli nie jest właściwie zarządzane. Sposób naprawy 🛠️ Jeśli chcesz tego uniknąć, dodaj warunek sprawdzający, czy wskaźnik zwrócony przez GetPCForce() jest nullptr - zanim wywołasz na nim metodę IsRunning() Rozwiązanie: Lokalizacja pliku: game -> input_main.cpp Znajdź funkcję: void CInputMain::SafeboxCheckin(LPCHARACTER ch, const char* c_pData) W tej funkcji na samym początku znajdziesz taki warunek: if (quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID())->IsRunning() == true) return; Zastąp powyższy warunek następującym kodem: auto* pc = quest::CQuestManager::Instance().GetPCForce(ch->GetPlayerID()); //fix sharegon const bool isQuestRunning = (pc != nullptr) && pc->IsRunning(); if (isQuestRunning) { return; } Podsumowanie 🌟 Dzięki tej prostej, ale skutecznej naprawie, zabezpieczysz swój serwer Metin2 przed potencjalnymi błędami segmentacji. To niewielka zmiana, lecz może znacząco wpłynąć na doświadczenie graczy i stabilność serwera. 🎉👍
-
[C++] Rewolucja w zarządzaniu buffami nowa funkcja dla GM.
temat opublikował(a) Nathan. w Metin2 - Questy, Dify, C++, Python
Najnowszy system, który dzisiaj pokażę, automatycznie rozpoznaje, kiedy Mistrz Gry próbuje nałożyć efekt na zwykłego gracza i automatycznie zwraca ten efekt do GM'a. To samo dzieje się, gdy zwykły gracz próbuje nałożyć efekt na GM'a. Jak to Działa? Nasz system inteligentnie rozpoznaje, kiedy Mistrz Gry próbuje nałożyć efekt na zwykłego gracza i od razu zwraca ten efekt na GM'a. Ale to nie wszystko! Działa to również w drugą stronę – jeżeli to gracz próbuje nałożyć efekt na GM. Teraz przedstawię krok po kroku jak wdrożyć powyższe rozwiązanie, zapraszam. 📂 Lokalizacja pliku: game -> stdafx.h ➕ Dodaj w przypadku gdy nie masz: #include <array> 📂 Lokalizacja pliku: 'common -> service.h / commondefines.h ➕ Dodaj: #define BLOCK_BUFF_FOR_GM 📂 Lokalizacja pliku: 'game -> char_skill.cpp' 🔍 Szukaj: int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel) { instrukcje funkcji } ➕ Dodaj: /* * This function checks if a Game Master (GM) is trying to apply a restricted buff on a regular player, * or if a regular player is trying to apply a restricted buff on a GM. If either condition is met, the * function returns true, indicating that the buff should be returned to the caster. * * @param dwVnum The unique identifier (VNUM) of the buff/skill to be applied. * @param pkVictim Pointer to the character receiving the buff. * @param pkCaster Pointer to the character casting the buff. * @return true if the buff should be returned to the caster, otherwise false. * @ SHAREGON.PL ~ by Sevence */ #if defined(BLOCK_BUFF_FOR_GM) bool CHARACTER::BlockBuffForGM(uint32_t dwVnum, LPCHARACTER pkVictim, LPCHARACTER pkCaster) { std::array<uint32_t, 6> iArrayIndexSkill = {94, 95, 96, 109, 110, 111}; bool shouldReturnBuff = false; if (std::find(iArrayIndexSkill.begin(), iArrayIndexSkill.end(), dwVnum) != iArrayIndexSkill.end() && pkCaster->IsGM() && !pkVictim->IsGM()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_BUFF_TO_%s_NOT_GM"), pkVictim->GetName()); shouldReturnBuff = true; } else if (std::find(iArrayIndexSkill.begin(), iArrayIndexSkill.end(), dwVnum) != iArrayIndexSkill.end() && !pkCaster->IsGM() && pkVictim->IsGM()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_BUFF_TO_GM_%s"), pkVictim->GetName()); shouldReturnBuff = true; } return shouldReturnBuff; } #endif 🔍 Szukaj: bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaster) 🔍 A w tej funkcji znajdz: if (false == CanUseSkill(dwVnum)) return false; ➕ Dodaj: #if defined(BLOCK_BUFF_FOR_GM) LPCHARACTER pkCaster = this; if (pkVictim) { if (BlockBuffForGM(dwVnum, pkVictim, pkCaster)) { pkVictim = pkCaster; } } #endif 📂 Lokalizacja pliku: 'game -> char.h' 🔍 Szukaj: bool SkillLevelDown(DWORD dwVnum); ➕ Dodaj: #if defined(BLOCK_BUFF_FOR_GM) bool BlockBuffForGM(uint32_t dwVnum, LPCHARACTER pkVictim, LPCHARACTER pkCaster); #endif 📂 Lokalizacja pliku: 'share -> locale -> poland -> locale_string.txt' ➕ Dodaj: "CANNOT_BUFF_TO_%s_NOT_GM"; "Próbowano nałożyć buff na gracza |cFFFFC700%s|r, będąc Mistrzem Gry. Efekt został zwrócony na Ciebie."; "CANNOT_BUFF_TO_GM_%s"; "Próbowano nałożyć buff na Mistrza Gry |cFFFFC700%s|r, nie posiadając uprawnień GM. Efekt został zwrócony."; -
Witajcie ! Niedługo opublikuję mój nowy projekt czystego źródła. Mam ambicję, by stał się on najlepszą darmową bazą do rozpoczęcia pracy nad własnym serwerem. Stawiając na jakość i chcąc być na bieżąco z najnowszymi standardami C++, postanowiłem przeprowadzić solidną przebudowę struktury DynamicCharacterPtr. __________________________________________________________________________________________________________________ char.cpp Szukamy: Zamieniamy na : _______________________________________________________________________________________________ char.h Szukamy: Zamieniamy na :
-
Nathan. obserwuje zawartość [C++] Konwersja formatu czasu.
-
Dziś przedstawię Wam sposób, by uczynić wyświetlanie czasu w przedmiotach bardziej intuicyjnym. Chciałbym Wam pokazać, jak dodać brakującą jednostkę sekund oraz jak zamienić skrócone nazwy jednostek czasu na ich pełne wersje, tak aby były one bardziej zrozumiałe dla każdego gracza. Dodatkowo dostosujemy wyświetlanie ich do polskiej lokalizacji jednostek czasu. Plik: root -> localeInfo.py Szukamy: Zamieniamy całą funkcje na: nad def SecondToDHM(time): dodajemy: root -> uiToolTip.py Szukamy: Zamieniamy na : Szukamy: Zamieniamy na : Szukamy: Dodajemy pod: Jak to wygląda? Filmik poniżej.
-
Gildia Banany zaprasza na Gromo 🙂
-
Wszystko na stronie Gromo.PL działa okej z klientem już.
-
Szukam serwera w starym stylu | Metin2
Nathan. odpowiedział(a) na temat walonewiadro123 w Metin2 - Serwery Prywatne
Jeśli chodzi o typowy klasyk to Gromo.pl, max 99lv bez szarf, alchemii i trzyma się bardzo długo bo od listopada 2019r ! Jeden z nielicznych serwerów do którego po przerwie można wrócić do gry bo konto nadal będzie, wieczorami zawsze więcej osób 😉 -
Stałe 60fps po alt+tab pomimo innego limitu
Nathan. odpowiedział(a) na temat mR.LoL? w League of Legends
Może masz włączone jakieś programy zewnetrzne typu blitz, porofessor? mi przy porofessorze tak wlasnie sie robiło ze 60fps a klatkowało strasznie. -
A nie wiem, troche ludzi jest. Opłaca się jak najbardziej, serwer naprawde ma klimacik i GM'owie są na straży i banują boty. Teraz niedługo będzie update to może graczy przybędzie ;)
-
Polecam '' Supernatural - nie z tego świata ''
-
Ma ktoś link do tego python'a?
