![]() |
AW: Ist das hier Delphi ?
oh das liest sich mal kompliziert.
also ich habe erst mal laut Beschreibung Indy ueber Software remove Programs aus Borland deinstalliert. und welche der Links dort muss ich runterladen ? einfach die erste Zip Datei 9.0.18 Source code Distribution ? was immer das ist |
AW: Ist das hier Delphi ?
so ich habe nun alle Packages installiert und die Projekt Dateien lassen sich ohne Fehler oeffnen
nur habe ich noch Probleme mit Dxgettext. ich habe das zwar installiert, aber es findet diese Gnugettext.pas nicht. und immer wieder bekomme ich bein Kompillieren diesen Fehler: program pasall; Uses gnugettext in 'D:\Borland\dxgettext\gnugettext.pas' ; begin end. In D: habe ich aber nichts installiert denn das ist mein CDROM Laufwerk. Kann es sein das dieser Pfad irgendwo im Quelltext verankert ist ? gesucht habe ich schon aber ich bin wohl blind. |
AW: Ist das hier Delphi ?
hast du mal die Windows-Suche benutzt, wo die Datei auf deiner Festplatte liegt?
Falls das alles installiert ist und du die Datei findest, musst du vielleicht nur den entsprechenden Pfad zum Suchpfad vom C++ Builder hinzufügen. |
AW: Ist das hier Delphi ?
ja ich weiss wo die von mir installierte liegt.
und auch wenn ich diesen Pfad eingebe findet es die Datei nicht das gleiche gilt auch fuer Gnugettext.dcu und .hpp reicht es eigendlich das Programm zu installieren oder muss ich da noch etwas kompillieren oder in Borland installieren. Ich habe mich glaube ich falsch ausgedrueck oben. Ich meinte kann es sein das dieser Pfad im Projekt von dem Macher irgendwo verankert ist, denn da sind noch mehrere ausgegraute (ungueltige Pfade) bei Include und den Library Pfaden und alle sind in E: oder D: obwohl alles was ich installiert habe befindet sich in C: Wenn ich diese Pfade in meine aendere,geht das auch. Nur nicht mit Gettext |
AW: Ist das hier Delphi ?
Hallo, da bin ich schon wieder :-D
nach 2 Jahren und nach gefühlten 157 Mal Betriebssystem neu aufsetzen, habe ich es endlich geschafft, dieses Programm zu kompillieren :cheer: Ich konnte diesen Parser endlich übersetzen und er liest alles aus,naja fast alles... da gibt es irgendwo ein hoffentlich nur ein kleines Detail , das ich ändern muss. der Parser liest den Chatlog aus und fügt die Werte in ein .xml Dokument ein. Das tut er auch so wie er sollte,allerdings bei einem einzigen Wert will er nicht: Das hier z.B. soll er lesen:
Code:
das liest er alles korrekt bis auf das:
[11:20:27] <Begin Info: Obedience>
[11:20:27] [11:20:27] usable by: [11:20:27] - Spiritmaster [11:20:27] - Runemaster [11:20:27] - Bonedancer [11:20:27] [11:20:27] Magical Bonuses: [11:20:27] - Summoning: 4 pts [11:20:27] - Constitution: 18 pts [11:20:27] - Matter: 10% [11:20:27] - Power: 8 pts [11:20:27] [11:20:27] Focus Bonuses: [11:20:27] - ALL spell lines: 50 lvls [11:20:27] [11:20:27] [11:20:27] Level Requirement: [11:20:27] - 50 Level [11:20:27] [11:20:27] Damage Modifiers: [11:20:27] - 16,5 Base DPS [11:20:27] - 4,5 Weapon Speed [11:20:27] - 100% Quality / 100% Condition [11:20:27] - Damage Type: Crush [11:20:27] [11:20:27] Effective Damage: [11:20:27] - 16,5 DPS [11:20:27] <End Info> [11:20:27] Focus Bonuses: [11:20:27] - ALL spell lines: 50 lvls wenn ich in dem Chatlog per Editor den Wert auf unter 10 sprich:"- ALL spell lines: 9 lvls"(oder tiefer) ändere,liest er es korrekt aus aber sobald er auf 10 oder höher geht, findet er ihn gar nicht mehr, einer von euch kann diesen code sicherlesen und mir sagen, ob der Hund überhaupt in diesem begraben liegt :)
Code:
[cpp]
#include <assert.h> #include <StrUtils.hpp> #pragma hdrstop #include "ChatLog.h" #include "Utils.h" #include "MainFrame.h" // Brauch die xml_config Struktur // Mit diesem String beginnt der Info-Bereich const char strInfoStart[] = "<Begin Info:"; // Mit diesem String endet der Info-Bereich const char strInfoStop[] = "<End Info>"; // Mit diesem String beginnt der Info-Bereich const char strMagBoniStart[] = "Bonuses:"; // Ein paar Strings zur identifikation bestimmter Werte const char strAF[] = "Armor"; const char strAbsorb[] = "Absorption"; // Daraus läßt sich Rüstungsklasse gewinnen const char strQuality[] = "Quality"; const char strSpeed[] = "Weapon"; const char strUnique[] = "Einzigartiger Gegenstand"; const char strCrafted[] = "Hergestellt von:"; const char strBonus[] = "Bonus auf"; const char strBonus2[] = "Bonus zum"; const char strRestriction[] = "usable by:"; const char strArtifact[] = "Artefakt:"; const char strActivLevel[] = " (Benötigte Objektstufe:"; //--------------------------------------------------------------------------- CChatLog::CChatLog() { fChatLog = NULL; arItemNames = new TStringList; }; CChatLog::~CChatLog() { CloseChatLog(); delete arItemNames; }; // Öffnet die ChatLog-Datei für Lesezugriff int CChatLog::OpenChatLog(const char* Filename) { if (fChatLog != NULL) delete fChatLog; // Seek funktioniert nur richtig im binary-mode. Nur ist jetzt immer /r hinter einem String fChatLog = new fstream(Filename, ios_base::in | ios_base::binary); iLineNo = 0; if (fChatLog->is_open()) return true; else return false; }; void CChatLog::CloseChatLog() { if (fChatLog != NULL) { fChatLog->close(); delete fChatLog; } fChatLog = NULL; }; // enumwerte des Parsers in Init enum ParserStateInit { STATE_START, // Scanne nach Start einer Info-Section STATE_ITEM, // Suche danach in der Sektion, das es ein Gegenstand ist }; // Diese Funktion scannt erstmal das gesamte Log nach Gegenständen und merkt // sich deren Position. In einem zweiten durchlauf wird versucht, die Herkunft // der Gegenstände herauszubekommen. Doppelte Items werden herausgefiltert void CChatLog::Init(void) { int posStart; // Startposition des aktuellen Info-Bereichs AnsiString strName; // Name des aktuellen Info-Bereichs char Line[1024]; // Hier eine maximale Länge eines Textes heruasfinden bool bIsItem; nItems = 0; iLineNo = 0; arItemNames->Clear(); arOffsets.Length = 0; ParserStateInit State = STATE_START; fChatLog->seekg(0, ios::beg); // Lesezeiger auf Dateianfang fChatLog->getline(Line, 1024); while(!fChatLog->eof()) { assert(StrLen(Line) < 1024); iLineNo++; switch (State) { case STATE_START: { // Suche nach dem Start eines Info-Bereichs char *pStart = AnsiStrPos(Line, (char*)strInfoStart); if (pStart != NULL) { posStart = fChatLog->tellg() - fChatLog->gcount(); AnsiString sTemp = pStart; strName = sTemp.SubString(sizeof(strInfoStart) + 1, StrLen(pStart) - sizeof(strInfoStart)- 2); // Jetzt mal schauen, ob es einen Doppelpunkt gibt. int p = strName.AnsiPos(':'); if (p > 0) { // Wenn ja, dann den String bis dorthin abschneiden strName = strName.SubString(p + 2, strName.Length() - p - 1); } bIsItem = false; State = STATE_ITEM; } } break; case STATE_ITEM: { // Suche nach Magieboni oder Info-Sektion Ende char *pStart = AnsiStrPos(Line, (char*)strMagBoniStart); if (pStart != NULL) bIsItem = true; // Ist Info-Sektion zu Ende? pStart = AnsiStrPos(Line, (char*)strInfoStop); if (pStart != NULL) { State = STATE_START; // Nach der nächsten Info-Sektion suchen if (bIsItem) { // Ende Info-Sektion und es ist ein Gegenstand // Also in die Liste der zu untersuchenden Gegenstände aufnehmen int index; if ((index = arItemNames->IndexOf(strName)) == -1) { // Item mit diesem Namen gibts noch nicht (im Logfile) arItemNames->Add(strName); arOffsets.Length = nItems + 1; arOffsets[nItems] = posStart; nItems++; } else { // Name gibts schon. Offset aber auf diesen setzen, // da immer das letzte das aktuellste sein sollte arOffsets[index] = posStart; } } } } break; } fChatLog->getline(Line, 1024); } } // Diese Funktion macht die eigentliche Lesearbeit // Input ist dabei der Index des zu beschaffenden Items und einen Zeiger // auf eine CItem-Klasse, welche ausgefüllt werden soll // Rückgabe ist true für keinen Fehler int CChatLog::GetItem(int index, CItem* Item) { unsigned int i; char Line[1024]; // Hier eine maximale Länge eines Textes heruasfinden char sArg[64]; // Längere Bonusbezeichnungen gibts glaub nicht int NextBonus = 0; // Welche Position soll der nächste Bonus eingetragen werden int NextRestriction = 0; // Nächster Index einer Klassenbeschränkung bool bRestriction = false; if ((index < 0) && (index >= nItems)) return false; // Itemindex nicht im gültigen Bereich Item->Init(); Item->Name = arItemNames->Strings[index]; Item->Realm = player->Realm; // Immer Realm des Spielers annehmen Item->Quality = 0; // Versuche Aufgrund des Namen auf den Itemslot zu schliessen AnsiString strTemp = Item->Name.LowerCase(); for (i = 0; i < 18; i++) { for (int j = 0; j < xml_config.arItemSlots[i].arIds.Length; j++) { if (strTemp.AnsiPos(xml_config.arItemSlots[i].arIds[j]) > 0) Item->Position = i; } } // Lesezeiger auf Beginn der entsprechenden Info-Sektion stellen fChatLog->clear(); // Ist nötig, da wir eventuell noch im eof-state sind fChatLog->seekg(arOffsets[index], ios::beg); fChatLog->getline(Line, 1024); // Erste Zeile Lesen (kann ignoriert werden) fChatLog->getline(Line, 1024); // Erste Zeile mit Infos while(!fChatLog->eof()) { assert(StrLen(Line) < 1024); int Value = 0; // Ist Info-Sektion zu Ende? char *pStart = AnsiStrPos(Line, (char*)strInfoStop); if (pStart!= NULL) break; if (Line[11] == '-') { // Alles danach ist ein Wert, der mich interessiert // Suche erstmal nach einem Zahlenwert. Sollte immer nur einer sein // Bonus-Argument ist immer der String vor einem Doppelpunkt, // oder der String hinter einer Zahl bool bValue = false; // Gibts eine Zahl? bool bDoppel = false; // gibt es einen Doppelpunkt im String bool bPercent = false; // Es ist ein Prozent-Wert int pArg = 0; // Aktuelle Position im Argument-String for (i = 13; i < StrLen(Line); i++) { if ((Line[i] >= '0') && (Line[i] <= '9')) { bValue = true; Value = Value * 10 + Line[i] - '0'; } else if (Line[i] == ':') bDoppel = true; else if (Line[i] == ' ') { if (bValue && (bDoppel || (pArg > 0))) break; pArg = 0; } else if (Line[i] == '%') bPercent = true; else if ((Line[i] == '\r') || (Line[i] == ',')) {} // Diese Zeichen ignorieren else { sArg[pArg++] = Line[i]; sArg[pArg] = 0; } } if (bValue) { // In xml_config nach einem entsprechendem Boni suchen int bid = xml_config.GetBonusId(sArg, bPercent); if (bid < 0) { // testen, ob der gesamte Text nicht vielleicht doch ein Bonus ist bid = xml_config.GetBonusId(MidStr(AnsiString(Line), 14, i - 16), bPercent); } if (bid >= 0) { // Es ist ein regulärer Bonus Item->Effect[NextBonus] = bid; Item->EffectValue[NextBonus] = Value; NextBonus++; } else { // Hier ein paar zusätzliche Werte nehmen, die keine Boni sind if (strcmp(sArg, strAF) == 0) Item->AF = Value; if (strcmp(sArg, strQuality) == 0) Item->Quality = Value; if (strcmp(sArg, strSpeed) == 0) Item->Speed = Value; if (strcmp(sArg, strAbsorb) == 0) { // Value in Rüstungsklasse umwandeln switch (Value) { case 0: Item->Class = 0; Item->Level = Item->AF;break; case 10: Item->Class = 1; Item->Level = Item->AF / 2; break; case 19: Item->Class = 2; Item->Level = Item->AF / 2; break; case 27: Item->Class = 3; Item->Level = Item->AF / 2; break; case 34: Item->Class = 4; Item->Level = Item->AF / 2; break; } //if (Item->Position < 0) // Item->Position = 0; // Alle Rüstungen als Handschuhe annehmen // Es gibt leider keine Info darüber im Log // Wenn wir die Position auf -1 lassen, dann kommt automatisch eine Auswahlbox } if (strcmp(sArg, "DPS") == 0) { // Nur ersten DPS-Wert speichern if (Item->DPS == 0) { Item->DPS = Value; // Berechne den Itemlevel int level = (Value - 11) / 3; if (level > 51) level = 51; Item->Level = level; } } } } } // else { // noch ein paar besondere Strings auswerten if (strncmp(&Line[11], strUnique, sizeof(strUnique) - 1) == 0) { // Unique Gegenstände nicht importieren return false; } if (strncmp(&Line[11], strCrafted, sizeof(strCrafted) - 1) == 0) { // Craftet Gegenstände nicht importieren return false; } if (strncmp(&Line[11], strArtifact, sizeof(strArtifact) - 1) == 0) { Item->MaxLevel = 10; Item->Realm = 7; } if ((strncmp(&Line[11], strBonus, sizeof(strBonus) - 1) == 0) \ || (strncmp(&Line[11], strBonus2, sizeof(strBonus2) - 1) == 0)) { // Spezielle Werte (meist Bonuserhöhungen) // Bonus auf BONUS: VALUE unsigned int i; for (i = 21; i < StrLen(Line); i++) { // Alles bis zum Doppelpunkt in sArg kopieren if (Line[i] == ':') break; sArg[i - 21] = Line[i]; } sArg[i - 21] = 0; for (; i < StrLen(Line); i++) { if ((Line[i] >= '0') && (Line[i] <= '9')) { Value = Value * 10 + Line[i] - '0'; } } // In xml_config nach einem entsprechendem Boni suchen int bid = xml_config.GetBonusId(sArg); if (bid >= 0) { // Es ist ein regulärer Bonus Item->Effect[NextBonus] = bid; Item->EffectValue[NextBonus] = Value; NextBonus++; } else { // Fehlermeldung Application->MessageBoxA(AnsiString("Ein Bonus '" + AnsiString(sArg) + "' ist unbekannt!\nDie Datei 'config.xml' bzw. die entsprechende Sprachdatei anpassen!").c_str(), "Fehler"); } } if (strncmp(&Line[11], strActivLevel, sizeof(strActivLevel) - 1) == 0) { // Danach kommt ne Zahl, welche den Level angibt int level = Str2Int(&Line[11 + sizeof(strActivLevel)]); Item->EffectLevel[NextBonus - 1] = level; } unsigned int cp = 12; if ((strncmp(&Line[11], strRestriction, sizeof(strRestriction) - 1) == 0) \ || (strncmp(&Line[12], strRestriction, sizeof(strRestriction) - 1) == 0)) { // Solange nachfolgende Strings eine Klasse darstellen, solange // diese bei den Beschränkungen eintragen bRestriction = true; cp = 12 + sizeof(strRestriction); } while (bRestriction && (cp < StrLen(Line))) { int pArg = 0; for (; cp < StrLen(Line); cp++) { if ((Line[cp] == ' ') || (Line[cp] == ',') || (Line[cp] == '-') || (Line[cp] == '\r')) { sArg[pArg] = 0; if (pArg > 0) { // Es gibt einen String. Schauen obs ne Klasse ist int cid = xml_config.GetClassId(sArg); if (cid >= 0) { Item->ClassRestriction[NextRestriction++] = cid; } else { // Keine Klasse mehr, Modus aufheben bRestriction = false; } } pArg = 0; } else { sArg[pArg++] = Line[cp]; } } } } fChatLog->getline(Line, 1024); } return true; } #pragma package(smart_init) [/cpp] |
AW: Ist das hier Delphi ?
Hallo,
ich habe gerade versucht, den Ablauf im Kopf nachzuvollziehen, aber auf die Schnelle seh ich den Fehler nicht. Bugs in solchen Parsern nur durch reines Draufschauen zu finden, ist aber auch sehr schwer. Ich würde dir daher empfehlen, die Log-Datei erst mal auf die relevanten Zeilen zu kürzen:
Code:
Und anschließend hierrunter, z.B. in die Zeile mit bPercent, einen Breakpoint zu setzen:
[11:20:27] <Begin Info: Obedience>
[11:20:27] Focus Bonuses: [11:20:27] - ALL spell lines: 50 lvls [11:20:27] <End Info>
Code:
Einen Breakpoint setzt du, indem du auf den Linken Editor-Rand neben der Zeile klickst (dort sollte dann ein roter Punkt erscheinen).
if (Line[11] == '-')
{ // Alles danach ist ein Wert, der mich interessiert // Suche erstmal nach einem Zahlenwert. Sollte immer nur einer sein // Bonus-Argument ist immer der String vor einem Doppelpunkt, // oder der String hinter einer Zahl bool bValue = false; // Gibts eine Zahl? bool bDoppel = false; // gibt es einen Doppelpunkt im String bool bPercent = false; // Es ist ein Prozent-Wert Wenn du das Programm dann anschließend aus der IDE heraus ausführst, hält das Programm an genau der Stelle an, wo der Breakpoint sitzt. Du kannst dann Zeile für Zeile die Ausführung fortsetzen (in Delphi geht es mit F8, im C++-Builder vielleicht auch?) und dabei die Werte, die Variablen annehmen, beobachten, indem du mit der Maus darüberfährst. Vielleicht siehst du dann, wo das Programm sich anders verhält als es sollte. Ich hoffe das hilft dir ein bisschen weiter... Und es wurde wahrscheinlich schon gefragt, aber ist der Autor des Programms denn nicht erreichbar? Edit: Achja, und Glückwunsch zum erfolgreichen Kompilieren :wink: |
AW: Ist das hier Delphi ?
danke schonmal für deine Hilfe
ich werde das gleich mal versuchen :) den Autor des Programms hatte ich vor 2 Jahren angeschrieben und er antwortete, das er weder die Zeit, noch den Compiler hat und mir deswegen nicht helfen kann. ich habe ihn auch vor 3 Tagen angeschrieben um ihm mitzuteilen, das ich es geschafft habe und ihn um Hilfe bei diesem Problem gefragt, aber er antwortet leider nicht :( |
AW: Ist das hier Delphi ?
ich habe das jetzt mal probiert,
diesen Breakpoint in der Zeile gesetzt, und dann auf F8 gedrückt, danach gehen nach und nach einige Seiten auf, bei einer die heisst: _istreambuf_iterator.h bleibt es an dieser Stelle hängen und zwar springt es zwischen diesen beiden Zeilen hin und her for(int i = 0; i < nItems; i++) delete arItems[i]; edit/ ah ich hatte das Programm nicht gestartet :) |
AW: Ist das hier Delphi ?
Also ich habe deinen Tipp probiert, aber kam damit leider nicht weiter :(
nun habe ich aber herrausgefunden, das wenn ich das Leerzeichen hinter dem Doppelpunkt wegnehme, dann liest er es.
Code:
[11:20:27] - ALL spell lines: 50 lvls
Code:
also ist es nur ein dummes Leerzeichen ?
[11:20:27] - ALL spell lines:50 lvls
nur wo kann ich das ändern, damit es gleich hinter dem Doppelpunkt anfängt zu lesen und nicht erst nach dem Leerzeichen :? |
AW: Ist das hier Delphi ?
Ich hab nicht viel Ahnung von C
aber hier steigt er jedenfalls mit break aus der ForSchleife(?) aus, wenn ein Leerzeichen und ein Doppelpunkt auftreten:
Code:
if (bValue && (bDoppel || (pArg > 0))) break;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz