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 )