You are viewing a potentially older version of this package. View all versions.
lammas123-CrabDevKit-1.2.1 icon

CrabDevKit

A utility mod that improves the experience for mod makers.

Date uploaded 6 days ago
Version 1.2.1
Download link lammas123-CrabDevKit-1.2.1.zip
Downloads 35
Dependency string lammas123-CrabDevKit-1.2.1

This mod requires the following mods to function

BepInEx-BepInExPack_CrabGame-6.0.577 icon
BepInEx-BepInExPack_CrabGame

Legacy BepInEx 6 pack for Crab Game. Preconfigured and ready to use.

Preferred version: 6.0.577

README

Features

Intermediary Namings

Since Crab Game is obfuscated, the names of most types, fields, methods, etc have been changed to gibberish, making it difficult to tell what anything actually is, or what is real in the case of all of the generated garbage methods.

Everything has been given a human readable name, so no more wondering what something is or which method is the one you want among all the garbage! Do note that since the game is compiled with Il2Cpp, this does not give you access to any source code, only the deobfuscated names of the obfuscated names ripped from the Il2Cpp Unhollower.

You don't need to add CrabDevKit as a dependency to use these namings! Feel free to copy the entire files into your project, or just what you need!

AssetBundlePtr

Due to the game being compiled with Il2Cpp, a majority of the functionality regarding Asset Bundles has been stripped, and the stubs generated by the Il2Cpp Unhollower are non-functional. However, through some pointer magic, functionality for them has been restored to some degree!

Due to the functionality being stripped, Unity appears to only be able to handle one Asset Bundle being loaded at any given time. So to allow assets from multiple Asset Bundles to be loaded at once, I dynamically load and unload 'loaded' Asset Bundles as mods interact with them.

Because of this:

  • you may not load Asset Bundles asynchronously, to avoid loading multiple at once and breaking functionality, (if it's possible, I may implement more complex functionality to support this in the future, we'll see)
  • the game may momentarily freeze whenever it has to unload and load another Asset Bundle,
  • mod makers may have to slightly change how they would normally use Asset Bundles, especially considering Il2Cpp may have stripped more niche uses of Asset Bundles I'm not aware of.

Otherwise, Asset Bundles are fully supported via AssetBundlePtr!

AssetBundlePtr bundle = AssetBundlePtr.LoadFromFile(bundlePath);

// Can't type cast the returned value, must redefine it via its Pointer, a Il2Cpp unhollowed quirk.
UnityEngine.Object prefabObject = bundle.LoadAsset<GameObject>(prefabName);
GameObject prefab = new GameObject(prefabObject.Pointer);

CrabNet

A simple networking solution (utilizing channel 123 of SteamNetworkingMessages) to allow mod makers to register and send custom messages between users of CrabDevKit through their mods.

Simply register a message via a string (ex: 'CrabDevKit:Test') and a MessageHandler delegate, which takes in a ulong for the sending client's steam id, and a Packet for the byte data within the message.

CrabNet.RegisterMessageHandler($"{MyPluginInfo.PLUGIN_NAME}:Test", (clientId, packet) =>
{
  Log.LogInfo($"Test message from {clientId}: {packet.ReadString()}");
});

Then you may send that message to any other user using CrabDevKit and your mod!

static IEnumerable<CSteamID> GetAllSteamIds()
{
    int members = SteamMatchmaking.GetNumLobbyMembers(LobbyManager.Instance.get_currentLobby());
    for (int i = 0; i < members; i++)
    {
        CSteamID steamId = SteamMatchmaking.GetLobbyMemberByIndex(LobbyManager.Instance.get_currentLobby(), i);
        yield return steamId;
    }
}

Packet packet = new();
packet.Write("Hello!");

CrabNet.SendMessage($"{MyPluginInfo.PLUGIN_NAME}:Test", packet, GetAllSteamIds());

// I would normally use a using statement, but Packet is an Il2Cpp unhollowed type and can't be used that way.
// CrabNet.SendMessage also calls packet.Dispose() itself when it's successfully sent the message, but it's good practice to do this anyway!
packet.Dispose();

Things to note with CrabNet:

  • You may only register messages after CrabDevKit has loaded, and before the game has started, so you should have your mod depend on CrabDevKit and register methods while your mod is loading!
  • Your message's identifier string is expected to contain a colon, which should separate your mod's name and the name of the message, in order to reduce the number of potential collisions caused by any mods using the same message identifiers.
  • It is up to you to ensure your server and client bound messages are being sent to, received by, rejected, and properly handled by the right users. Always ensure you're only sending server bound messages to the server, and that clients will reject server bound messages not intended for them!
  • In larger lobbies, due to the Steam networking issues detailed by FloatingPlayerPatch, messages you send client to client may not always reach eachother, though I don't recommend this style of network communication anyway.

FakeClients

A simple solution for simulating what it'd be like to do anything with more players than you have available. (Useful if you have no friends, or they just aren't available right when you need them xD)

Here's a simple Harmony patch that will spawn and remove fake clients when pressing Left Alt+P or Left Alt+O as the host:

// Create/Remove FakeClients
internal static List<FakeClient> fakeClients = [];
[HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Update))]
[HarmonyPostfix]
internal static void PostPlayerInputUpdate()
{
    if (!SteamManager.Instance.IsLobbyOwner() || !Input.GetKey(KeyCode.LeftAlt))
        return;

    if (Input.GetKeyDown(KeyCode.P))
    {
        CrabDevKit.Instance.Log.LogInfo("Creating fake player...");

        FakeClient fakeClient = FakeClients.Create(forceSpawnActive: true);
        fakeClients.Add(fakeClient);
    }

    if (Input.GetKeyDown(KeyCode.O))
    {
        FakeClient fakeClient = fakeClients.LastOrDefault();
        if (fakeClient == null)
          return;
        
        CrabDevKit.Instance.Log.LogInfo("Removing fake player...");

        FakeClients.Remove(fakeClient);
        fakeClients.RemoveAt(fakeClients.Count - 1);
    }
}

Other Utilities

ChatUtil

Provides a couple methods for sending chat messages with better formatting.

GiveUtil

Allows you to directly give vanilla players any item with any amount of ammo.

CHANGELOG

1.2.1

  • Added ChatUtil and GiveUtil.
  • Moved the Patches for FakeClients to be within the FakeClients class.

1.2.0

  • Updated several internal parts of CrabDevKit to make the source code neater.

1.1.0

  • Increased priority of the SteamManager.LobbyEnter postfix patch for CrabNet, that way it runs ahead of an exception sometimes caused by MapMod that led to message handlers not being registered.
  • Added a utility for FakeClients which allows host side mods to spawn fake clients as players, who at the bare minimum are recognized as and act like real players on the hosts end, but unless the mod does anything with them, they will just spawn and float there doing nothing.

1.0.0

  • Initial release.