Register for your free account! | Forgot your password?

You last visited: Today at 17:54

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Release] Double-Affect Bugfix

Discussion on [Release] Double-Affect Bugfix within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.

Reply
 
Old   #1
 
elite*gold: 26
Join Date: Oct 2011
Posts: 1,262
Received Thanks: 1,062
[Release] Double-Affect Bugfix

Guten Abend,

da ich vor einigen Monaten mal ein Video gefunden habe in dem es einem User gelungen ist die Boni eines Items der Typen USE_AFFECT&USE_BLEND zu verdoppeln und bis jetzt noch kein akzeptabler Lösungsweg veröffentlicht wurde, dachte ich mir, dass es mal wieder an der Zeit ist etwas anständiges zu veröffentlichen.

Hier mal eine Anleitung wie man den Bug ausnutzt (um die ganzen Leute mit einem gamecore < 40k mal ein bisschen in Zugzwang zu bringen )
Funktioniert mit:
  • Drachengott-Angriff, -Verteidigung, ...
  • Taus
  • Gebraute Tränke
  • Kritischer Treffer
  • evtl. EXP-Ringe (?)
  • Medallie des Glücks
  • Handschuhe des Diebes (?)
  • [...]
Anleitung:
  • Benutze ein Item des Typen ITEM_BLEND oder ITEM_AFFECT (bspw. Drachengott-Angriff oder Taus)
  • Optional: Lege das verwendete Item in deine Quickslot Leiste
  • Begib dich in die Charakterauswahl und wähle deinen Charakter aus
  • Spame bereits im Ladebildschirm die zugewiesene Taste des Items in deiner Quickslot Leiste
  • Herzlichen Glückwunsch! Du hast erfolgreich deinen Bonus verdoppelt.

Also, dann lasst uns das ganze mal reparieren.
Ich nehme nur mal eine Sache vorweg. Ich gebe euch keinen fertigen Code, wenn ihr das ganze lösen wollt, dann könnt ihr euch das hier durchlesen und ein bisschen euer Hirn anstrengen.

Als erstes sollten wir uns mal überlegen, wieso dieser Bug überhaupt auftritt.
Beim Verwenden eines Items der zuvor genannten Typen sollte ja eigentlich überprüft werden, ob der Affect bereits auf unseren Charakter wirkt. Wenn wir ein bisschen nach USE_AFFECT suchen, werden wir feststellen, dass bereits überprüft wird, ob der Affect des Items bereits wirkt. Falls dem so ist, returned die Funktion ja scheinbar false. Wieso ist es also trotzdem möglich, Boni zu verdoppeln?
Hmm.. Wenn wir uns die FindAffect Funktion anschauen, dann werden wir feststellen, dass wir durch eine Liste iterieren und dann, je nachdem ob der Affect bereits wirkt oder nicht, einen Pointer zu dem Affect oder einen nullpointer returnen. Naja.. Scheint ja zu passen, oder?
Dann muss es wohl daran liegen, dass die Liste zu dem Zeitpunkt der Abfrage noch leer ist. Demnach muss die Ladefunktion der Affects zu dem Zeitpunkt wohl noch nicht gecallt worden sein.
Wir erinnern uns zurück - der Bug funktioniert nur, wenn wir das Item sofort(!) nach dem Relog nochmals verwenden.

Die Affects sollten, wenn wir logisch darüber nachdenken, bei jedem Login automatisch geladen werden, da sie ja sonst nach jedem Relog oder Serverdown verschwunden wären. Wenn wir uns ein bisschen umschauen, und uns die Ladefunktion der Affects raussuchen (CHARACTER::LoadAffect) dann werden wir ein ein Problem feststellen, denn die LoadAffect-Methode wird nicht direkt beim Login aufgerufen. Hmm.. Das ist ziemlich Blöd und der Grund, wieso der Bug überhaupt möglich ist, da ansonsten ja alle Affects direkt geladen wären, die FindAffect Funktion einen validen Pointer auf ein CAffect Object returnen würde und demnach das Verwenden des Items nicht möglich wäre.
Wir sollten also die Nutzung von AFFECT Items unterbinden, solange die LoadAffect-Methode noch nicht aufgerufen wurde. Natürlich sticht uns da direkt m_bIsLoadedAffect ins Auge, da diese Variable am Ende der LoadAffect-Methode auf true gesetzt wird.
Was für ein Zufall. YMIR hat uns sogar schon eine Methode gebaut die wir verwenden können:
bool CHARACTER::IsLoadedAffect();

Gehen wir mal zurück in den Item-Part der CHARACTER Klasse und suchen einfach mal nach einem Fall, in den wir diesen Check einbauen müssen. Nach einer kurzen Suche nach USE_AFFECT werden wir auch direkt fündig (case USE_AFFECT).
Wir sehen einen FindAffect-Check und sollten demnach einfach davor checken, ob die LoadAffect-Methode bereits ausgeführt wurde.
Ich packe also direkt unter den jeweiligen Case (in meinem Beispiel USE_AFFECT) den IsLoaded Check.

Code:
[...]
case USE_AFFECT:
{
     if(!IsLoadedAffect())
     {
           //evtl. noch eine Ausgabe an den User einbauen ♥
           return false;
     }
[...]
}
Perfekt. Das wars also schon, oder?
Nein.
Wenn wir uns ein bisschen weiter mit m_bIsLoadedAffect beschäftigen, werden wir sehen, dass es standardmäßig auf false gesetzt ist und die LoadAffect-Methode ausgeführt werden muss, damit m_bIsLoadedAffect auf true gesetzt wird.

Damit dem so ist, müssen wir dafür sorgen, dass die LoadAffect Methodeimmer beim Login ausgeführt wird. Wenn wir uns ein bisschen im Source umschauen, werden wir feststellen, dass die LoadAffect-Methode durch ein eintreffendes Paket des dbcache ausgeführt wird (CInputDB::AffectLoad(LPDESC d, const char* c_pData). Es handelt sich hierbei um das Paket HEADER_DG_AFFECT_LOAD, welches der dbcache jedoch nur versendet, wenn mindestes ein Affect in der player.affect Tabelle gefunden wird. Ansonsten returned er und sendet das Paket nicht.
-> Die LoadAffect-Methode wird also nie aufgerufen!

Naja.. Das ist für uns ein bisschen unvorteilhaft, da wir ja das Verwenden von USE_AFFECT-Items verbieten, wenn die LoadAffect-Methode nicht ausgeführt wurde. Um das zu Lösen, müssen wir das AFFECT_LOAD Paket auch versenden, wenn kein Affect gefunden wurde. Wir senden also einfach ein leeres Paket in dem wir nur die PlayerID und die Anzahl der gefunden Affects (also 0) mitsenden.
Dazu nehmen wir einfach das schon bestehende if-Statement in der CClientManager::RESULT_AFFECT_LOAD und versenden ein "leeres" Paket.
Code:
if ((iNumRows = mysql_num_rows(pRes)) == 0)
{
	DWORD count = 0;
	sys_log(0, "AFFECT_LOAD: NOT LOADING AFFECT FOR %d - NO RESULTS FOUND!", dwPID);
	peer->EncodeHeader(HEADER_DG_AFFECT_LOAD, dwHandle, sizeof(DWORD) + sizeof(DWORD));
	peer->Encode(&dwPID, sizeof(DWORD));
	peer->Encode(&count, sizeof(DWORD));
	return;
}
[...]
Außerdem erweitert ihr die Argumentenliste von RESULT_AFFECT_LOAD um ein Argument.
Code:
void CClientManager::RESULT_AFFECT_LOAD(CPeer* peer, MYSQL_RES* pRes, DWORD dwHandle)

// wird zu

void CClientManager::RESULT_AFFECT_LOAD(CPeer* peer, MYSQL_RES* pRes, DWORD dwHandle, DWORD dwPID)
RESULT_AFFECT_LOAD wird im ClientManagerPlayer genau einmal aufgerufen. Sucht dazu einfach mal nach case QID_AFFECT, kann man eigentlich nicht verfehlen. Um die Methode auch wirklich verwenden zu können, müssen wir die Player-ID natürlich auch beim Aufruf der Methode übergeben.

Code:
RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle);
//wird zu
RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
(Zum Glück speichert die ClientHandleInfo die player_id bereits, weniger Arbeit für uns, yay!)

Wenn ihr euch bis hierhin durchgequält habt, habt ihr das Problem gelöst!
Glückwunsch.

WICHTIG:
Diese Änderung bitte ebenfalls durchführen. Betrifft die ClientManagerPlayer.cpp:
Code:
CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle));
//ändern zu
CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id));
Das Kopieren dieses Posts in andere Foren ist ohne meine Erlaubnis nicht gestattet.

Greetz,
Socialized
He3o Crysis is offline  
Thanks
24 Users
Old 11/19/2016, 20:07   #2
 
elite*gold: 260
Join Date: Jan 2013
Posts: 178
Received Thanks: 104
Thanks it was fixed in my files like for ages and finally someone noticed it and fixed it.

This is an important fix and will be important for many users here.

Thanks again
Metin2 Team is offline  
Thanks
1 User
Old 11/19/2016, 21:35   #3


 
MrTherzon's Avatar
 
elite*gold: 0
The Black Market: 180/0/1
Join Date: Dec 2012
Posts: 9,390
Received Thanks: 2,738
Nice Danke Socialized,

grüße das Team von mir
MrTherzon is offline  
Thanks
2 Users
Old 11/19/2016, 22:12   #4

 
LxR'EsoZiaL's Avatar
 
elite*gold: 15
Join Date: Mar 2010
Posts: 4,270
Received Thanks: 2,499
Eine Zeitverzögerung mit 2 Sekunden nach nutzen + Login hätten es auch getan.

Dazu ist dein How² krass umständlich geschrieben.

Für die Leute die kein Plan haben in welchen Dateien das alles steht:
DB :
ClientManager.h
ClientManagerPlayer.cpp
game:
char_item.cpp
LxR'EsoZiaL is offline  
Thanks
2 Users
Old 11/19/2016, 22:31   #5
 
elite*gold: 26
Join Date: Oct 2011
Posts: 1,262
Received Thanks: 1,062
Quote:
Originally Posted by LxR'EsoZiaL View Post
Eine Zeitverzögerung mit 2 Sekunden nach nutzen + Login hätten es auch getan.

Dazu ist dein How² krass umständlich geschrieben.

Für die Leute die kein Plan haben in welchen Dateien das alles steht:
DB :
ClientManager.h
ClientManagerPlayer.cpp
game:
char_item.cpp
Naja.
Das Problem zu umschiffen und es im Kern zu lösen sind zwei unterschiedliche Paar Schuhe. (Will da jetzt aber nicht drüber diskutieren, ist mir echt zu blöde)

Das Ding ist absichtlich so umständlich geschrieben, dass Leute die Bock haben nen bisschen Einsicht bekommen und an der Hand genommen werden und selber auf die Lösung kommen. Kann man sicher besser machen, war aber im Stress und hab da ab der hälfte alles hingeschaufelt.

Leute die darauf keinen Bock haben sind bei mir sowieso unten durch, ich unterstütze keine kompletten Copy&Paste **** mehr.
He3o Crysis is offline  
Thanks
2 Users
Old 11/19/2016, 22:33   #6

 
LxR'EsoZiaL's Avatar
 
elite*gold: 15
Join Date: Mar 2010
Posts: 4,270
Received Thanks: 2,499
Quote:
Originally Posted by Socialized View Post
Naja.
Das Problem zu umschiffen und es im Kern zu lösen sind zwei unterschiedliche Paar Schuhe. (Will da jetzt aber nicht drüber diskutieren, ist mir echt zu blöde)

Das Ding ist absichtlich so umständlich geschrieben, dass Leute die Bock haben nen bisschen Einsicht bekommen und an der Hand genommen werden und selber auf die Lösung kommen. Kann man sicher besser machen, war aber im Stress und hab da ab der hälfte alles hingeschaufelt.

Leute die darauf keinen Bock haben sind bei mir sowieso unten durch, ich unterstütze keine kompletten Copy&Paste **** mehr.
Ah okay verstehe ich schon.

Es wäre besser ein paar Vorlagen zu posten, wie einfache Schleifen und Arrays. Ein paar Bonus Erweiterungen oder ein Login Message Script. So das man sich nicht direkt in die Tiefste Materie stürzt.
LxR'EsoZiaL is offline  
Thanks
2 Users
Old 11/19/2016, 22:45   #7
 
#..SyNTeX..<3's Avatar
 
elite*gold: 0
Join Date: Aug 2014
Posts: 1,142
Received Thanks: 650
Super danke dir.
Und gut erklärt auch für jemanden wie mich der nicht soviel Erfahrung hat.
#..SyNTeX..<3 is offline  
Old 11/19/2016, 23:04   #8
 
elite*gold: 0
The Black Market: 105/0/0
Join Date: May 2016
Posts: 8,679
Received Thanks: 1,638
Sieht sauber aus.

Danke für den RLS
悪地城 is offline  
Old 11/20/2016, 01:07   #9
 
Gl0bal's Avatar
 
elite*gold: 8
Join Date: Oct 2010
Posts: 564
Received Thanks: 906
Nice muss ich bei mir noch einbauen

MfG Gl0bal
Gl0bal is offline  
Old 11/22/2016, 11:51   #10
 
.Mr ElefiN's Avatar
 
elite*gold: 19
Join Date: Nov 2016
Posts: 54
Received Thanks: 15
sehr hilfreich danke
.Mr ElefiN is offline  
Old 11/22/2016, 13:40   #11
 
»DeneX«'s Avatar
 
elite*gold: 0
Join Date: Jul 2015
Posts: 1,383
Received Thanks: 566
Danke fürs teilen, gab lange keine Lösung dafür.
»DeneX« is offline  
Old 11/27/2016, 17:05   #12

 
9TAILS's Avatar
 
elite*gold: 1308
Join Date: Jun 2012
Posts: 1,104
Received Thanks: 74
Vielen Dank, nach all den Jahren ein Fixx für diese Scheiße Göttlich, das schmeckt !
9TAILS is offline  
Old 04/19/2017, 23:51   #13
 
elite*gold: 20
Join Date: Feb 2017
Posts: 168
Received Thanks: 73
Wollt ihr ganz einfach denn Client Part haben, womit man das sperrt?
Wenn ja einfach kommentieren.
.'Avenir is offline  
Reply


Similar Threads Similar Threads
[Release] Wizard auto attack bugfix from database
01/02/2018 - SRO PServer Guides & Releases - 18 Replies
#requestdelete
[RELEASE][ZEHPLUSPLUS][BUGFIX] OX-Event
05/28/2015 - Metin2 PServer Guides & Strategies - 22 Replies
Liebe Community, ich release hier einen Fix für 'nen Bug im OX-Event, der es Spielern möglich macht, sich direkt nach dem teleportieren auszuloggen und sich dann nach auflösen einer Frage wieder an der gleichen Position einzuloggen und, trotz Logout, weiter am OX-Event teilzunehmen. bool COXEventManager::EnterAttender(LPCHARACTER pkChar) { // if (GetStatus() != OXEVENT_OPEN) { sys_err("cannot join ox %u %s (oxevent is not open)", pkChar->GetPlayerID(), pkChar->GetName());
[Release] CheckClientVersion Compare-BugFix
12/30/2013 - Metin2 PServer Guides & Strategies - 32 Replies
If u don't know, in the client and in the game there's a "number" (a const char* converted as a number with atoi in game, ps. atoi evaluates to 0 if the "number" contains characters not-digits) The default value is 1215955205 (g_stClientVersion), if the client version is smaller than the game ur character'll disconnect in 10 seconds with a message like this "U must patch the client to play" (u can declare it in locale_string.txt) The problem is this: client 1215955205 server 1215955205 =...



All times are GMT +1. The time now is 17:54.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.