Skocz do zawartości
Masz już aplikację Sharegon?

Odkryj wszystkie możliwości. Dowiedz się więcej

Sharegon.pl

Zainstaluj aplikację Sharegon i korzystaj z powiadomień push oraz licznika nowych aktywności bezpośrednio z ekranu głównego.

Aby zainstalować tę aplikację na iOS i iPadOS.
  1. Tap the Share icon in Safari
  2. Przewiń menu i stuknij Dodaj do ekranu początkowego.
  3. Stuknij Dodaj w prawym górnym rogu.
Zainstaluj aplikację Sharegon na Androidzie
  1. Otwórz Sklep Google Play na swoim smarfonie.
  2. Wyszukaj „Sharegon” w pasku wyszukiwania.
  3. Stuknij „Zainstaluj”, aby pobrać aplikację.

Naprawa błędu dodawania pustych komentarzy w systemie Gildii

Nieaktywny

Featured Replies

Opublikowano

image.png.a144663d4007d16872d3413c4a1a8bf3.png

 

Cześć,

 

Ostatnio podczas prac przy funkcji obsługującej komentarze gildii natknąłem się na kolejny istotny błąd. Gdy próbujemy wysłać komentarz do gildii wstawiając same białe znaki (np. spacje), funkcja odpowiadająca za dodawanie komentarza, doda go bez problemu. W prawidłowym przypadku taka wiadomość nie powinna zostać wysłana, a gracz powinien otrzymać komunikat, który go informuje o błędzie w wysyłaniu pustych wiadomości lub składających się tylko z białych znaków. Nie widziałem rozwiązania tego problemu w żadnym innym miejscu, dlatego przygotowałem dla Państwa poprawkę tego błędu.

 

Poprawka polega na wprowadzeniu dodatkowego warunku w funkcji odpowiedzialnej za dodawanie komentarzy. Warunek ten sprawdza, czy komentarz zawiera jakiekolwiek znaki oprócz białych znaków. Jeśli komentarz nie zawiera żadnych znaków, to funkcja zwraca komunikat błędu.

 

Przedstawienie błędu

Przedstawienie rozwiązania

 

Implementacja:

📂 Lokalizacja pliku: 'game -> guild.cpp'

 

🔍 Szukaj

🔐 Ukryta Treść 🔐

 

🔐 Ukryta Treść 🔐

 

 Dodaj:

🔐 Ukryta Treść 🔐

 

 

📂 Lokalizacja pliku: 'game -> utilis.h'

 

🔍 Szukaj

🔐 Ukryta Treść 🔐

 

  Dodaj:

🔐 Ukryta Treść 🔐

 

 

 📂 Lokalizacja pliku: 'share -> locale -> poland -> locale_string.txt'

 

   Dodaj:

🔐 Ukryta Treść 🔐
Opublikowano

Super!

To jeszcze poproszę na ten kostium nieszczęsny 😄

 

Cytat

guild.cpp:1030:36: error: use of undeclared identifier 'comment'
        if (checkForWhitespaceOnlyOrEmpty(comment))
                                          ^
guild.cpp:1044:1: error: function definition is not allowed here
{
^

 

Opublikowano

Można jeszcze dodać pewną zmianę do tego fixa. W momencie, gdy zaimplementujemy limit czasowy 1 minuta = 1 wiadomość oraz blokade wysyłania pustych wiadomości. To po próbie wysłania pustej wiadomości nadal otrzymujemy blokadę na jedną minutę. Teorytycznie nie wysłaliśmy żadnej wiadomości, a więc ta blokada jest nie potrzebna.

 

Skonstruowałem rozwiązanie, @Sevence jeśli zauważy w tym jakiś problem to popraw jeśli możesz i jeśli zdecydujesz to wstaw do posta.

Jak to działa po poprawce:


 

Spoiler

 Plik -> guild.cpp

 

Szukamy funkcji jak w temacie

void CGuild::AddComment(LPCHARACTER ch, const std::string& str)

Pod:

auto now = std::chrono::steady_clock::now();

Dodajemy nową zmienną która śledzi, czy ostatnia wiadomość była pusta:
 

static bool lastMessageWasEmpty = false;

 

Szukamy

if (checkForWhitespaceOnlyOrEmpty(str))

Zmieniamy:

	if (checkForWhitespaceOnlyOrEmpty(str)) 
	{
		lastMessageWasEmpty = true;
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NOTIFICATION_EMPTY_COMMENT_GUILD"));
		return;
	}

Pod całą instrukcją warunkową dodajemy:

lastMessageWasEmpty = false;

 

 

Poprawna implementacja:

 

Spoiler
void CGuild::AddComment(LPCHARACTER ch, const std::string& str)
{
	auto now = std::chrono::steady_clock::now();
	static bool lastMessageWasEmpty = false;
	if (now - lastCommentTime < FloodProtectionInterval) 
	{
		auto remainingTime = std::chrono::duration_cast<std::chrono::seconds>(FloodProtectionInterval - (now - lastCommentTime)).count();
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NOTIFICATION_ADD_COMMEND_GUILD_FLOOD_PROTECTION_%lld"), remainingTime);
		return;
	}

	
	if (str.length() > GUILD_COMMENT_MAX_LEN)
		return;

	if (checkForWhitespaceOnlyOrEmpty(str)) 
	{
		lastMessageWasEmpty = true;
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("NOTIFICATION_EMPTY_COMMENT_GUILD"));
		return;
	}
	lastMessageWasEmpty = false;
	lastCommentTime = now;

	char text[GUILD_COMMENT_MAX_LEN * 2 + 1];
	DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length());

	DBManager::instance().FuncAfterQuery(std::bind(&CGuild::RefreshCommentForce,this, ch->GetPlayerID()),
			"INSERT INTO guild_comment%s(guild_id, name, notice, content, time) VALUES(%u, '%s', %d, '%s', NOW())", 
			get_table_postfix(), m_data.guild_id, ch->GetName(), (str[0] == '!') ? 1 : 0, text);
}

 

 

Edytowane przez atk

Opublikowano
  • Autor

Nie ma potrzeby tworzenia flagi do śledzenia stanu. Tak naprawdę, wystarczy tylko przenieść warunek sprawdzający białe znaki przed warunek kontroli czasu. Zaktualizowałem temat. 

 

void CGuild::AddComment(LPCHARACTER ch, const std::string& str)
{
	auto now = std::chrono::steady_clock::now();
	
	if (checkForWhitespaceOnlyOrEmpty(str)) 
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "[LS;304]");
		return;
	}
	
	if (now - lastCommentTime < FloodProtectionInterval) 
	{
		auto remainingTime = std::chrono::duration_cast<std::chrono::seconds>(FloodProtectionInterval - (now - lastCommentTime)).count();
		ch->ChatPacket(CHAT_TYPE_INFO, "[LS;303;%lld]", remainingTime);
		return;
	}

	lastCommentTime = now;

	if (str.length() > GUILD_COMMENT_MAX_LEN || str.length() == 0) 
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "[LS;305]");
		return;
	}
  
	...
}

 

  • 4 tygodnie później...
Opublikowano

Muszę zobaczyć.

Sprawdzanie samych pustych komentarzy tutaj nie wystarczy.

Problem jest taki, że nie ma scrolla w gui od okna komentarzy gildyjnych, a nie każdy wie chyba, że można nimi zapchać baze. 

Powyższe poprawki dalej zapychaja baze tylko wolniej..

Tutaj potrzeba cooldown + limit komentarzy do 10.

 

To jest jeden z poważniejszych exploitow które wykorzystuja ludzie skryptem gdzieś widziałem go o Turków.

 

 

Edytowane przez Marchewa

  • 2 tygodnie później...
Opublikowano

rozwiązanie dla starszych wersji:

 

📂 Lokalizacja pliku: 'game -> utilis.h'

zamiast tego:

inline bool checkForWhitespaceOnlyOrEmpty(const std::string& str)
{
	return std::all_of(str.begin(), str.end(), [](unsigned char c) { return std::isspace(c) || c == '\0';});
}

 

dodaj to:

inline bool checkForWhitespaceOnlyOrEmpty(const std::string& str)
{
	for (size_t i = 0; i < str.size(); ++i)
	{
		unsigned char c = str[i];
		if (!(std::isspace(c) || c == '\0'))
		{
			return false;
		}
	}
	return true;
}

 

Edytowane przez Denis

  • 1 miesiąc temu...

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Konto

Nawigacja

Skonfiguruj powiadomienia push w przeglądarce.

Chrome (Android)
  1. Stuknij ikonę kłódki obok paska adresu.
  2. Wybierz Uprawnienia → Powiadomienia.
  3. Dostosuj swoje preferencje.
Chrome (Desktop)
  1. Kliknij ikonę kłódki na pasku adresu.
  2. Wybierz Ustawienia witryny.
  3. Znajdź Powiadomienia i dostosuj swoje preferencje.