S5Hook & GUI Editor

» Siedler Map Source Forum » Siedler DEdK Script Forum » S5Hook & GUI Editor

Seiten: Zurück 1 2 3 4 5 6 7 Nächste Seite

Zedeg
#101
26.05.2016 00:45
Beiträge: 428

Wo ist v1.0 hin?
Kommt auch noch die parallele Soundausgabe in zukünftigen Versionen?

____________________
Journalisten erkundigen sich bei Wissenschaftlern meist nicht nach Grundlagen, sondern eher nach Ergebnissen und Folgerungen. Das erklärt womöglich auch, warum sich Forschungsberichte in den Medien so häufig als feststehende Erkenntnisse lesen, nicht aber als Ideen, Entdeckungen oder Indizien, um die es sich genau genommen in den meisten Fällen handelt. -Axel Bojowski

yoq
#102
26.05.2016 01:06
Beiträge: 91

Die v1.0 war zwar direkt/ohne Callback aber mit 70ms Setupzeit recht langsam, und ich habe die nicht groß veröffentlicht. Die aktuelle Entwicklung gibts immer hier: https://bitbucket.org/settlersdev/s5hook/commits
Die neue v1.1 sollte mit etwa 2ms fürs Setup nun wirklich nicht mehr auffallen

Ob ich die Zeit für neue Features finde kann ich noch nicht sagen. Die Anwender kann man leider an einer Hand abzählen, und bisher habe ich noch nicht wirklich Maps gesehen wo S5Hook verwendet wurden.
*hust* @bobby: wäre mal Zeit, eine gewisse Map fertigzustellen *räusper*
Gibt es schon ein konkretes Projekt / Map wo du Sounds benötigst?

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

mcb
#103
26.05.2016 13:35
Beiträge: 1472

Meine Map wird leider auch noch nicht so schnell fertig. Muss noch einiges an Scripten schreiben... (Noch ein paar Heldenfähigkeiten, das Wetterturmscript, KI, HQs...)
Was ich ziemlich häufig nutze ist CreateProjectile und LoadGUI. AddArchive wird benutzt, spätestens wenn eine Map fertig ist.

Was ich gerne hätte, wäre eine Möglichkeit an einige Infos aus der Engine ranzukommen, ohne dafür jedes mal ein Entity zu erstellen. Insbesondere Blocking und z-Koordinate einer Position. Das macht Momentan meine Suche nach Bauplätzen ziemlich langsam. (Ich weiß auch nicht ob ne id von 156172374 so gut für die Engine ist...)
Hilfreich wäre auch wenn man sich irgendwie in die Zuweisung von Soldiers zu Leadern oder Serfs zu Baustellen einmischen könnte. Ich hab aber keine Ahnung wie kompliziert das ist.

Wie funktioniert das eigentlich, das das jetzt ohne Job geladen wird? Ich vermute mal, du schaffst es irgendwie die Entitys zu Updaten, so das der entsprechende Pointer erstellt wird, vielleicht mit XNetwork.Manager_GetLocalMachineUserName() ?

Zedeg
#104
26.05.2016 22:26
Beiträge: 428

Den Hauptzweck habe ich anscheinend schon wieder herausgenommen und ich kann mich nicht erinnern, was er war. War anscheinend doch nicht so wichtig.

____________________
Journalisten erkundigen sich bei Wissenschaftlern meist nicht nach Grundlagen, sondern eher nach Ergebnissen und Folgerungen. Das erklärt womöglich auch, warum sich Forschungsberichte in den Medien so häufig als feststehende Erkenntnisse lesen, nicht aber als Ideen, Entdeckungen oder Indizien, um die es sich genau genommen in den meisten Fällen handelt. -Axel Bojowski

MadShadow
#105
27.05.2016 11:22
Beiträge: 372

Ich sitze auch noch an einem relativ großen Projekt, in dem ich den s5Hook verwende. Wie das leider immer so ist mit großen Projekten dauert es recht lange, sitze schon seit Anfang Januar dran, aber immerhin kommt langsam ein Ende in Sicht. Zumindest glaube ich das.

yoq
#106
27.05.2016 14:31
Beiträge: 91

So, hab doch noch etwas angebaut: v1.2

local height, blocking, sector = S5Hook.GetTerrainInfo(x, y)


Um das einfach zu testen:

function runDbg()
    sID = 0
    Display.SetRenderLandscapeDebugInfo(1)
    GUIUpdate_UpdateDebugInfo = dbg
    XGUIEng.ShowWidget("DebugWindow", 1)
end

function dbg()
    local mx, my = GUI.Debug_GetMapPositionUnderMouse()
    
    if sID > 0 then
        Logic.DestroyEntity(sID)
        sID = 0
    end
    
    if mx > 0 and my > 0 then
        sID = Logic.CreateEntity(Entities.XD_StandartePlayerColor, mx, my, 0, 1)
    end
    
    local DebugString 
    local mz, blocking, sector = S5Hook.GetTerrainInfo(mx, my)
    if mz ~= nil then
        local fx = math.floor(mx * 0.01 + 0.5)
        local fy = math.floor(my * 0.01 + 0.5)
        DebugString = "Mouse at (" .. string.format("%.3f, %.3f, %.3f", mx, my, mz) .. " @cr " ..
                      "At Node (" .. fx .. ", " .. fy .. "): Sector = " .. sector .. ", Blocking = " .. blocking .. " @cr "
    end
    XGUIEng.SetText("DebugWindow", DebugString)
end



___

Um den Murks mit BigNum/Int2Float loszuwerden gibts jetzt auch eine Erweiterung um auf die Objekte direkt zuzugreifen. Damit kann man die SCV-Sammlung kürzer und schneller machen:

local eObj = S5Hook.GetEntityMem(eID)
eObj:GetInt()           -- Addresse im Speicher
eObj[0]:GetInt()        -- erstes Int im Objekt, meist ein vTable pointer

-- falls eObj[n] ein gültiger Pointer ist, kann dieser weiterverfolgt werden:
local nextObj = eObj[n]
nextObj[0]:GetInt()     -- erstes Int im Objekt eObj[n]

-- dass ganze kann beliebig weit geschachtelt werden:
S5Hook.GetEntityMem(eID)[25]:SetFloat(2.7)        -- setzt scale (SV -33)
S5Hook.GetEntityMem(eID)[31][1][7]:GetFloat()     -- liefert den speedfactor

-- so können die SCV Funktionen schneller und kürzer werden
-- der Unterschied zu GetEntityScriptingValue(e, n) ist eine Verschiebung um -58
-- zB aus dem bekannten SV -27 wird nun 58-27=31. Dies gilt natürlich nur für
-- den ersten Index. Index+1 = 4Byte im Speicher vor


Diese Funktionen sollte nur verwenden wer _wirklich_ verstanden hat was er da macht, und sollten immer nur über eine kleinen Lua-Funktion aufgerufen werden die überprüft ob die Argumente zulässig sind. Ein falscher Wert gespeichert, der Versuch einen ungültigen Pointer weiterzuverfolgen, :GetString() bei etwas anderem als einem String, etc... all das liefert einen garantierten Crash
Wer Lust hat da weiter zu Graben, findet evtl diese Auflistung der meisten Objekte im Spiel sinnvoll: Alt+Klick zum Download So können viele Objekte anhand ihrer vtable identifiziert werden: mit dem vtable 0x76E3CC findet man die Klasse des Objekts, und von welchen es abgeleitet wurde:

0076E3CCh: possible vtable (40 methods)
0000: GGL::CSettler
0000:     GGL::CEvadingEntity
0000:         EGL::CMovingEntity
0000:             EGL::CGLEEntity
0000:                 BB::IObject
0004:                 EGL::IEntityDisplay


___

Zum Thema "wie funktioniert dass alles" kann ich nur einen Blick in den Code auf bitbucket empfehlen. Die Network Funktion sorgt dafür dass die Daten aus stage0 an einem fixen Ort im Speicher landen, und diese kann ich dann mit durch eine geändertes vTable anspringen.

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

Dieser Beitrag wurde von yoq am 27.05.2016 um 14:51 editiert.

mcb
#107
29.05.2016 20:30
Beiträge: 1472

Bin endlich dazu gekommen, es auszuprobieren.
S5Hook.GetTerrainInfo funktioniert gut (insbesondere schneller). (Macht sich beim suchen einer Position zum Gebäudebau echt super. Danke dafür.)

S5Hook.GetEntityMem funktioniert soweit auch, bin noch dabei damit rumzuprobieren. Weiß irgendwer, wie das genau mit dem Attachment funktioniert? Unter S5Hook.GetEntityMem(leader)[31][4][6][0][4] ist das Maximum für diesen Leader, under SV 69 (beim Soldier) die id des Leaders. Das ganze reicht nur leider nicht um einen bestimmten Soldier einem bestimmten Leader zuzuordnen. (Von solchen Attachments wie Serfs, die ein Gebäude bauen mal ganz zu schweigen. Da hab ich noch nicht mal die id des Gebäudes bei den Serfs gefunden.)

MadShadow
#108
06.06.2016 15:52
Beiträge: 372

Bzgl. TerrainInfo, ist möglich noch den TextureType an der Position abzufragen?

totalwarANGEL
#109
06.06.2016 18:02
Beiträge: 2123

Sehe ich das richtig, dass es inzwischen auch einen S6Hook gibt?

____________________
Die Welt ist arschlochförmig und wir leben in der Mitte.

yoq
#110
07.06.2016 20:21
Beiträge: 91

Zitat von totalwarANGEL:
Sehe ich das richtig, dass es inzwischen auch einen S6Hook gibt?


Da hat sich seit Ende '14 nichts geändert: ja gibt es, aber es kann bis auf eval() und alert() nichts. Aber es ist open source, jeder ist eingeladen sinnvolle Funktionen zu schreiben.

Zitat von MadShadow:
Bzgl. TerrainInfo, ist möglich noch den TextureType an der Position abzufragen?


Ja recht einfach, werde ich mir ansehen

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

totalwarANGEL
#111
07.06.2016 23:52
Beiträge: 2123

Zitat von yoq:

Da hat sich seit Ende '14 nichts geändert: ja gibt es, aber es kann bis auf eval() und alert() nichts. Aber es ist open source, jeder ist eingeladen sinnvolle Funktionen zu schreiben.


Mal angenommen ich würde, was bräuchte ich alles an Know How dazu?

____________________
Die Welt ist arschlochförmig und wir leben in der Mitte.

yoq
#112
08.06.2016 00:33
Beiträge: 91

Zitat von totalwarANGEL:
Mal angenommen ich würde, was bräuchte ich alles an Know How dazu?


- Lua C API
- x86 Assembler Basics / Calling Conventions
- OllyDbg / evtl. IDA Decompiler

Alles basiert darauf in den Maschinencode von Siedler einzutauchen und den Engine-Code zu verstehen. Also x86 Assembler lesen und später auch schreiben können ist vmtl das wichtigste. Das klingt deutlich schlimmer als es ist - die Funktionen und Objekte, virtuelle Funktionsaufrufe, etc sind alle noch intakt und wurden nicht vom Compiler wegoptimiert . Es gibt natürlich keine Variablennamen - der Großteil der Arbeit liegt darin zu verstehen was macht welche Funktion, welche Daten sind in diesem Parameter, etc. Als ich mit den ganzen Tools für S5 begonnen habe konnte ich das selber nicht und habe mit Googlen anhand von S5 Assembler von Grund auf gelernt.
Dazu benötigt man zumindest einen Asm Debugger - ich verwende OllyDbg - damit kann man live durch den Code steppen und springen und Instruktionen und Register ändern wie es einem passt. Um komplexere Funktionen zu analysieren hilft ein Decompiler wie IDA ungemein. Damit kann man Variablen und Funktionen benennen, structs definieren, etc...

Das zentrale System ist die Lua C API, also wie die Engine mit dem Lua-Interpreter interagiert. Bei Siedler läuft das primär über Engine Funktionen und Callbacks. Wenn du im LuaDebugger eine Engine Funktion in die Konsole eingibst bekommst du einen Hex-Wert. Das ist die Stelle im Speicher an der die Funktion / der Maschienencode steht. Dh. ich setze dort mit Olly einen Breakpoint und sehe mir live an was die Funktion macht. (Oder ich versuche es mit IDA, meist ein wenig von beidem).
Bsp: Ich analysiere Logic.SetTerrainNodeType(x,y,t) bei 0x591BF0, dort finde ich heraus wo diese Daten hingespeichert werden. Und mit diesem Wissen kann ich nun selbst eine "Engine"-Funktion schreiben die bspw diese Daten nur ausliest, und ans Skript liefert.
Das könnte man theoretisch in C machen - bisher ist aber alles direkt in Asm geschrieben, da vieles nicht so einfach in C geht und man ein tolles Linkskript schreiben müsste dass die Asm und C Teile zusammenpackt.

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

totalwarANGEL
#113
17.06.2016 00:28
Beiträge: 2123

Uff...
Das klingt ja alles ganz schön... interessant. Auf jeden Fall erst mal Danke für die Info. Ich fand Assambler immer total schrecklich. Evtl. kann ich mich so motivieren es mir doch mal anzutun. Hat ja bei dir auch geklappt.

____________________
Die Welt ist arschlochförmig und wir leben in der Mitte.

MadShadow
#114
27.12.2016 18:26
Beiträge: 372

Mir ist aufgefallen dass ein Aufruf von

S5Hook.OSISetDrawTrigger(OnScreenCallbackFunc);


alle bisherigen DrawTrigger überschreibt?
Ist es auch möglich, mehrere Trigger zu haben? Für mich selbst könnte ich das anpassen, aber wenn man Skripte von jemand anderem mit einbindet die auch die Drawfunktion verwenden, würde man sich gegenseitig überschreiben oder man müsste immer im Code des anderen herumbasteln.

Außerdem frage ich mich, gibt es schon neues dazu:

Zitat von yoq:

Zitat von MadShadow:
Bzgl. TerrainInfo, ist möglich noch den TextureType an der Position abzufragen?


Ja recht einfach, werde ich mir ansehen

yoq
#115
28.12.2016 18:10
Beiträge: 91

Ja war zu faul die Verwaltung für mehrer Draw-Funktionen in Assembler zu schreiben - aber du kannst das ja durch 'Hacken' der OSISetDrawTrigger Funktion in Lua basteln.

S5Hook v1.4
- S5Hook.GetTerrainInfo() liefert jetzt auch den Terrain Type
- S5Hook.ChangeString() überprüft ob es den String überhaupt gibt
- S5Hook.SetPreciseFPU() erlaubt exaktes Rechnen mit großen Zahlen
- S5Hook.Unload() Falls S5Hook mal vorzeitig entfernt werden soll.
(Wird beim Beenden, oder vor dem Laden einer neue Map automatisch aufgerufen, war bisher nur nicht über Lua zugänglich)
- S5Hook.Version die Version von S5Hook als String
- Einiges bei den Memory Funktionen (seit v1.2)

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

Dieser Beitrag wurde von yoq am 28.12.2016 um 20:24 editiert.

mcb
#116
29.12.2016 00:05
Beiträge: 1472

Die SetPreciseFPU nutze ich schon seit einer Weile, so kann ich die Adressberechnungen ohne BigNum machen

Was ich gerne hätte wäre eine Möglichkeit, schnell über alle Entitys auf der Map zu iterieren. Wenn ich wüsste, wo die im Speicher abgelegt sind, würd ich das ja auch selber in Assembler schreiben... Bräuchte nur sowas wie den Pointer auf die Entitytypen.
Da ich grad bei Pointern bin: Welche zu den AnimSets und den EntityCategories würden mir auch weiterhelfen... Falls du ne Idee hast, wie man da schnell ran kommt

yoq
#117
29.12.2016 14:59
Beiträge: 91

Was für Iteratoren wären sinnvoll?
alle Entities, alle eines Typs, Player, ...
Was wären so die konkreten Anwendungen dafür?

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

mcb
#118
29.12.2016 15:39
Beiträge: 1472

Es sollte möglichst Flexibel sein, aber auch schnell. (Sowas wie mein EntityFind, nur schnell auch bei voller Map)
Wenn ich Pointer auf die Datenstruktur der Entitys hätte, könnte ich mir das auch selbst basteln.
Ich würd das eventuell so Schreiben, das eine übergebene Funktion mit allen Ids nacheinnder aufgerufen wird. Dann muss man kein table erstellen (zummindes, wenn man es nicht braucht)

yoq
#119
30.12.2016 01:08
Beiträge: 91

Zum testen: 1.5beta

Iterator: S5Hook.EntityIterator(...) Arguments: 0, 1 or more Predicates
Predicate.InCircle          ; x, y, r
Predicate.OfPlayer          ; pID
Predicate.OfType            ; eTypeID
Predicate.OfCategory        ; entCatID
Predicate.OfUpgradeCategory ; upCatID
Predicate.IsBuilding        ; -
Predicate.InSector          ; sectorID
Predicate.InRect           ; x0, y0, x1, y1

-- example: kill all serfs of player1
for eID in S5Hook.EntityIterator(Predicate.OfPlayer(1), Predicate.OfCategory(13)) do
  SetHealth(eID, 0)
end

-- example: fill table with all eIDs
local allEntities = S5Hook.EntityIteratorTableize()


Könntest du das mal gegen die bestehenden Lösungen benchmarken? Ich hab da nicht so den Durchblick. Wäre eine Funktion die ein Table liefert praktischer?

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

Dieser Beitrag wurde von yoq am 30.12.2016 um 16:36 editiert.

mcb
#120
30.12.2016 01:28
Beiträge: 1472

Ich selbst brauche ein table nicht so oft. Von daher ist ein Iterator wohl besser
Ich teste das morgen mal aus, mal sehen wie groß der Unterschied ist.

mcb
#121
30.12.2016 14:38
Beiträge: 1472

Die ersten Messungen (auf dieser Map: http://www.siedler-maps.de/maps/Testmap_No1-1632.htm):
Iteration über alle Entitys (10 mal):
EntityFind: 0.19 sec
S5Hook (iterator): 0.01 sec
S5Hook (table insert): 0.08 sec
SucheAufDerWelt: 0.38 sec (Nicht alle Entitys gefunden!)

Edit: Hab sie doch noch gefunden: Ist Predicate nicht Predicates

Iteration über alle Entitys von Spieler 2 (10 mal) (19 entitys):
EntityFind: 0.27 sec
S5Hook (iterator): 0.001 sec
S5Hook (table insert): 0.001 sec

Iteration über alle Entitys in 50000 Scm von der Zugbrücke (10 mal) (7781 entitys):
EntityFind: 0.99 sec
S5Hook (iterator): 0.01 sec
S5Hook (table insert): 0.09 sec

Beide Einschränkungen kombiniert (10 mal) (19 entitys):
EntityFind: 0.26 sec
S5Hook (iterator): 0.005 sec
S5Hook (table insert): 0.006 sec

Dieser Beitrag wurde von mcb am 30.12.2016 um 15:08 editiert.

yoq
#122
30.12.2016 16:39
Beiträge: 91

Jetzt gibt es mit S5Hook.EntityIteratorTableize(...) auch die Möglichkeit direkt ein Table zu erhalten. Ist etwa 1.5-2x schneller als eine ideale Lua Implementation (n zählen, kein table.getn):

function tableizeIterator(it)
  local n, t = 1, {}
  for e in it do
    t[n] = e
    n = n+1
  end
  return t
end



Tableize und Iterator sind etwa gleich schnell, in der Praxis dürfte meist der Iterator die Nase vorn haben, vorallem wenn für jedes Entity ein Aufruf durchgeführt wird, da das Entity-Objekt schon im CPU Cache liegt.

Und Predicate.InRect(x0,y0,x1,y1) hab ich noch hinzugefügt.

____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

Dieser Beitrag wurde von yoq am 30.12.2016 um 23:58 editiert.

mcb
#123
30.12.2016 17:15
Beiträge: 1472

Iteration über alle Entitys in 50000 Scm von der Zugbrücke (10 mal) (7781 entitys):
EntityFind: 1.01 sec
S5Hook (iterator): 0.01 sec
S5Hook (tableize): 0.02 sec
(deutlicher Unterschied zum manuellen table insert)

Wäre es möglich, gleich mehrere Entitytypen/Player abzufragen, etwa so:

Predicate.OfTypes{[Entities.PU_Serf]=true, [Entities.PU_Hero1a]=true}


oder eine Lua-Funktion aufzurufen:

Predicate.Accepter(function(id) return true end)


Dann könnte ich ziemlich einfach meine EntityFind-Funktionen daran anpassen

yoq
#124
31.12.2016 11:36
Beiträge: 91

Wie viele Typen wären da bei einem typischen Aufruf parallel? 2, 3, 20?
Einfachste Lösung wäre nämlich: Predicate.OR(pred0, pred1, ...)

Lua Predicate hab ich bewusst nicht gebaut, da es vermutlich langsamer wäre als dasselbe in Lua:

function IterateSelective(baseIter, predFn)
    return function()
        for eID in baseIter do
            if predFn(eID) then
                return eID
            end
        end
    end
end

-- iterator über gerade eIDs
evenEIDsIter = IterateSelective(S5Hook.EntityIterator(), function(eID) return math.mod(eID,2)==0; end)



____________________
S5 & S6: Lua Script Debugger (Thread) | bbaTool
S5: S5Hook (Thread) | S5 GUI Editor | S5 Grafikupgrade + nVidia fix | Win10 Creators Update

mcb
#125
31.12.2016 14:45
Beiträge: 1472

Das wären Ziemlich viele. Das ganze ist sozusagen ein Ersatz dafür, das die meisten CU-Entitys nicht in den EntityCategories sind. Deswegen kam ich auf die Idee, einfach in einem Table nachzusehen, ob der Typ erlaubt ist. Ein tablezugriff über einen bekannten key sollte eigentlich konstante Zeit brauchen (wenn das table richtig implementiert ist )

Seiten: Zurück 1 2 3 4 5 6 7 Nächste Seite

SiteEngine v1.5.0 by nevermind, ©2005-2007
Design by SpiderFive (www.siedler-games.de) - English translation by juja

Impressum