ResoniteModdingGroup / MonkeyLoader.GamePacks.ResoniteModLoader

MonkeyLoader Game Pack that provides compatibility for ResoniteModLoader.
GNU Lesser General Public License v3.0
5 stars 2 forks source link

RML mod config changed events don't seem to be happening #4

Closed Nytra closed 5 months ago

Nytra commented 5 months ago

I have a mod that under RML fires events when the mod configuration changes, however when changing the config via MonkeyLoader's settings, then events don't seem to fire at all.

Banane9 commented 5 months ago

Ah yup, forgot to actually call that 😂

Nytra commented 5 months ago

I think this is still not working. When trying to set or unset the keys manually in code, I am getting this error:

System.Collections.Generic.KeyNotFoundException: Key [COLOR_FULL_NODE] not found in this config section!
  at MonkeyLoader.Configuration.ConfigSection.ThrowKeyNotFound (MonkeyLoader.Configuration.IConfigKey key) [0x00015] in <f95b00f8851c4cd09697db7d8fb370ff>:0 
  at MonkeyLoader.Configuration.ConfigSection.GetDefinedKey (MonkeyLoader.Configuration.IConfigKey templateKey) [0x0000b] in <f95b00f8851c4cd09697db7d8fb370ff>:0 
  at ResoniteModLoader.ModConfiguration.Unset (ResoniteModLoader.ModConfigurationKey key) [0x0000e] in <58e205d2517b46ed8abaf004a7754f39>:0 
  at ColorMyProtoFlux.ColorMyProtoFlux+Patch_ProtoFluxNodeVisual_BuildUI+<>c__DisplayClass0_0.<Postfix>b__0 () [0x00085] in <bacbb59cfba54829b59b9d9fbcdc0f98>:0 
Banane9 commented 5 months ago

Interesting - will look into it again

Banane9 commented 5 months ago

Yea, okay, the keys weren't being added in the right place... and then the settings of course also didn't go through the rml config setting system of course, so I had to change that as well.. :D

Nytra commented 5 months ago

@Banane9 I'm still getting errors trying to set and unset keys directly in code:

System.Collections.Generic.KeyNotFoundException: Key [COLOR_FULL_NODE] not found in this config section!
  at MonkeyLoader.Configuration.ConfigSection.ThrowKeyNotFound (MonkeyLoader.Configuration.IConfigKey key) [0x00015] in <f52d3a45f94e4be19eb7b37b7159e50a>:0 
  at MonkeyLoader.Configuration.ConfigSection.GetDefinedKey (MonkeyLoader.Configuration.IConfigKey templateKey) [0x0000b] in <f52d3a45f94e4be19eb7b37b7159e50a>:0 
  at ResoniteModLoader.ModConfiguration.Unset (ResoniteModLoader.ModConfigurationKey key) [0x00007] in <d2d819d45af24731b3bd9050fcd73286>:0 
  at ColorMyProtoFlux.ColorMyProtoFlux+Patch_ProtoFluxNodeVisual_BuildUI+<>c__DisplayClass0_0.<Postfix>b__0 () [0x00085] in <988264b58b3d4ee698215428810b6f7b>:0 

This error is from this code:

Config.Unset(COLOR_FULL_NODE);
Banane9 commented 5 months ago

It does require the updated build of MonkeyLoader itself as well, as I changed something internal there to make things work 😅

Nytra commented 5 months ago

Yes I have built MonkeyLoader from source (I think)

Banane9 commented 5 months ago

Hmmmm, I'm not sure what's going on then - I'm also not at home atm 😅

You can try enabling the debugger in the Doorstop config and attaching VS via the UnityDebugger.

Nytra commented 5 months ago

I don't what the UnityDebugger is and I don't really know how to attach VS as a debugger.

Banane9 commented 5 months ago

I'll be back home in a few hours, can walk you through it then, if you want.

Nytra commented 5 months ago

I think this code is the problem, which is returning the hashcode of the key ID for untyped keys

private sealed class ConfigKeyEqualityComparer : IEqualityComparer<IConfigKey>
{
    /// <inheritdoc/>
    public bool Equals(IConfigKey? x, IConfigKey? y)
    {
        if (ReferenceEquals(x, y))
            return true;

        if (x is ITypedConfigKey typedX && y is ITypedConfigKey typedY)
            return typedX.ValueType == typedY.ValueType && typedX.Id == typedY.Id;

        return x is not null && y is not null && x.Id == y.Id;
    }

    /// <inheritdoc/>
    public int GetHashCode(IConfigKey? obj)
    {
        if (obj is ITypedConfigKey typedKey)
            return unchecked((31 * typedKey.ValueType.GetHashCode()) + obj.Id.GetHashCode());

        return obj?.Id.GetHashCode() ?? 0;
    }
}
Nytra commented 5 months ago

hm actually it might be this, it should be adding definingKey.AsUntyped to the _configurationItemDefinitionsSelfMap right?

internal void RegisterConfigKey(IDefiningConfigKey definingKey)
{
    if (_configurationItemDefinitionsSelfMap.ContainsKey(definingKey.AsUntyped))
    {
        Logger.Error(() => $"Tried to load duplicate key id [{definingKey.Id}] from section [{definingKey.FullId}]!");
        definingKey.Section.Saveable = false;
    }
    else
    {
        _configurationItemDefinitionsSelfMap.Add(definingKey, definingKey);
    }
}
Nytra commented 5 months ago

nvm if I change the code to do that it crashes me instantly :/

Banane9 commented 5 months ago

hm actually it might be this, it should be adding definingKey.AsUntyped to the _configurationItemDefinitionsSelfMap right?

nope, it's only using AsUntyped for the Contains check because that means it'll look for any key with a matching name, rather than matching name and type. But the map needs to have the real key for both.

Nytra commented 5 months ago

I fixed it but I don't know how or why

Code before which doesn't work:

public bool TryGetDefinedKey(IConfigKey templateKey, [NotNullWhen(true)] out IDefiningConfigKey? definingKey)
{
    return Config.TryGetDefiningKey(templateKey.AsUntyped, out definingKey) && keys.Contains(definingKey);
}

Code after which works:

public bool TryGetDefinedKey(IConfigKey templateKey, [NotNullWhen(true)] out IDefiningConfigKey? definingKey)
{
    return Config.TryGetDefiningKey(templateKey, out definingKey) && keys.Contains(definingKey);
}

I removed the AsUntyped

Nytra commented 5 months ago

~But this is in MonkeyLoader core which I guess I shouldn't be changing, the code which calls this is ModConfiguration.Unset in the RML game pack~

nvm there is nothing I can do in the RML game pack to fix this

Banane9 commented 5 months ago

Hmmm, it's weird that that isn't working to begin with - maybe it is funkiness with the HashCode calculation, since it should give the same thing for "equal" things.

Nytra commented 5 months ago

It might be because the types are from different assemblies and that is making it weird?

Banane9 commented 5 months ago

hmmm, that shouldn't make a difference, as it's using the types from the same assembly internally anyways.

Nytra commented 5 months ago

@Banane9 https://github.com/MonkeyModdingTroop/MonkeyLoader/commit/c2038c310360cb4cd76ceec8af528825b77e8a92 did not fix the problem, and in fact made it worse, because my game won't even start now :P

MonkeyLog.log

DESKTOP-H976HO2 - 2024.5.7.505 - 2024-05-07 21_59_14.log

Nytra commented 5 months ago

Okay sometimes it starts, but MonkeyLoader doesn't even seem to have loaded properly

Banane9 commented 5 months ago

and in fact made it worse, because my game won't even start now :P

because it's not backwards compatible due to the events and config key component changes 😅

Nytra commented 5 months ago

hm so everything needs to be recompiled? i think I already did that

Banane9 commented 5 months ago

hm so everything needs to be recompiled? i think I already did that

The Resonite integration and such weren't adapted to it yet, so they weren't loading at all 😅

I just pushed the update for that

Nytra commented 5 months ago

I tested it and it seems to be fixed now :D

Banane9 commented 5 months ago

Yay~

It was the hash function doing it differently depending on whether it had a type or not - which was wrong of course.

konn-neko commented 4 months ago

just so i can confirm things, with this loader, the rml config mod is redundant?

if it is, that means i can remove it right?

Banane9 commented 4 months ago

just so i can confirm things, with this loader, the rml config mod is redundant?

Mostly correct. There's some types that may be used as configuration options which don't have templates in Resonite's settings page yet, so they won't be displayed. However with Nytra having added a colorX template, all the most important ones are covered.

Nytra commented 4 months ago

Yeah, there are some types like Int4 that don't have UI, but who uses Int4 lol