Heyho,
da ich nach langer Abstinenz von allen M2Foren hier mal hergefunden habe und auch das Eine oder Andere hier finden konnte, möcht ich heut auch mal was kleines hier teilen.
Hierbei geht es um die "/flush" Funktion für GM-Chars. Diese erfordert eine PlayerID als Parameter. Das hat mich oft gestört, da ich während der Entwicklung von diversen System mehrere Chars nutze und daher nie die PlayerID im Kopf habe.
Also hab ich sie mal so umgebaut, dass es sowohl möglich ist mit der Angabe einer PlayerID als auch ohne diese Funktion auszuführen. Wenn man sie weglässt wird schlichtweg die aktuelle ID genommen.
Ein weiterer Part, der mich an der Funktion grundlegend störte: Sie tut einfach nichts, solange es der Core nicht eh tun würde.
Problemfall hier: Sämtliche Flush-Funktionen werden zwar aufgerufen, aber der PlayerCache gilt nicht als "QueryNeeded". Da der Core selber die Änderungen am Spieler noch gar nicht in den Cache eingetragen hat.
Ergo er tut nichts.
Diese Funktion sorgt dafür, dass der Cache richtig gesetzt wird und auch als zu Flushen gilt:
Nun können Änderungen am Charakter sofort in die Datenbank gespeichert werden.
Also hier die ganze Funktion. Ersetzt sie einfach mit eurer in den cmd_gm.cpp:
- ACMD(do_flush)
- {
- char arg1[256];
- one_argument(argument, arg1, sizeof(arg1));
- DWORD pid = 0;
- if(0 == arg1[0])
- {
- pid = ch->GetPlayerID();
- }
- else
- {
- pid = (DWORD)strtoul(arg1, NULL, 10);
- }
- if (pid != 0)
- {
- ch->SaveReal();
- db_clientdesc->DBPacketHeader(HEADER_GD_FLUSH_CACHE, 0, sizeof(DWORD));
- db_clientdesc->Packet(&pid, sizeof(DWORD));
- }
- }
#Edit:
Habe diese Methodik auch mal in den "/shutdown" Befehl eingebaut.
"cm_general.cpp":
erweitert Ihr zu:
- struct SendDisconnectFunc
- {
- void operator()(LPDESC d)
- {
- if(d->GetCharacter())
- {
- #ifdef FLUSH_AT_SHUTDOWN
- d->GetCharacter()->SaveReal();
- DWORD pid = d->GetCharacter()->GetPlayerID();
- db_clientdesc->DBPacketHeader(HEADER_GD_FLUSH_CACHE, 0, sizeof(DWORD));
- db_clientdesc->Packet(&pid, sizeof(DWORD));
- #endif
- if(d->GetCharacter()->GetGMLevel() == GM_PLAYER)
- {
- d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
- }
- }
- }
- };
in der main.cpp ist das selbe Struct vorhanden. Könnt ihr genau so anpassen. Dieses Struct wird allerdings nur genutzt wenn ein SHUTDOWN per AdminPage gesendet wird. Da es ja aber eig. eh keiner nutzt ist das nicht wirklich notwendig.
Damit könnt ihr den Server nun zumindest Ingame sicher herunterfahren und alle Spieler werden geflusht/gespeichert.
Viel Spaß damit.
Mfg Sanii