Guten Morgen,
ihr fragt euch nun was soll dieser Thread.
Ich werde es euch nun einmal erklären,
hier bei soll es sich um einen Thread handeln der immer wieder geupdatet wird.
Rund um den Source versteht sich natürlich.
Ich würde mich sehr freuen wenn dieser Thread eine "Communityarbeit" wird,
sprich Leute sich daran beteiligen diesen Thread mit Tutorials zu schmücken.
Werde dann natürlich die Quelle sprich Name dazu schreiben.
Tutorials die nur Serverseitig sind:
Tutorials die nur Clientseitig sind:
Tutorials die Serverseitig und Clientseitig sind:
Sicherheitsfixxes
Klein Kram Serverseitig
Ich hoffe jemand kann den Thread wegen den Bildern zitieren.
Mehrere Dinge werden im laufe des noch folgen.
ihr fragt euch nun was soll dieser Thread.
Ich werde es euch nun einmal erklären,
hier bei soll es sich um einen Thread handeln der immer wieder geupdatet wird.
Rund um den Source versteht sich natürlich.
Ich würde mich sehr freuen wenn dieser Thread eine "Communityarbeit" wird,
sprich Leute sich daran beteiligen diesen Thread mit Tutorials zu schmücken.
Werde dann natürlich die Quelle sprich Name dazu schreiben.
Tutorials die nur Serverseitig sind:
Party Flag:
(Dies ermöglicht euch, dass ein Skill den jemand in der Gruppe aktiviert hat und du in der Range stehst auch diesen Skill hast. Sprich z.B Segen, damit bräuchte man nicht jeden einzeln in der Gruppe buffen. Sondern alle neben den Schamanen stellen, er bufft sich selber und dann sind alle gebufft. Nur um das Prinzip davon zu erklären.)
Wir öffnen in game/skill.h
Suchen nach
Sieht unbearbeitet so aus:
Wenn dort jetzt nicht
steht,
bitte die IMMER die letzte Zeile neben und auch die Zahl wie hier z.B nach
in diesem Fall jetzt:
Wenn ihr das gemacht habt sieht es so aus:
Nun öffnen wir game/char_skill.cpp
Dort suchen wir nach:
Danach fügen wir diesen Code ein:
Das sieht dann so aus:
Dann suchen wir in der selben Datei nach:
Und fügen das darunter ein:
Das sieht dann so aus:
Diesen Schritt müsst ihr zweimal machen!!
Dann sucht ihr in der selben Datei nach:
Setzt darunter:
Sieht dann so aus:
Suchen dann in game/guild.cpp nach:
Setzen darunter:
Dann sind wir auch schon fertig, nun müsst ihr in der Skill_proto noch den "setFlag" anpassen, hinter FIRE kommt dann Party, sollte es in der "setFlag" nicht an 27er Stelle sein funktioniert es nicht, da die Datenbank die Zahlen vom Source abruft!
Suchen nach
Code:
SKILL_FLAG_FIRE
Wenn dort jetzt nicht
Code:
SKILL_FLAG_FIRE
bitte die IMMER die letzte Zeile neben und auch die Zahl wie hier z.B nach
Code:
(1 << 26),
Code:
(1 << 27),
Nun öffnen wir game/char_skill.cpp
Dort suchen wir nach:
Code:
SKILL_RESIST_PENETRATE
Code:
struct FPartyPIDCollector
{
std::vector <DWORD> vecPIDs;
FPartyPIDCollector()
{
}
void operator () (LPCHARACTER ch)
{
vecPIDs.push_back(ch->GetPlayerID());
}
};
Dann suchen wir in der selben Datei nach:
Code:
if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) pkVictim = this;
Code:
if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && !GetParty()) pkVictim = this;
Diesen Schritt müsst ihr zweimal machen!!
Dann sucht ihr in der selben Datei nach:
Code:
if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) ComputeSkill(dwVnum, this);
Code:
else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && !GetParty())
ComputeSkill(dwVnum, this);
else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && GetParty())
{
FPartyPIDCollector f;
GetParty()->ForEachOnMapMember(f, GetMapIndex());
for (std::vector <DWORD>::iterator it = f.vecPIDs.begin(); it != f.vecPIDs.end(); it++)
{
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(*it);
ComputeSkill(dwVnum, ch);
}
}
Suchen dann in game/guild.cpp nach:
Code:
if ((pkSk->dwFlag & SKILL_FLAG_SELFONLY))
{
// ÀÌ¹Ì °É·Á ÀÖÀ¸¹Ç·Î »ç¿ëÇÏÁö ¾ÊÀ½.
if (ch->FindAffect(pkSk->dwVnum))
return;
victim = ch;
}
Code:
if ((pkSk->dwFlag & SKILL_FLAG_PARTY))
{
if (ch->FindAffect(pkSk->dwVnum))
return;
victim = ch;
}
Tutorials die nur Clientseitig sind:
Kommt noch
Tutorials die Serverseitig und Clientseitig sind:
Stone Slots erweitern:
Handelsfenster erweitern
Quelle: gerald500
Levelanzeige aktualisiert sich nach Levelup nicht direkt:
Großes Dankeschoen an Sanii dafür, die Erlaubnis habe ich natürlich.
Lagererweiterung:
Habe die dump_proto in den Anhang gepackt.
Danke dafür nochmal an Sanii.
Fangen wir Serverseitig an:
In der Datei common/item_length.h suchen wir nach:
ändern das zu:
Öffnen die Datei: db/ClientManager.cpp und suchen nach:
Ersetzen das mit dem:
Dann sind wir mit dieser Datei fertig und kann abgespeichert werden.
Öffnen folgende Datei: db/cache.cpp suchen dort nach folgendem Teil
ersetzen das mit diesem Code:
Wenn wir das gemacht haben speichern wir das ab
Nun gehen wir öffnen wir db/clientmanagerplayer.cpp und suchen nach:
Darunter fügen wir folgendes hinzu:
Dann suchen wir in der selben Datei nach:
Und ersetzen das mit dem:
Dann suchen wir nochmals in der selben Datei nach:
Und ersetzen das mit dem:
Dann sind wir auch fertig mit dieser Datei und können sie abspeichern.
Dann öffnen wir die Datei game/constants.cpp und suchen nach:
Wer keinen Lykaner eingebaut hat, lässt die "CLAW" weg!!
Und ersetzen das mit dem:
Dann suchen wir in der selben Datei nach:
Und ersetzen das mit:
Wenn man nun z.B 6 Slots haben möchte für ein bestimmtes Item muss man dies natürlich in der Datenbank dort item_proto die socket_pct dem entsprechend anpassen.
Nun ist Serverseitig alles fertig.
Nun zum Clientteil:
Vorab, wer mehr als 3 Slots verwendet muss noch die Sockets in der Item_proto Clientseitig einfügen, werde euch dafür die Offizielle Item_proto von DE abgeändert mit 6 Slots in den Anhang packen. Serverseitig geht es Standard gemäß bis zu 6 Slots.
Dort öffnen wir die Datei userinterface/gametype.h und suchen nach:
Das ersetzen wir Logischerweise mit
Danke dafür nochmal an Sanii.
Fangen wir Serverseitig an:
In der Datei common/item_length.h suchen wir nach:
Code:
ITEM_SOCKET_MAX_NUM = 3,
Code:
ITEM_SOCKET_MAX_NUM = 6,
Code:
"SELECT id, window+0, pos, count, vnum, socket0, socket1, socket2, "
Code:
"SELECT id, window+0, pos, count, vnum, socket0, socket1, socket2, socket3, socket4, socket5, "
Öffnen folgende Datei: db/cache.cpp suchen dort nach folgendem Teil
Code:
if (isSocket)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2");
iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
", %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]);
iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
", socket0=%lu, socket1=%lu, socket2=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]);
}
Code:
if (isSocket)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2, socket3, socket4, socket5");
iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
", %lu, %lu, %lu, %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]);
iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
", socket0=%lu, socket1=%lu, socket2=%lu, socket3=%lu, socket4=%lu, socket5=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]);
}
Nun gehen wir öffnen wir db/clientmanagerplayer.cpp und suchen nach:
Code:
str_to_number(item.alSockets[2], row[cur++]);
Code:
str_to_number(item.alSockets[3], row[cur++]); str_to_number(item.alSockets[4], row[cur++]); str_to_number(item.alSockets[5], row[cur++]);
Code:
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
Code:
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
Code:
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
Code:
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
Dann öffnen wir die Datei game/constants.cpp und suchen nach:
Wer keinen Lykaner eingebaut hat, lässt die "CLAW" weg!!
Code:
3, // WEAPON_SWORD, 3, // WEAPON_DAGGER, 3, // WEAPON_BOW, 3, // WEAPON_TWO_HANDED, 3, // WEAPON_BELL, 3, // WEAPON_FAN, 3, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR
Code:
6, // WEAPON_SWORD, 6, // WEAPON_DAGGER, 6, // WEAPON_BOW, 6, // WEAPON_TWO_HANDED, 6, // WEAPON_BELL, 6, // WEAPON_FAN, 6, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR
Code:
3, // ARMOR_BODY,
Code:
6, // ARMOR_BODY,
Nun ist Serverseitig alles fertig.
Nun zum Clientteil:
Vorab, wer mehr als 3 Slots verwendet muss noch die Sockets in der Item_proto Clientseitig einfügen, werde euch dafür die Offizielle Item_proto von DE abgeändert mit 6 Slots in den Anhang packen. Serverseitig geht es Standard gemäß bis zu 6 Slots.
Dort öffnen wir die Datei userinterface/gametype.h und suchen nach:
Code:
ITEM_SOCKET_SLOT_MAX_NUM = 3,
Code:
ITEM_SOCKET_SLOT_MAX_NUM = 6,
Handelsfenster erweitern
Quelle: gerald500
Fangen wir mit dem Clientteil an, öffnen UserInterFace/PythonExchange.h
dort suchen wir nach:
"Die 12 steht für 4x3 sprich 3 Reihen von Slots hoch und 4 Breit das heißt die ändern wie auf die Gewünschte Zahl ich habe das ganze erweitert auf 6 slots Breit und 6 slots hoch d.h bei mir ist die zahl 36."
Kommen zum Serverteil und öffnen game/exchange.h suchen nach:
"Die 12 wieder ändern gleich wie oben wie ihr das haben wollt oder eben auf 36 für 36 findet ihr im Anhang!"
öffnen dann game/exchange.cpp und suchen:
ersetzt:
mit
dort suchen wir nach:
Code:
enum
{
EXCHANGE_ITEM_MAX_NUM = 12,
};
Kommen zum Serverteil und öffnen game/exchange.h suchen nach:
Code:
enum EExchangeValues
{
EXCHANGE_ITEM_MAX_NUM = 12,
EXCHANGE_MAX_DISTANCE = 1000
};
öffnen dann game/exchange.cpp und suchen:
Code:
CExchange::CExchange(LPCHARACTER pOwner)
{
m_pCompany = NULL;
m_bAccept = false;
for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
m_apItems[i] = NULL;
m_aItemPos[i] = NPOS;
m_abItemDisplayPos[i] = 0;
}
m_lGold = 0;
m_pOwner = pOwner;
pOwner->SetExchange(this);
m_pGrid = M2_NEW CGrid(4,3);
}
Code:
m_pGrid = M2_NEW CGrid(4,3);
Code:
m_pGrid = M2_NEW CGrid(6,6);
Levelanzeige aktualisiert sich nach Levelup nicht direkt:
Großes Dankeschoen an Sanii dafür, die Erlaubnis habe ich natürlich.
ihr kennt ja sicher folgende Problematik:
Ihr levelt und levelt, aber die Levelanzeige an eurem Namen steht noch immer auf dem Level mit dem ihr angefangen habt.
Ich hab rausgefunden was dort los war! Folgende Problematik:
Das Spielerlevel wird an den Clienten nur in der __Create__ mitgegeben.
Im UpdatePacket() fehlt es allerdings. Er führt im Verlaufe des UpdatePackets das RefreshTextTail() aus, welches das Level theoretisch auch wirklich aktualisiert mit dem wert "m_dwLevel". Dieser Wert wird aber nur gesetzt wenn der Spieler "Created" wird. Sprich Spawnen, Mounten etc.
Mit diesem Fix zeig ich euch wie ihr ganz einfach das Level in das UpdatePacket() einbaut!
Server:
In packet.h suchen:
unter
In char.cpp suchen:
unter
Client:
In Packet.h suchen:
unter
In PythonNetworkStreamPhaseGameActor.cpp suchen:
unter
In NetworkActorManager.cpp suchen:
unter
In NetworkActorManager.h suchen:
unter
In InstanceBase.cpp suchen:
unter der Funktion adden wir diese Funktion:
In InstanceBase.h suchen:
darunter hinzufügen:
Ihr levelt und levelt, aber die Levelanzeige an eurem Namen steht noch immer auf dem Level mit dem ihr angefangen habt.
Ich hab rausgefunden was dort los war! Folgende Problematik:
Das Spielerlevel wird an den Clienten nur in der __Create__ mitgegeben.
Im UpdatePacket() fehlt es allerdings. Er führt im Verlaufe des UpdatePackets das RefreshTextTail() aus, welches das Level theoretisch auch wirklich aktualisiert mit dem wert "m_dwLevel". Dieser Wert wird aber nur gesetzt wenn der Spieler "Created" wird. Sprich Spawnen, Mounten etc.
Mit diesem Fix zeig ich euch wie ihr ganz einfach das Level in das UpdatePacket() einbaut!
Server:
In packet.h suchen:
Code:
typedef struct packet_update_char
Code:
short sAlignment; hinzufügen: DWORD dwLevel;
Code:
void CHARACTER::UpdatePacket()
Code:
pack.sAlignment = m_iAlignment / 10; hinzufügen: pack.dwLevel = GetLevel();
Client:
In Packet.h suchen:
Code:
typedef struct packet_update_char
Code:
short sAlignment; hinzufügen: DWORD dwLevel;
Code:
bool CPythonNetworkStream::RecvCharacterUpdatePacket()
Code:
kNetUpdateActorData.m_sAlignment=chrUpdatePacket.sAlignment; hinzufügen: kNetUpdateActorData.m_dwLevel=chrUpdatePacket.dwLevel;
Code:
void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData)
Code:
pkInstFind->SetAlignment(c_rkNetUpdateActorData.m_sAlignment); hinzufügen: pkInstFind->SetLevel(c_rkNetUpdateActorData.m_dwLevel);
Code:
struct SNetworkUpdateActorData
Code:
short m_sAlignment; hinzufügen: DWORD m_dwLevel;
Code:
void CInstanceBase::SetAlignment(short sAlignment)
Code:
void CInstanceBase::SetLevel(DWORD level)
{
m_dwLevel = level;
RefreshTextTail();
}
Code:
void SetAlignment(short sAlignment);
Code:
void SetLevel(DWORD level);
Lagererweiterung:
Kommt
Sicherheitsfixxes
CrashFix Cube QUELLE WoM2 DEV
[FIX] quest::PC::GetFlag Crash
Quelle: Norri
Um diesen Exploit/Bug zu fixen muesst ihr in der char.cpp nach der folgenden Methode Suche:
und schreibt unter der Zeile:
folgendes:
Das gleiche macht ihr dann nochmal in der Funktion:
Damit ist dann dieser Exploit geschlossen.
Ich werde nicht sagen wie man diesen Exploit erzeugt oder durch welche Wege dieser ausgenutzt werden kann.
Nicht bekannt was der Fehler ist
"Wir (Dev Team von WoM2) werden noch keine Informationen über das herbeiführen des Crashes geben, da er auch in älteren eingesetzen Game Revisionen problemlos funktioniert (34k - 40k), früher auch auf DE aber die wurden von uns informiert und haben das beim Lycan launch gefixxt.
Mit freundlichen Grüßen
Das WoM2 Source Dev Team
Special thanks an Think mit dem ich damals rumgetüftelt habe
PS: Wenn ihr das kopiert gebt bitte die Quelle an Danke "
Sucht in game/src/cube.cpp nach
fügt darunter:
Sucht in der selben Datei nach:
und ersetz das mit dem hier:
Code:
resultCount = resultList.size();
Code:
if (resultCount == 0)
return;
Code:
if (false == bCatchInfo)
Code:
if (!bCatchInfo || materialInfoText.size() == 0)
Mit freundlichen Grüßen
Das WoM2 Source Dev Team
Special thanks an Think mit dem ich damals rumgetüftelt habe
PS: Wenn ihr das kopiert gebt bitte die Quelle an Danke "
[FIX] quest::PC::GetFlag Crash
Quelle: Norri
Hallo Community,
musste leider in den vergangen Tagen feststellen das es wieder ein Exploit gibt welchen den Game-Core zum Absturz bringt.
In dem BT der game.core findet man meist folgende Zeile quest::PC::GetFlag wo die Instanz ein NullPointer ist
musste leider in den vergangen Tagen feststellen das es wieder ein Exploit gibt welchen den Game-Core zum Absturz bringt.
In dem BT der game.core findet man meist folgende Zeile quest::PC::GetFlag wo die Instanz ein NullPointer ist
Um diesen Exploit/Bug zu fixen muesst ihr in der char.cpp nach der folgenden Methode Suche:
Code:
int CHARACTER::GetQuestFlag(const std::string& flag) const
Code:
quest::PC* pPC = q.GetPC(GetPlayerID());
Code:
if(!pPC) {
sys_err("Nullpointer in CHARACTER::GetQuestFlag %lu", GetPlayerID());
return 0;
}
Code:
void CHARACTER::SetQuestFlag(const std::string& flag, int value)
Ich werde nicht sagen wie man diesen Exploit erzeugt oder durch welche Wege dieser ausgenutzt werden kann.
Klein Kram Serverseitig
Muschel Dropp ändern bzw Chance
Quelle: .Callous
Quelle: .Callous
Wir öffnen game/src/char_item.cpp suchen dort nach:
Darunter finden wir dann z.B:
Welches den Drop der Steinstücke aus Muscheln bestimmt in diesem fall 50%
Diese Zeile hier:
Bestimmt das nichts aus der Muschel kommt das bezieht sich auf diese Zeile hier:
Wenn ihr den Sinn dahinter versteht könnt ihr diese beliebig ändern, könnt dort auch eine Item hinterlegen, dies könnt ihr dann von den Perlen Zeilen abgucken zu denen wir jetzt kommen.
Hier einmal die Chancen der Muscheln:
Dort wird aber rückwärts gerechnet sprich 95% sind 5%, 97% sind 3% und 99% 1%
Diese Chancen beziehen sich auf
Das in die Codes der Perlen diese könnt ihr nun abändern oder einfach nur die Prozente ändern.
Code:
case 27987:
Code:
{
item->SetCount(item->GetCount() - 1);
int r = number(1, 100);
if (r <= 50)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¶°³¿¡¼* µ¹Á¶°¢ÀÌ ³ª¿Ô½À´Ï´Ù."));
AutoGiveItem(27990);
}
Diese Zeile hier:
Code:
const int prob_table_euckr[] =
{
80, 90, 97
};
Code:
if (r <= prob_table[0])
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¶°³°¡ ÈçÀûµµ ¾øÀÌ »ç¶óÁý´Ï´Ù."));
}
Hier einmal die Chancen der Muscheln:
Code:
const int prob_table_gb2312[] =
{
95, 97, 99
};
Diese Chancen beziehen sich auf
Code:
else if (r <= prob_table[1])
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¶°³¿¡¼* ¹éÁøÁÖ°¡ ³ª¿Ô½À´Ï´Ù."));
AutoGiveItem(27992);
}
else if (r <= prob_table[2])
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¶°³¿¡¼* ûÁøÁÖ°¡ ³ª¿Ô½À´Ï´Ù."));
AutoGiveItem(27993);
}
else
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¶°³¿¡¼* ÇÇÁøÁÖ°¡ ³ª¿Ô½À´Ï´Ù."));
AutoGiveItem(27994);
}
Ich hoffe jemand kann den Thread wegen den Bildern zitieren.
Mehrere Dinge werden im laufe des noch folgen.






