Skocz do zawartości

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...

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...