Open main menu

Difference between revisions of "Wintermute/Externals"

8,451 bytes added ,  16:08, 29 August 2020
no edit summary
Line 19: Line 19:


Sets 3rd param to "Request Error." on error
Sets 3rd param to "Request Error." on error
Context:
    var buf = new String(255);
    var buf2 = new String(255);
    getURLContent("http://www.lacosaweb.com", DirURL, buf);
    if((((buf == "Request Error.") || (buf == null)) || (buf == ""))) {
        SCUPDalt.Red = 0;
        textoscup1 = "www.jamesperis.com";
        textoscup2 = "www.jamesperis.com";
    }
    else {
        SCUPDalt.Red = 1;
        textoscup1 = buf;
        getURLContent("http://www.lacosaweb.com", DirURL2, buf2);
        textoscup2 = buf2;
    }


== Various games by HeroCraft ==
== Various games by HeroCraft ==
Line 28: Line 44:


Known usage: SetValueToReg("Software\HeroCraft\<GameID>\Video", "Windowed", 1)
Known usage: SetValueToReg("Software\HeroCraft\<GameID>\Video", "Windowed", 1)
Context:
    if(checkBox.Pressed) {
        SetValueToReg("Software\HeroCraft\Pole\Video", "Windowed", 0);
        Game.windowedState = 0;
    }
    else {
        SetValueToReg("Software\HeroCraft\Pole\Video", "Windowed", 1);
        Game.windowedState = 1;
    }


=== img.dll ===
=== img.dll ===
Line 36: Line 62:


Known usage: changeWindowCaption(Game.Hwnd, <Title>)
Known usage: changeWindowCaption(Game.Hwnd, <Title>)
Context:
    if(Game.WindowedMode) {
        maximizedWindow(Game.Hwnd, 1024, 768);
    }
    changeWindowCaption(Game.Hwnd, getStr("Поле Чудес"));


==== maximizedWindow ====
==== maximizedWindow ====
Line 54: Line 86:


Returns value >32 on success
Returns value >32 on success
Context:
    function RunDocument(Filename) {
        ShellExecuteA(0, "open", Filename, "", "", 3);
        return null;
    }
   
    ...
   
    on "off_url" {
        RunDocument("http://offstudio.fabry.cz");
        return;
    }
    on "dc_url" {
        RunDocument("http://dead-code.org");
        return;
    }


= 2.5D games =
= 2.5D games =
Line 67: Line 116:


Returns 1 on success, other value on fail (which leads to Game.QuitGame() in non-Debug mode)
Returns 1 on success, other value on fail (which leads to Game.QuitGame() in non-Debug mode)
Context:
    var ivlmsg = Game.ExpandString("/vld0002/Proszę włożyć płytę ''Art of Murder Sztuka Zbrodni'' do napędu DVD-ROM.");
    var valid = _InstallUtilAnsi@0();
    if((valid != 1)) {
        var query = Game.ConfirmBox(ivlmsg);
        valid = _InstallUtilAnsi@0();
        if((valid != 1)) {
            if(Game.DebugMode) {
                Game.Msg("!!! no media !!!");
            }
            else {
                Game.QuitGame();
            }
        }
    }


== Various games by Corbomite Games ==
== Various games by Corbomite Games ==
Line 88: Line 153:


Returns 0 on success, other value on error
Returns 0 on success, other value on error
Context:
    if(EnableIRC) {
        IRCConnected = IRC_init(PlayerName);
    }


==== ChangeNick ====
==== ChangeNick ====
Line 97: Line 167:


Return value is never used
Return value is never used
Context:
    if(EnableIRC) {
        ChangeNick(PlayerName);
    }


==== IRC_SendString ====
==== IRC_SendString ====
Line 106: Line 181:


Known Channel values are: "#Zbeng" and "#ZbengDebug"
Known Channel values are: "#Zbeng" and "#ZbengDebug"
Context:
    function SendMessageToIrc(inStr) {
        if((IRCConnected == 0)) {
            IRC_SendString(inStr, "#zbeng");
        }
        return null;
    }
    function SendDebugMessageToIrc(inStr) {
        if((IRCConnected == 0)) {
            IRC_SendString(inStr, "#ZbengDebug");
        }
        return null;
    }


==== IRC_GetChatStrings ====
==== IRC_GetChatStrings ====
Line 130: Line 219:


Return values are only compared with zero and are never used in other APIs
Return values are only compared with zero and are never used in other APIs
Context:
    var inifile = new File("Zbang.ini");
    inifile.OpenAsText(1);
    IRCWinSetting = inifile.ReadText(1);
    if(((IRCWinSetting != 1) && (IRCWinSetting != 2))) {
        IRCWinSetting = 0;
    }
    DEBUG(("IRCWinSetting " + IRCWinSetting));
    if((IRCWinSetting > 0)) {
        IRCDllLib = LoadLibraryA("dlltest.dll");
    }
    if((IRCDllLib == 0)) {
        EnableIRC = 0;
    }


==== FreeLibrary ====
==== FreeLibrary ====
Line 148: Line 252:


Known EnvName values used in licensing code: "FULLGAME"
Known EnvName values used in licensing code: "FULLGAME"
Context:
    method getEnvironmentVar(envName) {
        var envContent = new String(65535);
        var retval = GetEnvironmentVariableA(envName, envContent, 65535);
        return envContent;
        return null;
    }
    method CheckArmadillo() {
        var path = getEnvironmentVar("");
        DEBUG(path);
        var variarblesArr = new Array("USERKEY", "ALTUSERNAME", "ENHFINGERPRINT", "EXTRAINFO", "FINGERPRINT", "KEYSTRING", "STOLENKEY", "TRIAL", "FULLGAME");
        var len = variarblesArr.Length;
        var i = 0;
        while((i < len)) {
            var key = variarblesArr[i];
            var variable = getEnvironmentVar(key);
            DEBUG(((key + "=") + variable));
            i = (i + 1);
        }
        global g_Publisher;
        if(!(g_Publisher.DRM)) {
            if(!(g_Publisher.OverrideFullgame)) {
                var PublisherFullGame = getEnvironmentVar("FULLGAME");
                if((PublisherFullGame != "TRUE")) {
                    isFullDemo = 1;
                }
            }
            else {
                global isBought = 1;
            }
        }
        return null;
    }


=== httpconnect ===
=== httpconnect ===
Line 186: Line 324:


For some reason always returns -7 for me in a test game
For some reason always returns -7 for me in a test game
Context:
    method RegisterKey(inProductkey) {
        var productID = new String(65535);
        var productKey = new String(65535);
        productKey = inProductkey;
        productID = "357868";
        var rerVal = Register(productID, 65535, productKey, 65535);
        DEBUG(("Validate : " + rerVal));
        if((rerVal == 1)) {
            return 1;
        }
        productID = "353058";
        rerVal = Register(productID, 65535, productKey, 65535);
        DEBUG(("Validate : " + rerVal));
        if((rerVal == 1)) {
            return 1;
        }
        productID = "353006";
        rerVal = Register(productID, 65535, productKey, 65535);
        DEBUG(("Validate : " + rerVal));
        if((rerVal == 1)) {
            return 1;
        }
        ShowMessage(rerVal);
        return rerVal;
        return null;
    }


==== Validate ====
==== Validate ====
Line 214: Line 380:


Return value is never used
Return value is never used
Context:
    method sendEventNow(inEventName, extraParams) {
        global NetworkEnabled;
        if((NetworkEnabled != 1)) {
            DEBUG("Not sending event due to network disabled");
            return 0;
        }
        if(firewall) {
            DEBUG("Not sending event due to firewall");
            return 0;
        }
        var httpStr = new String(65535);
        var Request = new String(65535);
        var server = new String(65535);
        Request = ((((((((((("http://backend.pizzamorgana.com/event.php?Event=" + inEventName) + "&player=") + this.PlayerName) + "&extraParams=") + extraParams) + "&SN=") + this.SN) + "&Episode=1&GameTime=") + Game.CurrentTime) + "&UniqueID=") + this.Unique);
        server = "backend.pizzamorgana.com";
        DEBUG((((("Send: '" + Request) + "' to server '") + server) + "'"));
        if((Request != null)) {
            SendHTTPAsync(server, 65535, Request, 65535, httpStr, 65535);
        }
        httpStr = httpStr.Substr(0, 256);
        DEBUG((("Recv: '" + httpStr) + "'"));
        return httpStr;
        return null;
    }


==== SendRecvHTTP (6 params variant) ====
==== SendRecvHTTP (6 params variant) ====
Line 247: Line 439:


Known usage: dpi = GetDPI()
Known usage: dpi = GetDPI()
Context:
    function CheckFont() {
        var dpi = Game.RegReadNumber("DefaultDPI", 0);
        BASEFONT = "fonts";
        if((dpi == 0)) {
            dpi = GetDPI();
        }
        if((dpi <= 72)) {
            dpi = 72;
        } else if((dpi <= 96)) {
            dpi = 96;
        } else if((dpi <= 120)) {
            dpi = 120;
        } else {
            dpi = 144;
        }
        if((dpi == 72)) {
            BASEFONT = "fonts.72";
        }
        if((dpi == 120)) {
            BASEFONT = "fonts.120";
        }
        if((dpi == 144)) {
            BASEFONT = "fonts.144";
        }
    }


==== GetCaption ====
==== GetCaption ====
Line 256: Line 475:


Known usage: GetCaption(Game.Hwnd)
Known usage: GetCaption(Game.Hwnd)
Context:
    function CheckCaption() {
        var p = "Wintermute Engine";
        while(1) {
            var s = GetCaption(Game.Hwnd);
            s = new String(s);
            if((s.IndexOf(p, 0) >= 0)) {
                break;
            }
            Sleep(1);
        }
        SetCaption(Game.Hwnd, Game.ExpandString("/MAIN_CAPTION3/"));
    }


==== SetCaption ====
==== SetCaption ====
Line 272: Line 505:


Known usage: RemoveFile(Game.SaveDirectory + "\" + newname + ".bmp")
Known usage: RemoveFile(Game.SaveDirectory + "\" + newname + ".bmp")
Context:
    var sd = Game.SaveDirectory;
    if((sd == NULL)) {
        sd = "qsaves";
    }
    sd = (sd + "\");
    this.SaveFilePath = sd;
    this.SaveFileExtention = ".dat";
    this.TempScreenShot = (Directory.TempDirectory + "\tempss.bmp");
   
    ...
   
    method RemoveTempScreenShot() {
        var filename = this.TempScreenShot;
        if(Game.FileExists(filename)) {
            RemoveFile(filename);
        }
        return null;
    }
    method SaveTempScreenShot(newname) {
        var oldname = this.TempScreenShot;
        if(!(Game.FileExists(oldname))) {
            log.Add((("svg::SaveTempScreenShot(" + GetValue(newname)) + ") error, temporary screenshot is unavailable"));
            return null;
        }
        if((newname == NULL)) {
            newname = "qsave";
        }
        newname = ((this.SaveFilePath + newname) + ".bmp");
        if(Game.FileExists(newname)) {
            RemoveFile(newname);
        }
        RenameFile(oldname, newname);
        return null;
    }


==== RenameFile ====
==== RenameFile ====
Line 284: Line 553:
Steam version of Stroke of Fate: Operation Bunker does not have this DLL.
Steam version of Stroke of Fate: Operation Bunker does not have this DLL.


However, game code contain some checks that depend on GetOptions() results.
However, game code contain some checks that depend on GetOptions() results, which use some of those calls.


Specifications:
Specifications:
    external "protect.dll" stdcall long PSA_IsTrialMode(membuffer);
     external "protect.dll" stdcall long PSA_DisableFeaturesGrantedByLicense(membuffer);
     external "protect.dll" stdcall long PSA_DisableFeaturesGrantedByLicense(membuffer);
    external "protect.dll" stdcall PSA_DummyFunction();
     external "protect.dll" stdcall long PSA_GetFeaturesGrantedByLicense(membuffer);
     external "protect.dll" stdcall long PSA_GetFeaturesGrantedByLicense(membuffer);
     external "protect.dll" stdcall long PSA_IsDemoMode(membuffer);
     external "protect.dll" stdcall long PSA_IsDemoMode(membuffer);
     external "protect.dll" stdcall PSA_DummyFunction();
     external "protect.dll" stdcall long PSA_IsTrialMode(membuffer);
 
PSA_GetFeaturesGrantedByLicense sets 4-byte buffer's first 5 bits with some feature flags of unknown semantics. Maybe same game features are missing in Steam version because of this.
 
PSA_IsDemoMode sets 1-byte buffer to non-zero if license is Demo.
 
PSA_IsTrialMode sets 1-byte buffer to non-zero if license is Trial.
 
PSA_DisableFeaturesGrantedByLicense & PSA_DummyFunction are never used.


Usage:
Context:
     function GetOptions() {
     function GetOptions() {
         var p;
         var p;
Line 313: Line 590:
         return p;
         return p;
     }
     }
Known checks:
    o = (!(o.R1) && o.R5)
    if(((((Random(0, 1) == 0) || (enl.safe_state == "oil")) || DEBUG) && (!(o.D) && !(o.R2))))
    if(((quest.herda == 12) && o.R3))
    o = (!(o.T) && o.R3)
    if(o.R3)
    if(o.R4)
    if((((((((enl.linge_a && enl.linge_b1) && enl.linge_b2) && enl.linge_b3) && enl.linge_b4) && enl.linge_d) || TRUE) && (!(o.T) && o.R4)))
234

edits