Ergebnis 1 bis 7 von 7

Thema: python exeption (ohne Auswirkung?)

  1. #1
    Registrierter Benutzer Avatar von klops
    Registriert seit
    20.05.16
    Ort
    Hannover
    Beiträge
    2.688

    python exeption (ohne Auswirkung?)

    Moin!
    Seit den letzten 2-3 saves bekomme ich eine Fehlermeldung. Die kann ich wegklicken und das Spiel läuft dann *scheinbar* normal. Bisschen komisch finde ich das allerdings schon und vielleicht ist ja auch was kaputt, was ich oberflächlich nicht sehe.

    Kann mir jemand etwas Näheres dazu sagen?
    WB scheint der Worldbuilder zu sein, den ich aber nicht nutze, und spezielle ascii Zeichen hab ich auch nicht im Namen

    Bild
    Angehängte Grafiken Angehängte Grafiken

  2. #2
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    12.110
    Ich habe diesen Fahler in der Vergangenheit gehabt, wenn ich ein Landschaftsfeld mit einem Buchstaben wie Ä,ö,ü,ß benannt habe.
    Vereinzelt habe ich das auch schon einmal gesehen, wenn eine Nachricht kam, in der eine der Variablen (z.b. der Einheitenname) so einen Buchstaben enthielt. (Bär, Barbarenhäuptling). Auswirkungen hatte ich bisher nicht feststellen können.
    That's why I am here: Mein Mod
    Mehr Technologien, mehr Einheiten, mehr Zivilisationen, mehr Gebäude

    Die aktuelle Story zum Mod:
    Kathys Mod: The british Empire - United Kingdom zum Dritten

    Alte Stories zu alten Versionen:
    Alte Storys

  3. #3
    Registrierter Benutzer Avatar von klops
    Registriert seit
    20.05.16
    Ort
    Hannover
    Beiträge
    2.688
    Hmm... paar Markierungs-Schilder hab ich tatsächlich gemacht. Mit Prozentzeichen... oh und "jüd." ist auch dabei. Dann war es das wohl, danke.
    Wenn du keine Auswirkung entdeckt hast, dann mach ich mir auch erstmal keine Sorgen, hab immerhin viele Speicherstände


  4. #4
    Civ4 BASE Coder Avatar von rucivfan
    Registriert seit
    10.07.11
    Ort
    Antarktika
    Beiträge
    18.787
    Pythonfehler werden abgefangen, aber je nach Ort der Auslösung könnten wichtigte Sachen nicht geschalten werden. Nach dem Stack hier zu beurteilen sollte das kein Problem sein.

  5. #5
    Registrierter Benutzer Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    8.697
    Es hängt sicher mit den Schildern zusammen und ja: '\xfcd' ist ein ü.
    Code:
    class CvSignDesc:
    	"serialize map data"
    	def __init__(self):
    		self.iPlotX = 0
    		self.iPlotY = 0
    		self.playerType = 0
    		self.szCaption = ""
    		
    	def apply(self):
    		plot = CyMap().plot(self.iPlotX, self.iPlotY)
    		CyEngine().addSign(plot, self.playerType, self.szCaption)
    		
    	def write(self, f, sign):
    		"write sign data"
    		f.write("BeginSign\n")
    		f.write("\tplotX=%d\n" %(sign.getPlot().getX(),))
    		f.write("\tplotY=%d\n" %(sign.getPlot().getY(),))
    		f.write("\tplayerType=%d\n" %(sign.getPlayerType(),))
    		f.write("\tcaption=%s\n" %(sign.getCaption(),))
    		f.write("EndSign\n")
    Warum intern irgendwo '.encode('ascii')' aufgerufen wird ist mir nicht so ganz klar(*), aber da dort, im Unterschied zu latin-1 nur 128 Zeichen (7 Bit) definiert sind, und die Umlaute nicht dabei sind, wird der Fehler geworfen.
    Man könnte es verhindern indem man sign.getCaption.encode('ascii', 'ignore') schreibt, aber besser wäre es sicher es anders zu lösen, da Umlaute innerhalb des Spiels ja keine Probleme bereiten.


    (*) Also halbklar ist es schon. In Python2 erwartet die Methode file.write() einen String vom Typ str. Unicode-Strings werden mit .encode('ascii') umgewandelt. Wenn man die Eingabe vorher selber umwandelt, z.B. u'jüd'.encode('utf-8'), hat die Eingabe schon den richtigen Objekttyp und der String wird geschrieben.
    Geändert von Ramkhamhaeng (19. Februar 2018 um 00:46 Uhr)

  6. #6
    Registrierter Benutzer Avatar von klops
    Registriert seit
    20.05.16
    Ort
    Hannover
    Beiträge
    2.688


    danke euch

    Vielleicht ist es den Amis damals einfach nicht in den Sinn gekommen, daß auch andere Zeichen möglich sind und das daher gar nicht erst versucht haben abzufangen.

  7. #7
    Registrierter Benutzer Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    8.697
    Aufgrund der erneuten Nachfrage von Klops und dem Umstand, dass ich mich mit dem Encoding-Thema gerade beschäftigt habe, will ich meine
    Antwort etwas erweitern. Die Ursache des Problems liegt zum einen im intern verwendetem Encoding der Schilder-Texte (cp1252) und dem Mix
    der String-Typen bei der Interaktion mit den „Signs“. Eine Ungenauigkeit beim Design der Civ4-Schnittstellen.

    Zuerst einmal zur Eingabe der Sign-Texte. Dafür gibt es folgende Funktion
    Code:
        Python Library Documentation: method addSign
        
        addSign(...) method of CvPythonExtensions.CyEngine instance
            void (CyPlot *plot, int /* PlayerTypes */ playerType, const TCHAR* caption)
    Um die richtige Kodierung zu wählen, muss man utf-8-Texte folgendermaßen in cp1252 konvertieren:
    Code:
      
    CyEngine().addSign(gc.getMap().plot(0,4), -1, "ü".decode('utf-8').encode('cp1252'))
        None  # <- Rückgabe wert zeigt, dass es geklappt hat
    
    # Nicht gehen würde
    CyEngine().addSign(gc.getMap().plot(0,4), -1, "ü".encode('cp1252')) 
    # weil "ü" in der Regel in einer Python-Datei mit utf-8-Kodierung gespeichert ist(?!)
    # Im Spiel gilt aber standardmäßig…
    print(sys.getdefaultencoding())
        ascii
    Nun zum Auslesen der Schilder. Dafür gibt es in CyEnigne…
    Code:
        getNumSigns(...) unbound CvPythonExtensions.CyEngine method
            int getNumSigns()
        getSignByIndex(...) unbound CvPythonExtensions.CyEngine method
            CySign* (int index)
    Und dann CySign:
    Code:
        Python Library Documentation: CySign in module CvPythonExtensions object
        
        class CySign(Boost.Python.instance)
         |  Method resolution order:
         |      CySign
         |      Boost.Python.instance
         |      __builtin__.object
         |  
         |  Methods defined here:
         |  
         |  __init__(...)
         |  
         |  getCaption(...)
         |      wstring getCaption()
         |  
         |  getPlayerType(...)
         |      PlayerTypes getPlayerType()
         |  
         |  getPlot(...)
         |      CyPlot getPlot()
         |
    D.h. die Rückgabe ist ein Unicode-String. Beispiel-Anwedung:
    Code:
    sign = CyEngine().getSignByIndex(0)  # Hier muss man ggf. den richtigen Index suchen 
    print(sign.getCaption().encode('utf-8'))
    TLDR: Rein müssen Strings mit cp1252-Kodierung, aber raus fallen Unicode-Strings. Ich werde den WB in der PB Mod
    so anpassen, dass die in Civ4 erlaubten Sonderzeichen/Umlaute keine Probleme mehr bereiten.

    Edit: Patch von CvWBDesc.py ist
    Code:
    CvWBDesc.py  
    @@ -1997,7 +1997,7 @@ class CvSignDesc:
             f.write("\tplotX=%d\n" %(sign.getPlot().getX(),))
             f.write("\tplotY=%d\n" %(sign.getPlot().getY(),))
             f.write("\tplayerType=%d\n" %(sign.getPlayerType(),))
    -        f.write("\tcaption=%s\n" %(sign.getCaption(),))
    +        f.write("\tcaption=%s\n" %(sign.getCaption().encode('utf-8'),))
             f.write("EndSign\n")
     
         def read(self, f):
    @@ -2030,7 +2030,7 @@ class CvSignDesc:
     
                 v = parser.findTokenValue(toks, "caption")
                 if v!=-1:
    -                self.szCaption = v
    +                self.szCaption = v.decode('utf-8').encode('cp1252')
                     continue
    Geändert von Ramkhamhaeng (30. Januar 2020 um 23:24 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •