Liches/Nemesis are not implemented #446

Closed
opened 2024-07-01 15:46:25 -07:00 by VampireKitten · 5 comments
VampireKitten commented 2024-07-01 15:46:25 -07:00 (Migrated from github.com)

Example request when vanquishing a larvling mid-mission:

2024-12-25T07:44:30:245 [0.1.0] error:  unknown endpoint POST /api/nemesis.php
2024-12-25T07:44:30:245 [0.1.0] debug:  data provided to /api/nemesis.php: {"target":{"fp":5604904486637265999,"manifest":"/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix","KillingSuit":"/Lotus/Powersuits/Ember/EmberPrime","killingDamageType":0,"ShoulderHelmet":"/Lotus/Upgrades/Skins/Ember/EmberHelmetAlt","DisallowedWeapons":[],"WeaponIdx":-1,"AgentIdx":1,"BirthNode":"SolNode27","Faction":"FC_GRINEER","Rank":0,"k":false,"Traded":false,"d":{"$date":{"$numberLong":"000"}},"InfNodes":[],"GuessHistory":[],"Hints":[],"HintProgress":0,"Weakened":false,"PrevOwners":0,"HenchmenKilled":0,"SecondInCommand":false}}
1735109070.mYRo3bL8dc5xzbexzKxzkqISxt2NYR1uXJAy/zs4+i77e8WKAlZgzUZWPuBlKrn7fPl0C93Klamuer3h/e4XNw==
2024-12-25T07:44:30:246 [0.1.0] http:   POST /api/nemesis.php?accountId=6633b81e9dba0b714f28ff02&nonce=8921291300141453&ct=MSI&mode=s 404 1.587 ms - 34

Example body with DisallowedWeapons:

{"target":{"fp":-6994193815086618,"manifest":"/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix","KillingSuit":"/Lotus/Powersuits/Ember/EmberPrime","killingDamageType":1,"ShoulderHelmet":"/Lotus/Upgrades/Skins/Ember/EmberHelmetAlt","DisallowedWeapons":["/Lotus/Weapons/Grineer/LongGuns/GrnKuvaLichRifle/GrnKuvaLichRifleWeapon","/Lotus/Weapons/Grineer/Bows/GrnBow/GrnBowWeapon"],"WeaponIdx":-1,"AgentIdx":1,"BirthNode":"SolNode70","Faction":"FC_GRINEER","Rank":0,"k":false,"Traded":false,"d":{"$date":{"$numberLong":"000"}},"InfNodes":[],"GuessHistory":[],"Hints":[],"HintProgress":0,"Weakened":false,"PrevOwners":0,"HenchmenKilled":0,"SecondInCommand":false}}
Example request when vanquishing a larvling mid-mission: ``` 2024-12-25T07:44:30:245 [0.1.0] error: unknown endpoint POST /api/nemesis.php 2024-12-25T07:44:30:245 [0.1.0] debug: data provided to /api/nemesis.php: {"target":{"fp":5604904486637265999,"manifest":"/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix","KillingSuit":"/Lotus/Powersuits/Ember/EmberPrime","killingDamageType":0,"ShoulderHelmet":"/Lotus/Upgrades/Skins/Ember/EmberHelmetAlt","DisallowedWeapons":[],"WeaponIdx":-1,"AgentIdx":1,"BirthNode":"SolNode27","Faction":"FC_GRINEER","Rank":0,"k":false,"Traded":false,"d":{"$date":{"$numberLong":"000"}},"InfNodes":[],"GuessHistory":[],"Hints":[],"HintProgress":0,"Weakened":false,"PrevOwners":0,"HenchmenKilled":0,"SecondInCommand":false}} 1735109070.mYRo3bL8dc5xzbexzKxzkqISxt2NYR1uXJAy/zs4+i77e8WKAlZgzUZWPuBlKrn7fPl0C93Klamuer3h/e4XNw== 2024-12-25T07:44:30:246 [0.1.0] http: POST /api/nemesis.php?accountId=6633b81e9dba0b714f28ff02&nonce=8921291300141453&ct=MSI&mode=s 404 1.587 ms - 34 ``` Example body with DisallowedWeapons: ```json {"target":{"fp":-6994193815086618,"manifest":"/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix","KillingSuit":"/Lotus/Powersuits/Ember/EmberPrime","killingDamageType":1,"ShoulderHelmet":"/Lotus/Upgrades/Skins/Ember/EmberHelmetAlt","DisallowedWeapons":["/Lotus/Weapons/Grineer/LongGuns/GrnKuvaLichRifle/GrnKuvaLichRifleWeapon","/Lotus/Weapons/Grineer/Bows/GrnBow/GrnBowWeapon"],"WeaponIdx":-1,"AgentIdx":1,"BirthNode":"SolNode70","Faction":"FC_GRINEER","Rank":0,"k":false,"Traded":false,"d":{"$date":{"$numberLong":"000"}},"InfNodes":[],"GuessHistory":[],"Hints":[],"HintProgress":0,"Weakened":false,"PrevOwners":0,"HenchmenKilled":0,"SecondInCommand":false}} ```

Nemesis inventory format:

    "Nemesis": {
        "fp": 336234901346275053,
        "manifest": "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionFive",
        "KillingSuit": "/Lotus/Powersuits/Ember/EmberPrime",
        "killingDamageType": 12,
        "ShoulderHelmet": "/Lotus/Upgrades/Skins/Ember/EmberHelmetAltStatless",
        "WeaponIdx": 18,
        "AgentIdx": 1,
        "BirthNode": "SolNode70",
        "Faction": "FC_GRINEER",
        "Rank": 1,
        "k": false,
        "Traded": false,
        "d": {
            "$date": {
                "$numberLong": "1693907501929"
            }
        },
        "InfNodes": [
            {
                "Node": "SolNode16",
                "Influence": 1
            },
            {
                "Node": "SolNode65",
                "Influence": 1
            },
            {
                "Node": "SolNode30",
                "Influence": 1
            },
            {
                "Node": "SolNode36",
                "Influence": 1
            },
            {
                "Node": "SolNode45",
                "Influence": 0.2
            },
            {
                "Node": "SolNode46",
                "Influence": 1
            },
            {
                "Node": "SolNode68",
                "Influence": 1
            },
            {
                "Node": "ClanNode8",
                "Influence": 1
            },
            {
                "Node": "SolNode106",
                "Influence": 1
            },
            {
                "Node": "SolNode14",
                "Influence": 1
            },
            {
                "Node": "ClanNode9",
                "Influence": 1
            },
            {
                "Node": "SolNode58",
                "Influence": 1
            },
            {
                "Node": "SolNode41",
                "Influence": 1
            },
            {
                "Node": "SolNode11",
                "Influence": 1
            }
        ],
        "PrevOwners": 0,
        "HenchmenKilled": 10,
        "SecondInCommand": false,
        "HintProgress": 50,
        "Hints": [
            1
        ],
        "GuessHistory": [
            25881
        ]
    },
Nemesis inventory format: ```json "Nemesis": { "fp": 336234901346275053, "manifest": "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionFive", "KillingSuit": "/Lotus/Powersuits/Ember/EmberPrime", "killingDamageType": 12, "ShoulderHelmet": "/Lotus/Upgrades/Skins/Ember/EmberHelmetAltStatless", "WeaponIdx": 18, "AgentIdx": 1, "BirthNode": "SolNode70", "Faction": "FC_GRINEER", "Rank": 1, "k": false, "Traded": false, "d": { "$date": { "$numberLong": "1693907501929" } }, "InfNodes": [ { "Node": "SolNode16", "Influence": 1 }, { "Node": "SolNode65", "Influence": 1 }, { "Node": "SolNode30", "Influence": 1 }, { "Node": "SolNode36", "Influence": 1 }, { "Node": "SolNode45", "Influence": 0.2 }, { "Node": "SolNode46", "Influence": 1 }, { "Node": "SolNode68", "Influence": 1 }, { "Node": "ClanNode8", "Influence": 1 }, { "Node": "SolNode106", "Influence": 1 }, { "Node": "SolNode14", "Influence": 1 }, { "Node": "ClanNode9", "Influence": 1 }, { "Node": "SolNode58", "Influence": 1 }, { "Node": "SolNode41", "Influence": 1 }, { "Node": "SolNode11", "Influence": 1 } ], "PrevOwners": 0, "HenchmenKilled": 10, "SecondInCommand": false, "HintProgress": 50, "Hints": [ 1 ], "GuessHistory": [ 25881 ] }, ```

The weapon seems to be generated based on the fingerprint (fp) with typical Knuth's 64-bit LCG, e.g. with the current KuvaLichManifestVersionSix and seed=1337, it'll generate KuvaNukor. If the given weapon is on the discard pile, it'll increment the index (modulo the array size), until it finds a weapon that's not in the discard pile.

The weapon seems to be generated based on the fingerprint (`fp`) with typical Knuth's 64-bit LCG, e.g. with the current `KuvaLichManifestVersionSix` and seed=1337, it'll generate KuvaNukor. If the given weapon is on the discard pile, it'll increment the index (modulo the array size), until it finds a weapon that's not in the discard pile.

Slight problem we'll definitely have when doing this in our beloved JavaSkript:

JSON.parse("5604904486637265999").toString() == "5604904486637265999" // false

This seems like it might be an okay-ish solution: https://www.npmjs.com/package/json-with-bigint
Just hope Mongoose also works fine with BigInts.

Slight problem we'll definitely have when doing this in our beloved JavaSkript: ```js JSON.parse("5604904486637265999").toString() == "5604904486637265999" // false ``` This seems like it might be an okay-ish solution: https://www.npmjs.com/package/json-with-bigint Just hope Mongoose also works fine with BigInts.

Of course JSON.stringify is also extremely uncooperative when you just wanna encode a 64-bit integer without loss of precision, some totally not insane hacking is needed here:

(BigInt.prototype as any).toJSON = function () {
    return "<JS_SUCKS>" + this.toString() + "</JS_SUCKS>";
};
const og_stringify = JSON.stringify;
(JSON as any).stringify = (obj: any) => {
    return og_stringify(obj).split(`"<JS_SUCKS>`).join(``).split(`</JS_SUCKS>"`).join(``);
};
Of course JSON.stringify is also extremely uncooperative when you just wanna encode a 64-bit integer without loss of precision, some totally not insane hacking is needed here: ```ts (BigInt.prototype as any).toJSON = function () { return "<JS_SUCKS>" + this.toString() + "</JS_SUCKS>"; }; const og_stringify = JSON.stringify; (JSON as any).stringify = (obj: any) => { return og_stringify(obj).split(`"<JS_SUCKS>`).join(``).split(`</JS_SUCKS>"`).join(``); }; ```

The format for the guess history:

  • The symbol is 0-7 for the normal requiems, 8 for none, and 9 for wildcard.
  • The result is 0 for correct, 1 for incorrect, 2 for neutral. 3, 4, and 5 also look interesting, like more muted versions for the first 3, maybe for a repeat guess when the result of it was no surprise? But not used on live afaik.
const decode_guess = (val: number): number[] => {
    return [
        val & 0xF,
        (val >> 12) & 3,
        (val & 0xFF) >> 4,
        (val & 0xFFFF) >> 14,
        (val >> 8) & 0xF,
        (val >> 16) & 3
    ];
};

const encode_guess = (
    symbol1: number,
    result1: number,
    symbol2: number,
    result2: number,
    symbol3: number,
    result3: number
): number => {
    return (
        (symbol1 & 0xf) |
        ((result1 & 3) << 12) |
        ((symbol2 << 4) & 0xff) |
        ((result2 << 14) & 0xffff) |
        ((symbol3 & 0xf) << 8) |
        ((result3 & 3) << 16)
    );
};
The format for the guess history: - The symbol is 0-7 for the normal requiems, 8 for none, and 9 for wildcard. - The result is 0 for correct, 1 for incorrect, 2 for neutral. 3, 4, and 5 also look interesting, like more muted versions for the first 3, maybe for a repeat guess when the result of it was no surprise? But not used on live afaik. ```ts const decode_guess = (val: number): number[] => { return [ val & 0xF, (val >> 12) & 3, (val & 0xFF) >> 4, (val & 0xFFFF) >> 14, (val >> 8) & 0xF, (val >> 16) & 3 ]; }; const encode_guess = ( symbol1: number, result1: number, symbol2: number, result2: number, symbol3: number, result3: number ): number => { return ( (symbol1 & 0xf) | ((result1 & 3) << 12) | ((symbol2 << 4) & 0xff) | ((result2 << 14) & 0xffff) | ((symbol3 & 0xf) << 8) | ((result3 & 3) << 16) ); }; ```
Sainan referenced this issue from a commit 2025-03-20 05:36:10 -07:00
Sign in to join this conversation.
No description provided.