wohahobg / pterosync

PteroSync new WHMCS Pterodactyl Module
75 stars 16 forks source link

API error if you use Quantity as configurable option #34

Open HayKer97 opened 2 weeks ago

HayKer97 commented 2 weeks ago

If you use as configurable option type "Quantity", the Variable will be interpreted as integer while the environment array always need strings. In my example, the wrong Value is at MAX_PLAYERS

This problem only appears if you up- or downgrade a server in whmcs.

Module Log: Request:

{
    "environment":
    {
        "HHGS":"mcv",
        "BUILD_VANILLA_VERSION":"latest",
        "BUILD_PURGE":"false",
        "BUILD_CREATE_BACKUP_ON_SAME_SERVER":"false",
        "BUILD_PURGE_AFTER_BACKUP_ON_SAME_SERVER":"false",
        "MAX_PLAYERS":6,
        "MOTD":"Bla",
        "GAMEMODE":"0",
        "DIFFICULTY":"2",
        "PVP":"true",
        "FLIGHT":"false",
        "NETHER":"true",
        "SPAWNMOBS":"true",
        "SPAWNNPC":"true",
        "SPAWNANIMALS":"true",
        "SPAWNSTRUCTURES":"true"
    },
    "startup":"\/tmp\/.run",
    "egg":25,
    "image":"bla",
    "skip_scripts":false
}

Response:

Array
(
    [errors] => Array
        (
            [0] => Array
                (
                    [code] => DataValidationException
                    [status] => 500
                    [detail] => Could not save Pterodactyl\Models\ServerVariable[739]: failed to validate data: {"variable_value":["The variable value must be a string."]}
                )

        )

    [status_code] => 500
)

If I use the Dropdown type for configurable options, it will work. The MAX_PLAYER value is a string here.

Request:

{
    "environment":
    {
        "HHGS":"mcv",
        "BUILD_VANILLA_VERSION":"latest",
        "BUILD_PURGE":"false",
        "BUILD_CREATE_BACKUP_ON_SAME_SERVER":"false",
        "BUILD_PURGE_AFTER_BACKUP_ON_SAME_SERVER":"false",
        "MAX_PLAYERS":"8",
        "MOTD":"Bla",
        "GAMEMODE":"0",
        "DIFFICULTY":"2",
        "PVP":"true",
        "FLIGHT":"false",
        "NETHER":"true",
        "SPAWNMOBS":"true",
        "SPAWNNPC":"true",
        "SPAWNANIMALS":"true",
        "SPAWNSTRUCTURES":"true"
    },
    "startup":"\/tmp\/.run",
    "egg":25,
    "image":"Bla",
    "skip_scripts":false
}

Response:

[...]
    [status_code] => 200
)

I remember this worked in the past with the Quantity type also. So I would fix it by my self, but my PHP knowledge is too small :)

HayKer97 commented 2 weeks ago

Nevermind, i edit the function "pteroSyncGetOption" as follows:

function pteroSyncGetOption(array $params, $id, $default = NULL)
{
    $options = pterosync_ConfigKeys();

    $friendlyName = $options[$id];
    if (isset($params['A'][$friendlyName]) && $params['configoptions'][$friendlyName] !== '') {
        $value = $params['configoptions'][$friendlyName];
    } else if (isset($params['configoptions'][$id]) && $params['configoptions'][$id] !== '') {
        $value = $params['configoptions'][$id];
    } else if (isset($params['customfields'][$friendlyName]) && $params['customfields'][$friendlyName] !== '') {
        $value = $params['customfields'][$friendlyName];
    } else if (isset($params['customfields'][$id]) && $params['customfields'][$id] !== '') {
        $value = $params['customfields'][$id];
    } else {
        $found = false;
        $i = 0;
        foreach ($options as $key => $value) {
            $i++;
            if ($key === $id) {
                $found = true;
                break;
            }
        }
        if ($found && isset($params['configoption' . $i]) && $params['configoption' . $i] !== '') {
            $value = $params['configoption' . $i];
        } else {
            $value = $default;
        }
    }

    // Check if value is an integer
    if (is_int($value)) {
        return (string)$value; // convert integer to string
    }

    return $value;
}
wohahobg commented 2 weeks ago

The issue is in your Egg Variables.

The rule should be required|numeric not required|string or whatever. image

HayKer97 commented 2 weeks ago

Nope, not working for me. I configured the Input Rules with "required|integer" Now I have tested it with "required|numeric" like in your example and with "required|filled". Every Time I get the same response from the API and the Value in the request isn't in brackets.

I also tested it with various config options in config.json. Still the same.

And if I am correctly informed, all values, regardless of whether they are integers or bools, must be transferred to the Pterodactyl API as strings.

wohahobg commented 2 weeks ago

Then is not max_players, it will be something else. What game is that?

HayKer97 commented 2 weeks ago

Now I have tested it with all variables only have "required". Still the same.

And I am so sorry I forgot to say that this problem only appears if I up- or downgrade a server in whmcs. A fresh setup works. Edited above.

I use my own egg for minecraft vanilla. If you need it to test, I will provide it for you.

wohahobg commented 2 weeks ago

Yes please. I don't think the issue is due the max_players as even the error you have give

Array
(
    [errors] => Array
        (
            [0] => Array
                (
                    [code] => DataValidationException
                    [status] => 500
                    [detail] => Could not save Pterodactyl\Models\ServerVariable[739]: failed to validate data: {"variable_value":["The variable value must be a string."]}
                )

        )

    [status_code] => 500
)

does not say the variable name. Which is wired.

HayKer97 commented 2 weeks ago

Here is my egg. I just replaced the installscript and docker images to original Minecraft Vanilla egg.

Minecraft Vanilla Egg

```json { "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO", "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2024-08-29T21:21:18+02:00", "name": "Vanilla Minecraft", "author": "info@hosthonest.de", "description": "Minecraft ist ein Spiel, in dem es darum geht, Bl\u00f6cke zu platzieren und Abenteuer zu erleben. Erforsche zuf\u00e4llig generierte Welten und baue erstaunliche Dinge, vom einfachsten Haus bis hin zu den gr\u00f6\u00dften Schl\u00f6ssern. Spiele im Kreativmodus mit unbegrenzten Ressourcen oder baue im \u00dcberlebensmodus tief in der Erde und stelle Waffen und R\u00fcstungen her, um gef\u00e4hrliche Mobs abzuwehren. Das alles kannst du allein oder mit Freunden machen.", "features": [ "eula", "java_version", "pid_limit" ], "docker_images": { "Java 21": "ghcr.io\/pterodactyl\/yolks:java_21", "Java 17": "ghcr.io\/pterodactyl\/yolks:java_17", "Java 16": "ghcr.io\/pterodactyl\/yolks:java_16", "Java 11": "ghcr.io\/pterodactyl\/yolks:java_11", "Java 8": "ghcr.io\/pterodactyl\/yolks:java_8" }, "file_denylist": [], "startup": "\/tmp\/.run", "config": { "files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"{{server.build.default.ip}}\",\r\n \"server-port\": \"{{server.build.default.port}}\",\r\n \"query.port\": \"{{server.build.default.port}}\",\r\n \"max-players\": \"{{server.build.env.MAX_PLAYERS}}\",\r\n \"motd\": \"{{server.build.env.MOTD}}\",\r\n \"allow-nether\": \"{{server.build.env.NETHER}}\",\r\n \"gamemode\": \"{{server.build.env.GAMEMODE}}\",\r\n \"difficulty\": \"{{server.build.env.DIFFICULTY}}\",\r\n \"spawn-monsters\": \"{{server.build.env.SPAWNMOBS}}\",\r\n \"pvp\": \"{{server.build.env.PVP}}\",\r\n \"spawn-npcs\": \"{{server.build.env.SPAWNNPC}}\",\r\n \"allow-flight\": \"{{server.build.env.FLIGHT}}\",\r\n \"spawn-animals\": \"{{server.build.env.SPAWNANIMALS}}\",\r\n \"generate-structures\": \"{{server.build.env.SPAWNSTRUCTURES}}\"\r\n }\r\n }\r\n}", "startup": "{\r\n \"done\": \")! For help, type \"\r\n}", "logs": "{}", "stop": "stop" }, "scripts": { "installation": { "script": "#!\/bin\/ash\r\n# Vanilla MC Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\nmkdir -p \/mnt\/server\r\ncd \/mnt\/server\r\n\r\nLATEST_VERSION=`curl https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq -r '.latest.release'`\r\nLATEST_SNAPSHOT_VERSION=`curl https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq -r '.latest.snapshot'`\r\n\r\necho -e \"latest version is $LATEST_VERSION\"\r\necho -e \"latest snapshot is $LATEST_SNAPSHOT_VERSION\"\r\n\r\nif [ -z \"$VANILLA_VERSION\" ] || [ \"$VANILLA_VERSION\" == \"latest\" ]; then\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $LATEST_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nelif [ \"$VANILLA_VERSION\" == \"snapshot\" ]; then\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $LATEST_SNAPSHOT_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nelse\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $VANILLA_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nfi\r\n\r\nDOWNLOAD_URL=$(curl ${MANIFEST_URL} | jq .downloads.server | jq -r '. | .url')\r\n\r\necho -e \"running: curl -o ${SERVER_JARFILE} $DOWNLOAD_URL\"\r\ncurl -o ${SERVER_JARFILE} $DOWNLOAD_URL\r\n\r\necho -e \"Install Complete\"", "container": "ghcr.io\/pterodactyl\/installers:alpine", "entrypoint": "ash" } }, "variables": [ { "name": "Gameserver", "description": "Diese Variable gibt an, um welchen Gameserver es sich handelt.", "env_variable": "HHGS", "default_value": "mcv", "user_viewable": false, "user_editable": false, "rules": "required", "field_type": "text" }, { "name": "Setup: Server Version", "description": "Die zu installierende Version von Minecraft Vanilla. Verwende \u201elatest\u201c, um die neueste Version zu installieren, oder verwende \u201esnapshot\u201c, um den neuesten Snapshot zu installieren. Gehe zu \u201eSettings > Reinstall Server\u201c, um die \u00c4nderung anzuwenden.\r\nAlle Daten des Servers bleiben bestehen, sofern nicht andere Optionen gesetzt wurden.", "env_variable": "BUILD_VANILLA_VERSION", "default_value": "latest", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Setup: Server Bereinigung", "description": "L\u00f6schung aller Daten des Servers bei einem Reinstall des Servers. Gehe zu \u201eSettings > Reinstall Server\u201c, um die \u00c4nderung anzuwenden.\r\nAlle Daten des Servers werden gel\u00f6scht, inkl. Backups.", "env_variable": "BUILD_PURGE", "default_value": "false", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Setup: Backup bei Reinstall", "description": "Es wird ein Backup des aktuellen Servers durchgef\u00fchrt, wenn eine Neuinstallation des Servers angesto\u00dfen wird. Gehe zu \u201eSettings > Reinstall Server\u201c, um die \u00c4nderung anzuwenden.\r\nAlle Daten des Servers bleiben bestehen.\r\nDiese Option wird \u00fcbersprungen, wenn \"Setup: Server Bereinigung\" aktiviert ist.\r\nBackups werden deinem Speicherplatzverbrauch gutgeschrieben.", "env_variable": "BUILD_CREATE_BACKUP_ON_SAME_SERVER", "default_value": "false", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Setup: Datenbereinigung nach Backup", "description": "Wenn bei einem Reinstall ein Backup erstellt wird, wird im Anschluss der Server bereinigt.\r\nGehe zu \u201eSettings > Reinstall Server\u201c, um die \u00c4nderung anzuwenden.\r\nServerdaten werden bereinigt. Backups bleiben bestehen.\r\nDiese Option wird \u00fcbersprungen, wenn \"Setup: Server Bereinigung\" aktiviert ist.\r\nDiese Option wird \u00fcbersprungen, wenn \"Setup: Backup bei Reinstall\" deaktivert ist.\r\nBackups werden deinem Speicherplatzverbrauch gutgeschrieben.", "env_variable": "BUILD_PURGE_AFTER_BACKUP_ON_SAME_SERVER", "default_value": "false", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Slots", "description": "Maximale Anzahl an Spielern, die den Server gleichzeitig betreten d\u00fcrfen.", "env_variable": "MAX_PLAYERS", "default_value": "1", "user_viewable": true, "user_editable": false, "rules": "required", "field_type": "text" }, { "name": "Message of the Day", "description": "Nachricht, die im Serverbrowser angezeigt werden soll.", "env_variable": "MOTD", "default_value": "Minecraft Vanilla Server by hosthonest.de", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Gamemode", "description": "Stelle ein, welcher Gamemode genutzt werden soll\r\n0:Survival\r\n1:Creative\r\n2:Adventure", "env_variable": "GAMEMODE", "default_value": "0", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Difficulty", "description": "Stelle ein, welche Schwierigkeitsstufe eingestellt werden soll.\r\n0:peaceful\r\n1:easy\r\n2:normal\r\n3:hard", "env_variable": "DIFFICULTY", "default_value": "2", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "PVP", "description": "Erlaube PVP auf deinem Server, oder auch nicht.", "env_variable": "PVP", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Fliegen erlauben", "description": "Erlaube es dir und deinen Spielern zu fliegen.", "env_variable": "FLIGHT", "default_value": "false", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Nether erlauben", "description": "Erlaube den Zugang zum Nether.", "env_variable": "NETHER", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Monster spawnen", "description": "Monster werden gespawnt", "env_variable": "SPAWNMOBS", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "NPC's spawnen", "description": "NPC's werden gespawnt", "env_variable": "SPAWNNPC", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Tiere spawnen", "description": "Tiere werden gespawnt", "env_variable": "SPAWNANIMALS", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" }, { "name": "Strukturen generierend", "description": "Strukturen werden gebaut", "env_variable": "SPAWNSTRUCTURES", "default_value": "true", "user_viewable": true, "user_editable": true, "rules": "required", "field_type": "text" } ] } ```

wohahobg commented 2 weeks ago

Ok. Will try it today. Also please share with me your module "log" for request and response , from the last changes not old one.

wohahobg commented 2 weeks ago

I have just tested your egg and is working fine.

If you upgrade the product from the "admin panel in whmcs" make sure when you change Max Players to press save, and after that Change Package.

HayKer97 commented 1 week ago

Just don't work for me, sadly. On Admin side I got same error 500.

Client side up- and downgrade also.

Date: 02/09/2024 20:58 - Module: pterosync-whmcs - Action: patch - https://[mydomain]/api/application/servers/106/startup

Request

```json {"environment":{"HHGS":"mcv","BUILD_VANILLA_VERSION":"latest","BUILD_PURGE":"false","BUILD_CREATE_BACKUP_ON_SAME_SERVER":"false","BUILD_PURGE_AFTER_BACKUP_ON_SAME_SERVER":"false","MAX_PLAYERS":179,"MOTD":"MOTD","GAMEMODE":"0","DIFFICULTY":"2","PVP":"true","FLIGHT":"false","NETHER":"true","SPAWNMOBS":"true","SPAWNNPC":"true","SPAWNANIMALS":"true","SPAWNSTRUCTURES":"true"},"startup":"\/tmp\/.run","egg":25,"image":"image","skip_scripts":false} ```

Response

``` Array ( [errors] => Array ( [0] => Array ( [code] => DataValidationException [status] => 500 [detail] => Could not save Pterodactyl\Models\ServerVariable[983]: failed to validate data: {"variable_value":["The variable value must be a string."]} ) ) [status_code] => 500 ) ```

wohahobg commented 1 week ago

Hi, sorry for late response just little be busy.

Then the issue is not from the MAX_PLAYERS must be something else. Try with the default egg from pterodactyl ?

HayKer97 commented 1 week ago

Hi, no problem, I have the same issue :D

I tested it now with the original Minecraft Vanilla Egg. I Just add the MAX_PLAYERS variable. Same issue here.

Request

```json {"environment":{"SERVER_JARFILE":"server.jar","VANILLA_VERSION":"latest","MAX_PLAYERS":5},"startup":"java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}","egg":43,"image":"ghcr.io\/pterodactyl\/yolks:java_21","skip_scripts":false} ```

Response

``` Array ( [errors] => Array ( [0] => Array ( [code] => DataValidationException [status] => 500 [detail] => Could not save Pterodactyl\Models\ServerVariable[996]: failed to validate data: {"variable_value":["The variable value must be a string."]} ) ) [status_code] => 500 ) ```

Only when I force the MAX_PLAYERS variable to be a string, this error is gone and everything is working fine. Also, without my MAX_PLAYERS variable, everything is fine. And also, if I change MAX_PLAYERS in WHMCS from Quantity to Dropdown, everything is fine.

wohahobg commented 1 week ago

That's soo wired you are the only one with such as issue.

Can you show me in a video what exactly what u r doing.

HayKer97 commented 1 week ago

Cool, nice to hear that. So many times I think I have strange problems, which only I have in the IT business. Now I have a confirmation :D

I will try to make a video for u this weekend.

HayKer97 commented 6 days ago

Done: https://youtu.be/JpXJtu60P0w

Sorry for the bad quality at the end.

wohahobg commented 6 days ago

In your egg settings how does the VARIABLE MAX_PLAYERS look like.

HayKer97 commented 3 days ago

In my egg settings the Variable looks Like that:

Screenshot_20240911_112027_Edge

Same results i get if i test it with other input rules i descriped here

wohahobg commented 10 hours ago

Ok, I was playing with this and i don't understand what's wrong for you.

Do you mind if join the Discord Server so we can talk and u share me a screen ?