Jump to content

[1.16.5] NumberFormatException after copying the options.txt


Skyriis

Recommended Posts

Hey Guys,

I'm working on a mod which allows to store your settings (options.txt) in a cloud service but something seems to cause a weird problem. I'm getting this log message which doesn't really makes sense to me since i'm just copying the values from the options.txt when the Options#save has finished writing and load those values on startup before Options#load once.

 

Has someone an idea what could cause that problem?

 

Link to comment
Share on other sites

i've checkt the content of the options.txt before and after sync with the cloud and the only difference is the order of the lines.

 

APIHelper class:

Spoiler
    public static boolean sendSetting(String key, String value) {
        try {
            CloseableHttpResponse response = HTTP_CLIENT.execute(authorizedGet(String.format("store/%s/%s/%s", getUserId(), encode(key), encode(value))));

            HttpEntity entity = response.getEntity();
            JsonReader reader = new JsonReader(new StringReader(EntityUtils.toString(entity)));
            reader.setLenient(true);
            JsonObject resultObject = new JsonParser().parse(reader).getAsJsonObject();

            String resultValue = getResultValue(resultObject);

            if (resultValue == null) return false;
            if (resultValue.startsWith("Login failed")) {
                if (SettingsLoadingHandler.getLoginKeyFile().delete()) {
                    LogHelper.getLogger().info("Login Token is outdated. Requesting new a new one...");
                }
                AuthenticationWindow window = new AuthenticationWindow(Minecraft.getInstance().getUser().getUuid());
                window.show();
                return sendSetting(key, value);
            }
            return resultValue.equals("Value saved");
        } catch (Exception e) {
            LogHelper.getLogger().trace("Exception while trying to send the update to the cloud.", e);
            return false;
        }
    }

    public static List<String> loadSettings() {
        try (CloseableHttpResponse response = HTTP_CLIENT.execute(authorizedGet(String.format("store/%s", getUserId())))) {
            HttpEntity entity = response.getEntity();
            JsonObject resultObject = new JsonParser().parse(EntityUtils.toString(entity)).getAsJsonObject();
            String resultValue = getResultValue(resultObject.get("result").getAsJsonObject());
            //Exit if no status has been sent
            if (resultValue == null) return Lists.newArrayList();
            if (resultValue.startsWith("Login failed")) {
                if (SettingsLoadingHandler.getLoginKeyFile().delete()) {
                    LogHelper.getLogger().info("Login Token is outdated. Requesting new a new one...");
                }
                AuthenticationWindow window = new AuthenticationWindow(Minecraft.getInstance().getUser().getUuid());
                window.show();
                return loadSettings();
            }
            if (!resultValue.equals("Success")) return Lists.newArrayList();
            //Exit if no values has been sent
            if (!resultObject.has("entries")) return Lists.newArrayList();
            JsonArray storedSettings = resultObject.get("entries").getAsJsonArray();

            ArrayList<String> settings = new ArrayList<>();
            storedSettings.forEach(jsonElement -> {
                if (!jsonElement.isJsonObject()) return;

                JsonObject jsonObject = jsonElement.getAsJsonObject();
                if (!jsonObject.has("key") || !jsonObject.has("value")) return;

                String settingLine = String.format("%s:%s", jsonObject.get("key").getAsString(), jsonObject.get("value").getAsString());
                settings.add(settingLine);
            });

            LogHelper.getLogger().info("Loaded {} settings from Cloud.", settings.size());
            return settings;
        } catch (IOException e) {
            LogHelper.getLogger().trace("Failed to load settings from Cloud.", e);
            return Lists.newArrayList();
        }
    }

    private static String getUserId() {
        return Minecraft.getInstance().getUser().getUuid();
    }

    @Nullable
    private static String getResultValue(JsonObject jsonObject) {
        if (!jsonObject.has("result")) return null;
        return jsonObject.get("result").getAsString();
    }

    private static String encode(String value) throws UnsupportedEncodingException {
        return URLEncoder.encode(value, "UTF-8");
    }

Handler class:

Spoiler
public class SettingsLoadingHandler {
    private static boolean initialLoadCompleted = false;
    @Getter
    private static final File loginKeyFile = new File(System.getProperty("user.home"))
        .toPath()
        .resolve(".minecraft")
        .resolve("cloudsettings")
        .resolve("login.key")
        .toFile();
    public static AtomicReference<String> apiToken = new AtomicReference<>("");
    private static final ConcurrentHashMap<String, String> settingsMap = new ConcurrentHashMap<>();
    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

    public static void checkForLoad(Options options) {
        if (initialLoadCompleted) return;
        final File optionsFile = ((OptionsAccessor) options).getOptionsFile();


        LogHelper.getLogger().info("Requesting for authentication...");

        AuthenticationWindow window = new AuthenticationWindow(Minecraft.getInstance().getUser().getUuid());
        window.show();

        if (apiToken.get().isEmpty()) {
            LogHelper.getLogger().warn("No API Token found. Canceling Synchronization!");
            return;
        }

        //Load known configs
        ApiHelper.loadSettings()
            .forEach(settingLine -> settingsMap.put(getKeyFromOptionLine(settingLine), settingLine));

        if (!optionsFile.exists()) {
            LogHelper.getLogger().info("No options file found. Trying to create a new one...");
            //generate new config file
            try {
                Files.write(optionsFile.toPath(), settingsMap.values(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                LogHelper.getLogger().trace("Exception while trying to create a new options.txt file.", e);
                return;
            }
        } else {
            LogHelper.getLogger().info("Options file found. Trying up update settings...");
            //write patches into file
            try {
                //TODO skip blacklisted settings
                Files.write(optionsFile.toPath(), settingsMap.values(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                LogHelper.getLogger().trace("Exception while updating options.txt file.", e);
            }
        }

        initialLoadCompleted = true;
    }

    public static void checkForUpdate(Options options) {
        if (!initialLoadCompleted) return;
        //check for update
        final File optionsFile = ((OptionsAccessor) options).getOptionsFile();
        LogHelper.getLogger().info("Checking options.txt for updates...");
        try (Stream<String> lines = Files.lines(optionsFile.toPath())) {
            AtomicInteger added = new AtomicInteger(0);
            AtomicInteger updated = new AtomicInteger(0);

            lines.forEach(settingsLine -> {
                String key = getKeyFromOptionLine(settingsLine);

                //TODO skip blacklisted settings
                if (settingsMap.containsKey(key)) {
                    // check for change
                    String value = settingsMap.get(key);
                    if (!value.equals(settingsLine)) {
                        //update
                        updateOption(key, settingsLine);
                        updated.incrementAndGet();
                    }
                } else {
                    //Add new entry
                    updateOption(key, settingsLine);
                    added.incrementAndGet();
                }
            });

            LogHelper.getLogger().info("Added {} and updated {} options", added.get(), updated.get());
        } catch (IOException e) {
            LogHelper.getLogger().trace("Exception while checking the options.txt file", e);
        }
    }

    private static String getKeyFromOptionLine(String line) {
        return line.substring(0, line.indexOf(':'));
    }

    private static void updateOption(String key, String value) {
        EXECUTOR.submit(() -> {
            settingsMap.put(key, value);
            if (ApiHelper.sendSetting(key, value)) {
                LogHelper.getLogger().info("Updated {} in Cloud.", key);
            } else {
                LogHelper.getLogger().info("Failed to update {} in Cloud.", key);
            }
        });
    }
}

 

 

Link to comment
Share on other sites

Before:

Spoiler
version:2586
autoJump:true
autoSuggestions:true
chatColors:true
chatLinks:true
chatLinksPrompt:true
enableVsync:true
entityShadows:true
forceUnicodeFont:false
discrete_mouse_scroll:false
invertYMouse:false
realmsNotifications:false
reducedDebugInfo:false
snooperEnabled:false
showSubtitles:false
touchscreen:false
fullscreen:false
bobView:true
toggleCrouch:false
toggleSprint:false
mouseSensitivity:0.5
fov:0.0
screenEffectScale:1.0
fovEffectScale:1.0
gamma:0.0
renderDistance:12
entityDistanceScaling:1.0
guiScale:0
particles:0
maxFps:120
difficulty:2
graphicsMode:1
ao:2
biomeBlendRadius:2
renderClouds:true
resourcePacks:[]
incompatibleResourcePacks:[]
lastServer:
lang:en_us
chatVisibility:0
chatOpacity:1.0
chatLineSpacing:0.0
textBackgroundOpacity:0.5
backgroundForChatOnly:true
hideServerAddress:false
advancedItemTooltips:false
pauseOnLostFocus:true
overrideWidth:0
overrideHeight:0
heldItemTooltips:true
chatHeightFocused:1.0
chatDelay: 0.0
chatHeightUnfocused:0.44366195797920227
chatScale:1.0
chatWidth:1.0
mipmapLevels:4
useNativeTransport:true
mainHand:right
attackIndicator:1
narrator:0
tutorialStep:movement
mouseWheelSensitivity:1.0
rawMouseInput:true
glDebugVerbosity:1
skipMultiplayerWarning:false
hideMatchedNames:true
joinedFirstServer:false
syncChunkWrites:true
key_key.attack:key.mouse.left
key_key.use:key.mouse.right
key_key.forward:key.keyboard.w
key_key.left:key.keyboard.a
key_key.back:key.keyboard.s
key_key.right:key.keyboard.d
key_key.jump:key.keyboard.space
key_key.sneak:key.keyboard.left.shift
key_key.sprint:key.keyboard.left.control
key_key.drop:key.keyboard.q
key_key.inventory:key.keyboard.e
key_key.chat:key.keyboard.t
key_key.playerlist:key.keyboard.tab
key_key.pickItem:key.mouse.middle
key_key.command:key.keyboard.slash
key_key.socialInteractions:key.keyboard.p
key_key.screenshot:key.keyboard.f2
key_key.togglePerspective:key.keyboard.f5
key_key.smoothCamera:key.keyboard.unknown
key_key.fullscreen:key.keyboard.f11
key_key.spectatorOutlines:key.keyboard.unknown
key_key.swapOffhand:key.keyboard.f
key_key.saveToolbarActivator:key.keyboard.c
key_key.loadToolbarActivator:key.keyboard.x
key_key.advancements:key.keyboard.l
key_key.hotbar.1:key.keyboard.1
key_key.hotbar.2:key.keyboard.2
key_key.hotbar.3:key.keyboard.3
key_key.hotbar.4:key.keyboard.4
key_key.hotbar.5:key.keyboard.5
key_key.hotbar.6:key.keyboard.6
key_key.hotbar.7:key.keyboard.7
key_key.hotbar.8:key.keyboard.8
key_key.hotbar.9:key.keyboard.9
soundCategory_master:1.0
soundCategory_music:1.0
soundCategory_record:1.0
soundCategory_weather:1.0
soundCategory_block:1.0
soundCategory_hostile:1.0
soundCategory_neutral:1.0
soundCategory_player:1.0
soundCategory_ambient:1.0
soundCategory_voice:1.0
modelPart_cape:true
modelPart_jacket:true
modelPart_left_sleeve:true
modelPart_right_sleeve:true
modelPart_left_pants_leg:true
modelPart_right_pants_leg:true
modelPart_hat:true

After:

Spoiler
tutorialStep:tutorialStep:movement
key_key.pickItem:key_key.pickItem:key.mouse.middle
chatDelay:chatDelay:+0.0
chatLinksPrompt:chatLinksPrompt:true
key_key.playerlist:key_key.playerlist:key.keyboard.tab
textBackgroundOpacity:textBackgroundOpacity:0.5
useNativeTransport:useNativeTransport:true
chatScale:chatScale:1.0
enableVsync:enableVsync:true
modelPart_cape:modelPart_cape:true
particles:particles:0
toggleSprint:toggleSprint:false
mouseSensitivity:mouseSensitivity:0.5
key_key.advancements:key_key.advancements:key.keyboard.l
advancedItemTooltips:advancedItemTooltips:false
key_key.swapOffhand:key_key.swapOffhand:key.keyboard.f
modelPart_hat:modelPart_hat:true
touchscreen:touchscreen:false
entityShadows:entityShadows:true
incompatibleResourcePacks:incompatibleResourcePacks:[]
version:version:2586
ao:ao:2
mipmapLevels:mipmapLevels:4
hideMatchedNames:hideMatchedNames:true
key_key.hotbar.5:key_key.hotbar.5:key.keyboard.5
key_key.hotbar.6:key_key.hotbar.6:key.keyboard.6
key_key.hotbar.7:key_key.hotbar.7:key.keyboard.7
key_key.hotbar.8:key_key.hotbar.8:key.keyboard.8
fullscreen:fullscreen:false
renderDistance:renderDistance:12
key_key.hotbar.1:key_key.hotbar.1:key.keyboard.1
key_key.hotbar.2:key_key.hotbar.2:key.keyboard.2
key_key.hotbar.3:key_key.hotbar.3:key.keyboard.3
discrete_mouse_scroll:discrete_mouse_scroll:false
key_key.hotbar.4:key_key.hotbar.4:key.keyboard.4
modelPart_left_sleeve:modelPart_left_sleeve:true
soundCategory_record:soundCategory_record:1.0
key_key.sprint:key_key.sprint:key.keyboard.left.control
key_key.forward:key_key.forward:key.keyboard.w
skipMultiplayerWarning:skipMultiplayerWarning:false
key_key.drop:key_key.drop:key.keyboard.q
key_key.back:key_key.back:key.keyboard.s
soundCategory_music:soundCategory_music:1.0
toggleCrouch:toggleCrouch:false
key_key.attack:key_key.attack:key.mouse.left
soundCategory_master:soundCategory_master:1.0
key_key.use:key_key.use:key.mouse.right
chatWidth:chatWidth:1.0
key_key.saveToolbarActivator:key_key.saveToolbarActivator:key.keyboard.c
chatHeightUnfocused:chatHeightUnfocused:0.44366195797920227
realmsNotifications:realmsNotifications:false
showSubtitles:showSubtitles:false
key_key.smoothCamera:key_key.smoothCamera:key.keyboard.unknown
backgroundForChatOnly:backgroundForChatOnly:true
chatHeightFocused:chatHeightFocused:1.0
glDebugVerbosity:glDebugVerbosity:1
hideServerAddress:hideServerAddress:false
modelPart_right_pants_leg:modelPart_right_pants_leg:true
maxFps:maxFps:120
renderClouds:renderClouds:true
guiScale:guiScale:0
forceUnicodeFont:forceUnicodeFont:false
biomeBlendRadius:biomeBlendRadius:2
entityDistanceScaling:entityDistanceScaling:1.0
chatOpacity:chatOpacity:1.0
gamma:gamma:0.0
key_key.right:key_key.right:key.keyboard.d
key_key.jump:key_key.jump:key.keyboard.space
resourcePacks:resourcePacks:[]
modelPart_left_pants_leg:modelPart_left_pants_leg:true
chatLineSpacing:chatLineSpacing:0.0
chatColors:chatColors:true
soundCategory_weather:soundCategory_weather:1.0
mouseWheelSensitivity:mouseWheelSensitivity:1.0
key_key.sneak:key_key.sneak:key.keyboard.left.shift
modelPart_jacket:modelPart_jacket:true
heldItemTooltips:heldItemTooltips:true
key_key.spectatorOutlines:key_key.spectatorOutlines:key.keyboard.unknown
screenEffectScale:screenEffectScale:1.0
autoSuggestions:autoSuggestions:true
soundCategory_player:soundCategory_player:1.0
key_key.left:key_key.left:key.keyboard.a
graphicsMode:graphicsMode:1
difficulty:difficulty:2
mainHand:mainHand:right
lastServer:lastServer:
overrideHeight:overrideHeight:0
chatLinks:chatLinks:true
autoJump:autoJump:true
soundCategory_block:soundCategory_block:1.0
invertYMouse:invertYMouse:false
reducedDebugInfo:reducedDebugInfo:false
modelPart_right_sleeve:modelPart_right_sleeve:true
key_key.command:key_key.command:key.keyboard.slash
key_key.screenshot:key_key.screenshot:key.keyboard.f2
fov:fov:0.0
key_key.hotbar.9:key_key.hotbar.9:key.keyboard.9
soundCategory_neutral:soundCategory_neutral:1.0
rawMouseInput:rawMouseInput:true
attackIndicator:attackIndicator:1
snooperEnabled:snooperEnabled:false
key_key.togglePerspective:key_key.togglePerspective:key.keyboard.f5
soundCategory_ambient:soundCategory_ambient:1.0
pauseOnLostFocus:pauseOnLostFocus:true
lang:lang:en_us
key_key.chat:key_key.chat:key.keyboard.t
bobView:bobView:true
soundCategory_hostile:soundCategory_hostile:1.0
fovEffectScale:fovEffectScale:1.0
overrideWidth:overrideWidth:0
syncChunkWrites:syncChunkWrites:true
key_key.inventory:key_key.inventory:key.keyboard.e
key_key.fullscreen:key_key.fullscreen:key.keyboard.f11
key_key.loadToolbarActivator:key_key.loadToolbarActivator:key.keyboard.x
chatVisibility:chatVisibility:0
narrator:narrator:0
joinedFirstServer:joinedFirstServer:false
soundCategory_voice:soundCategory_voice:1.0
key_key.socialInteractions:key_key.socialInteractions:key.keyboard.p

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.